# app_player 音频播放组件 app_player 是一个轻量级的音频播放器模块,支持网络音频文件和本地音频文件播放。 ## 核心能力 - **多种音频源支持**:支持 HTTP/HTTPS 网络音频、本地 Flash 提示音 - **多种音频格式**:支持 PCM、MP3、WAV、AAC、M4A 格式 - **播放控制**:播放、暂停、恢复、停止、跳转(seek) - **事件回调**:支持准备完成、播放中、暂停、停止、播放完成、错误等事件通知 - **PA 功放管理**:外部注册PA硬件控制函数 - **高级选项**:支持跳过音频开头、跳过低能量段等高级播放选项 - **音量控制**:1-100 级音量调节 ## 快速开始 ### 1. 初始化模块 ```c #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. 创建播放器实例 ```c // 创建播放器 app_player_t *player = app_player_create("my_player"); // 注册事件回调(可选,建议在首次播放前调用) app_player_register_callback(player, event_callback, user_data); ``` ### 3. 播放音频 **基本播放:** ```c // 播放网络音频 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); ``` **高级播放:** ```c 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. 播放控制 ```c // 暂停 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. 状态查询 ```c // 获取播放器状态 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. 清理资源 ```c // 销毁播放器 app_player_destroy(player); ``` ## 事件处理 ```c 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 文件打包成二进制文件: ```bash 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. 代码中使用 ```c #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.mp3` → `TONE_ID_0` - `001_network_suc.mp3` → `TONE_ID_1` - `002_network_fail.mp3` → `TONE_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 错误 |