app_player 音频播放组件

app_player 是一个轻量级的音频播放器模块,支持网络音频文件和本地音频文件播放。

核心能力

  • 多种音频源支持:支持 HTTP/HTTPS 网络音频、本地 Flash 提示音

  • 多种音频格式:支持 PCM、MP3、WAV、AAC、M4A 格式

  • 播放控制:播放、暂停、恢复、停止、跳转(seek)

  • 事件回调:支持准备完成、播放中、暂停、停止、播放完成、错误等事件通知

  • PA 功放管理:外部注册PA硬件控制函数

  • 高级选项:支持跳过音频开头、跳过低能量段等高级播放选项

  • 音量控制:1-100 级音量调节

快速开始

1. 初始化模块

#include "app_player.h"

// PA 控制回调函数(控制功放开关)
static int pa_control_callback(int onoff) {
    // onoff: 1=打开PA, 0=关闭PA
    // 返回 0 表示成功
    return lisa_gpio_write_pin(gpio_dev, PA_PIN_NUM,
                               onoff ? LISA_GPIO_HIGH : LISA_GPIO_LOW);
}

// 初始化 app_player
app_player_config_t config = {
    .pa_ctrl_callback = pa_control_callback  // 必填
};
app_player_init(&config);

2. 创建播放器实例

// 创建播放器
app_player_t *player = app_player_create("my_player");

// 注册事件回调(可选,建议在首次播放前调用)
app_player_register_callback(player, event_callback, user_data);

3. 播放音频

基本播放:

// 播放网络音频
app_player_play(player, "https://example.com/audio.mp3");

// 播放本地提示音(需先使用 app_tone_get_url 获取 URL)
const char *url = app_tone_get_url(TONE_ID_0);
app_player_play(player, url);

高级播放:

app_player_play_opt_t opt = {
    .url = "https://example.com/audio.mp3",
    .throw_time_ms = 500,        // 跳过前 500ms
    .throw_low_energy = true     // 跳过低能量段
};
app_player_play_ex(player, &opt);

4. 播放控制

// 暂停
app_player_pause(player);

// 恢复(异步)
app_player_resume(player);

// 恢复(同步,等待完成)
app_player_resume_sync(player);

// 停止(异步)
app_player_stop(player);

// 停止(同步,等待完成)
app_player_stop_sync(player);

// 跳转到指定位置
app_player_seek(player, 5000);  // 跳转到 5 秒位置

// 设置音量
app_player_set_volume(player, 80);  // 音量 80/100

5. 状态查询

// 获取播放器状态
app_player_state_t state = app_player_get_state(player);

// 获取当前播放位置
uint32_t position;
app_player_get_position(player, &position);

// 获取音频总时长
uint32_t duration;
app_player_get_duration(player, &duration);

6. 清理资源

// 销毁播放器
app_player_destroy(player);

事件处理

static void event_callback(app_player_t *player,
                          app_player_event_t event,
                          void *user_data) {
    switch (event) {
    case APP_PLAYER_EVENT_PREPARED:
        // 准备完成,即将开始播放
        break;
    case APP_PLAYER_EVENT_PLAYING:
        // 正在播放
        break;
    case APP_PLAYER_EVENT_PAUSED:
        // 已暂停
        break;
    case APP_PLAYER_EVENT_STOPPED:
        // 已停止
        break;
    case APP_PLAYER_EVENT_COMPLETED:
        // 播放完成
        break;
    case APP_PLAYER_EVENT_SEEK_COMPLETE:
        // Seek 完成
        break;
    case APP_PLAYER_EVENT_ERROR:
        // 播放出错
        break;
    }
}

播放器状态机

IDLE → PREPARING → PREPARED → PLAYING ⇄ PAUSED
                      ↓           ↓
                   STOPPED ← ─ ─ ┘
                      ↓
                    ERROR
  • IDLE: 初始空闲状态

  • PREPARING: 正在准备音频资源

  • PREPARED: 准备完成,即将开始播放

  • PLAYING: 正在播放

  • PAUSED: 已暂停

  • STOPPED: 已停止

  • ERROR: 错误状态

本地提示音使用指南

本地提示音功能允许将音频文件打包到 Flash 中,实现快速离线播放。

1. 准备音频文件

音频文件需满足以下格式要求:

  • 采样率: 16 kHz(推荐)

  • 位深度: 16 bit(推荐)

  • 格式: 支持 PCM、MP3、WAV、AAC、M4A

2. 打包音频文件

使用 tools/tone_tool 工具将 MP3 文件打包成二进制文件:

cd tools/tone_tool

# 将音频文件放入 ring/ 目录,使用数字前缀命名
# 例如:000_greeting.mp3, 001_network_suc.mp3

# 执行打包脚本
./run.sh

打包工具会生成:

  • ring/tone.bin - 音频二进制数据(需烧录到 Flash)

  • ring/tone.h - C 头文件,包含音频 ID 枚举定义(如 TONE_ID_0, TONE_ID_1

详细使用方法请参考:(tools/tone_tool/README.md)

3. 烧录到设备

将生成的 tone.bin 烧录到设备 Flash 的指定地址(例如 0x30100000)。

4. 代码中使用

#include "app_tone.h"
#include "tone.h"  // 包含工具生成的头文件

// 初始化本地提示音(指定 Flash 地址)
app_tone_init(0x30100000);

// 获取提示音 URL(使用工具生成的 TONE_ID)
const char *url = app_tone_get_url(TONE_ID_0);  // 对应 000_greeting.mp3

// 播放提示音
app_player_play(player, url);

音频 ID 说明

工具会按音频文件名排序生成对应的枚举 ID:

  • 000_greeting.mp3TONE_ID_0

  • 001_network_suc.mp3TONE_ID_1

  • 002_network_fail.mp3TONE_ID_2

API 参考

详细 API 文档请查看 (app_player.h)

主要 API

函数

说明

app_player_init()

初始化模块(必须最先调用)

app_player_create()

创建播放器实例

app_player_destroy()

销毁播放器实例

app_player_register_callback()

注册事件回调

app_player_play()

播放指定 URL

app_player_play_ex()

高级播放(支持更多选项)

app_player_stop()

停止播放(异步)

app_player_stop_sync()

停止播放(同步)

app_player_pause()

暂停播放

app_player_resume()

恢复播放(异步)

app_player_resume_sync()

恢复播放(同步)

app_player_seek()

跳转到指定位置

app_player_set_volume()

设置音量(1-100)

app_player_get_state()

获取播放器状态

app_player_get_position()

获取当前播放位置

app_player_get_duration()

获取音频总时长

app_player_reset()

重置播放器到初始状态

注意事项

  1. 必须先初始化: 调用 app_player_init() 必须在创建播放器实例之前

  2. PA 回调必填: 初始化时必须提供 pa_ctrl_callback,用于控制功放

  3. 多实例限制(重要):

    • 支持创建多个播放器实例

    • 不支持混音:同一时刻只能有一个播放器处于播放状态

    • 允许一个播放器暂停,另一个播放器播放

    • 多个播放器同时播放会导致音频冲突

  4. 音频格式要求:

    • 采样率: 16 kHz(推荐)

    • 位深度: 16 bit(推荐)

    • 格式: 支持 PCM、MP3、WAV、AAC、M4A

  5. 同步 vs 异步: stop_sync()resume_sync() 会阻塞等待操作完成,适合需要确保状态切换完成的场景

  6. 音量范围: 音量值范围是 1-100

  7. 资源清理: 使用完毕后记得调用 app_player_destroy() 释放资源

错误码

错误码

说明

APP_PLAYER_OK

成功

APP_PLAYER_ERR_INVALID_PARAM

无效参数

APP_PLAYER_ERR_NO_MEMORY

内存不足

APP_PLAYER_ERR_INVALID_STATE

状态错误

APP_PLAYER_ERR_NOT_SUPPORTED

不支持的操作

APP_PLAYER_ERR_TIMEOUT

超时

APP_PLAYER_ERR_IO

IO 错误