你好! 针对 #9337 描述的 URL 音频播放卡顿及 test1 无法播放问题,经源码分析,根因已定位,以下是详细分析和解决方案。
问题一:test1 不能播放(必现)
根因:guoxin_test1.mp3 是 MP3 格式文件,但代码中错误地设置了 src.format = AI_AUDIO_CODEC_WAV。
查看 decoder_wav.c 第 43 行:
Code: Select all
// decoder_wav.c 第43行
if (!memcmp(&buf[WAV_RIFF_POS], "RIFF", 4) && !memcmp(&buf[WAV_FORMAT_POS], "WAVE", 4)) {
WAV 解码器期望收到标准的 RIFF/WAVE 文件头(44字节),而 MP3 文件以 ID3 或帧同步字 0xFFE 开头,解码器识别失败 → 无法播放。
修复:将 AI_AUDIO_CODEC_WAV 改为 AI_AUDIO_CODEC_MP3
Code: Select all
// 修复后的代码
case 1:
src.url = MUSIC_URL_1; // "http://wx.nationalchip.com/guoxin_test1.mp3"
src.format = AI_AUDIO_CODEC_MP3; // ← 改成 MP3,不是 WAV!
break;
问题二:test / test2 播放卡顿、断断续续
根因同样:guoxin_test.mp3 和 guoxin_test2.mp3 也是 MP3 文件,但被标为 AI_AUDIO_CODEC_WAV。
用 WAV 解码器去解 MP3 数据,本质是用错误的解码器解析数据流,会产生:
- 解码输出噪声(卡顿感)
- 或解码器频繁报错、重启 → 断断续续
修复:三个 URL 全部改为 AI_AUDIO_CODEC_MP3
Code: Select all
// 完整修复版本
void play_music_by_index(uint8_t index)
{
WUKONG_AI_MUSIC_SRC_T src = {0};
WUKONG_AI_MUSIC_T music = {0};
switch(index) {
case 1:
src.url = MUSIC_URL_1; // guoxin_test1.mp3
src.format = AI_AUDIO_CODEC_MP3; // ✅ MP3
break;
case 2:
src.url = MUSIC_URL_2; // guoxin_test.mp3
src.format = AI_AUDIO_CODEC_MP3; // ✅ MP3(原为WAV,错误)
break;
case 3:
src.url = MUSIC_URL_3; // guoxin_test2.mp3
src.format = AI_AUDIO_CODEC_MP3; // ✅ MP3(原为WAV,错误)
break;
default:
TAL_PR_ERR("invalid index");
return;
}
music.src_cnt = 1;
music.src_array = &src;
wukong_audio_play_music(&music);
}
补充:网络抖动导致卡顿的可能性
如果修改 format 后仍有零星卡顿,需排查网络侧:
datasink_url.c 中 HTTP 读取超时配置(第 117、174 行):
Code: Select all
http_set_timeout(ctx->session, AI_PLAYER_HTTP_YIELD_MS); // 默认 10ms
若服务器 wx.nationalchip.com 响应慢,10ms yield 可能导致 player 缓冲区饥饿。可尝试:
- 换用稳定服务器测试:排除服务器端问题
- 增加 HTTP yield 时间(可选,谨慎修改):
Code: Select all
// svc_ai_player.h 第59-60行,按需调整
#ifndef AI_PLAYER_HTTP_YIELD_MS
#define AI_PLAYER_HTTP_YIELD_MS (10) // 可尝试改为 50 看是否有改善
#endif
总结
| 现象 | 根因 | 修复 |
| test1 完全不能播放 | MP3 文件用了 WAV 解码器 | src.format = AI_AUDIO_CODEC_MP3 |
| test/test2 卡顿断续 | 同上,解码器输出异常 | 同上 |
| 修改后仍有零星卡顿 | 网络侧抖动(可能性) | 排查服务器响应,或适当增大 YIELD_MS |
请先按上述修改 play_music_by_index() 函数,重新编译验证,有问题欢迎继续追问。