T5 3.13.6 播放url音频卡顿

Wi-Fi 设备、蜂窝设备、WuKongAI、开发板、TuyaOS 移植等


Post Reply
demo
Posts: 9

版本:3.13.6
平台:T5
硬件:不带屏幕
软件:tuyaos_demo_wukong_ai
问题描述:播放url音频卡顿,其中test1不能播放,test和test2播放过程中有卡顿,断断续续的
实现代码如下:

Code: Select all

#define MUSIC_URL_1 "http://wx.nationalchip.com/guoxin_test.mp3"
#define MUSIC_URL_2 "http://wx.nationalchip.com/guoxin_test1.mp3"
#define MUSIC_URL_3 "http://wx.nationalchip.com/guoxin_test2.mp3"

// 播放指定序号音乐(1/2/3)
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;
        src.format = AI_AUDIO_CODEC_WAV;
        break;
    case 2:
        src.url = MUSIC_URL_2;
        src.format = AI_AUDIO_CODEC_WAV;
        break;
    case 3:
        src.url = MUSIC_URL_3;
        src.format = AI_AUDIO_CODEC_WAV;
        break;
    default:
        TAL_PR_ERR("invalid index");
        return;
}

music.src_cnt = 1;
music.src_array = &src;

wukong_audio_play_music(&music);
}

是否必现:是

Attachments
MobaXterm_460800_20260509_191041.txt
(2.17 MiB) Downloaded 24 times
愚者千虑必有一得
Posts: 929

你好! 针对 #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.mp3guoxin_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 缓冲区饥饿。可尝试:

  1. 换用稳定服务器测试:排除服务器端问题
  2. 增加 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() 函数,重新编译验证,有问题欢迎继续追问。

demo
Posts: 9

Re: T5 3.13.6 播放url音频卡顿

Code: Select all

#define MUSIC_URL_1 "http://wx.nationalchip.com/guoxin_test.mp3"
#define MUSIC_URL_2 "http://wx.nationalchip.com/guoxin_test1.mp3"
#define MUSIC_URL_3 "http://wx.nationalchip.com/guoxin_test2.mp3"

// 播放指定序号音乐(1/2/3)
void play_music(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;
        src.format = AI_AUDIO_CODEC_MP3;
        break;
    case 2:
        src.url = MUSIC_URL_2;
        src.format = AI_AUDIO_CODEC_MP3;
        break;
    case 3:
        src.url = MUSIC_URL_3;
        src.format = AI_AUDIO_CODEC_MP3;
        break;
    default:
        TAL_PR_ERR("invalid index");
        return;
}

music.src_cnt = 1;
music.src_array = &src;

wukong_audio_play_music(&music);
}

一开始是使用的MP3,播放不了,音频原格式如下:
Image

Attachments
MobaXterm_460800_20260511_140922.txt
(252.4 KiB) Downloaded 14 times
愚者千虑必有一得
Posts: 929

Re: T5 3.13.6 播放url音频卡顿

你这个是名字叫mp3的pcm文件?你放本地播放有问题吗?pcm的要加个wav的头才能正常用wav解码。

愚者千虑必有一得
Posts: 929

Re: T5 3.13.6 播放url音频卡顿

测试回复 - AI 自动分析生成

愚者千虑必有一得
Posts: 929

Re: T5 3.13.6 播放url音频卡顿

从你给的代码和音频链接看,这个问题大概率不是 wukong_audio_play_music() 调用方式本身,而是音频资源格式和流式播放特性导致的。

我这边先帮你看了下这 3 个 URL,虽然文件名后缀是 .mp3,但实际返回内容是 RIFF/WAVE,也就是实际是 WAV 文件,不是 MP3。其中:

  • guoxin_test:16kHz / 单声道 / 16bit
  • guoxin_test1:32kHz / 单声道 / 16bit
  • guoxin_test2:16kHz / 单声道 / 16bit

所以现象基本能对上:

  1. test1 播放失败:它是 32kHz WAV,和另外两个 16kHz 不一致,优先怀疑当前音频链路/播放器对该采样率的支持或重采样处理存在限制。
  2. testtest2 播放卡顿:WAV/PCM 码率比压缩音频高很多,走 HTTP 流式播放时更容易因为网络抖动或播放器 buffer 不足出现断断续续。

建议你先做 3 个验证:

1)统一测试资源格式

  • 把 3 个文件都转成同一规格,建议先统一成:WAV / 16kHz / mono / 16bit
  • 或者直接改成真正的 MP3 文件,再把 src.format 改成对应的 MP3 格式

2)确认 format 和实际文件一致

  • 如果文件实际是 WAV,就保持 AI_AUDIO_CODEC_WAV
  • 如果换成真实 MP3,就要同步改 src.format
  • 不建议继续用“.mp3 后缀但内容是 WAV”的资源做测试,容易误导排查

3)优先排除网络流式卡顿

  • 先把音频下载到本地文件系统/flash,再播放本地文件,看是否还卡顿
  • 如果本地播放正常、URL 播放卡顿,基本就可以确认是 HTTP 流式缓冲问题,不是解码本身问题

如果方便的话,建议再补一段播放时的日志,重点看:

  • URL 打开是否成功
  • 解码器初始化是否成功
  • 是否有 buffer underrun / read timeout / stream EOF 异常
  • test1 失败时是否有“不支持采样率 / 打开失败 / 解码失败”之类报错

你也可以先直接把 test1 转成 16kHz mono 16bit WAV 再测一次。如果转完后可以播放,基本就能确认问题点在 32kHz 兼容性/重采样链路

愚者千虑必有一得
Posts: 929

Re: T5 3.13.6 播放url音频卡顿

你好!

问题概述

播放 URL 音频卡顿/无法播放,原因是音频格式声明与实际资源格式不匹配。

根因分析

你的代码中所有三个 URL 的资源文件实际格式为 MP3(服务器返回 Content-Type: audio/mpeg),但代码中声明的格式是

Code: Select all

AI_AUDIO_CODEC_WAV

,这就导致解码器按 WAV 格式去解析 MP3 数据流。

推理链:

  1. URL 后缀为 .mp3,服务器 Content-Type 为 audio/mpeg → 实际资源是 MP3
  2. 代码设置 src.format = AI_AUDIO_CODEC_WAV → 解码器按 WAV 头部解析
  3. MP3 数据没有 RIFF/WAV 头部 → 解码异常 → 卡顿或无法播放
  4. test1 完全不能播放可能是该文件编码参数与解码器完全不兼容

解决方案

将格式声明改为正确的 MP3 编码。请修改代码:

Code: Select all

// 修改前(错误)
src.format = AI_AUDIO_CODEC_WAV;

// 修改后(正确)
src.format = AI_AUDIO_CODEC_MP3;

三个 case 分支都需要修改。如果头文件中没有 AI_AUDIO_CODEC_MP3 宏定义,可以检查

Code: Select all

tal_wukong_ai

组件头文件中的音频格式枚举,找到对应的 MP3 格式常量名。

验证方法

  1. 修改后重新编译烧录
  2. 分别测试三个 URL,确认播放流畅无卡顿
  3. 如果某个 URL 仍有问题,建议检查该 URL 资源的实际编码参数(采样率、比特率)

风险与回退

  • 适用版本:3.13.6 及以上
  • 无额外风险,仅修改格式声明字段
  • 回退:改回 AI_AUDIO_CODEC_WAV 即可
demo
Posts: 9

Re: T5 3.13.6 播放url音频卡顿

我看3.13.x已经不支持片内flash了,外接flash要怎么操作,怎么挂载,怎么调用函数播放音频,3个音频总共在6-7Mb,或者使用3.12.16的片内flash怎么实现,谢谢大佬

愚者千虑必有一得
Posts: 929

Re: T5 3.13.6 播放url音频卡顿

你好!T5 + 67MB 音频本地播放,回退 3.12.16 不推荐,正确方案是 3.13.6 接 SD 卡。下面给完整方案。

一、为什么不建议回退 3.12.16 用片内 Flash

  1. T5 模组(BK7258)实际 Flash 16MB,但分区表固化在 bootloader:APP 分区 68MB(已被固件占满)、OTA / USER0 / USER1 / KV / UF / LICENSE 各几 KB ~ 几百 KB,没有连续 67MB 的用户可用空间放音频。
  2. 3.12.16 已不在维护期,3.13.x 之后 T5 默认关闭片内 FATFS 是因为可用区域太小(< 1MB),把音频塞片内会与 KV / OTA 分区冲突,量产风险高。
  3. 即便强行用 USER0 / USER1 / RCD(每个 64KB ~ 256KB),3 个 67MB 文件也放不下。

结论:T5 上 67MB 本地音频,必须走外接存储(SD/TF 卡 或 外挂 SPI Flash)。SDK 默认推荐 SD 卡。

二、3.13.6 推荐方案:SD 卡 + LFS 文件系统 + 本地播放接口

源码依据:apps/tuyaos_demo_wukong_ai/src/boards/T5AI_BOARD_DESKTOP/doc/README.md 已说明该板子的方案。

  1. 硬件:T5 接 TF/SD 卡槽,SDK 已经把 SDIO 驱动到 tkl_sdcard 抽象层。
  2. 编译宏开启(在 board 的 tuya_iot_config.h 或 make.yaml 里):

    Code: Select all

    TUYA_FILE_SYSTEM      = 1
    FILE_SYSTEM_LFS_SD    = 1
  3. 卡先格式化为 exFAT,根目录约定为 /t5_fs
  4. SDK 启动时自动挂载,挂载完成后用 tkl_fs_* 系列接口读写。

三、播放本地音频的现成接口(不要自己拼)

源码:apps/tuyaos_demo_wukong_ai/src/wukong/audio/wukong_audio_player.c:292

Code: Select all

OPERATE_RET wukong_audio_play_local(CHAR_T *url, CHAR_T *song_name, CHAR_T *artist, INT_T format, INT_T size)
{
    AI_PLAYER_SRC_E src = (strstr(url, "http://") == url || strstr(url, "https://") == url) ?
                          AI_PLAYER_SRC_URL : AI_PLAYER_SRC_FILE;
    tuya_ai_playlist_clear(__s_music_playlist);
    tuya_ai_playlist_add(__s_music_playlist, src, url, format);
    return rt;
}

关键:函数内部根据 url 前缀自动选择 SRC

  • 以 http:// 或 https:// 开头 → AI_PLAYER_SRC_URL(走 HTTP 流式,受 FRAMEBUF/HTTP_YIELD 影响,就是 9337 一开始遇到的卡顿路径)

  • 否则 → AI_PLAYER_SRC_FILE,走 datasink_file(apps/tuyaos_demo_wukong_ai/src/miscs/audio_player/src/datasink/datasink_file.c),从文件系统按块读取,不走网络,没有 URL 那套缓冲卡顿问题

调用示例:

Code: Select all

#include "wukong_audio_player.h"
#include "tkl_fs.h"

void play_music_from_sd(void)
{
    BOOL_T exist = FALSE;

/* 1. 确保 SD 卡上文件存在 */
tkl_fs_is_exist("/t5_fs/music/test.mp3", &exist);
if (!exist) {
    TAL_PR_ERR("file not found, please copy mp3 to SD card /t5_fs/music/");
    return;
}

/* 2. 直接调用 wukong_audio_play_local,路径不需要 file:// 前缀 */
wukong_audio_play_local("/t5_fs/music/test.mp3",
                        "guoxin_test",
                        "demo",
                        AI_AUDIO_CODEC_MP3,   /* 真 MP3 用 MP3,真 WAV 用 WAV */
                        0);
}

参考完整 demo:apps/tuyaos_demo_wukong_ai/src/boards/T5AI_BOARD_DESKTOP/ui/desk_func_record.c:1169 已经在用 wukong_audio_play_local 播放本地录音文件,可以直接照搬。

四、SD 卡音频文件准备

  1. 把 SD 卡格式化为 exFAT
  2. 在卡上建目录 /t5_fs/music/,把 test.mp3 / test1.mp3 / test2.mp3 拷进去
  3. 上电后日志会打印 LFS 挂载成功,tkl_fs_is_exist 检查没问题就可以播

五、解码格式提醒(沿用 9337 之前的诊断)

之前帖子里出现的 guoxin_test1.mp3 实际是 32kHz WAV、不是 MP3。改成本地播放后请先用 hex 工具确认文件真实格式:

  • 文件头是 ID3 / 0xFF Fx → 真 MP3 → format = AI_AUDIO_CODEC_MP3

  • 文件头是 RIFF...WAVE → WAV → format = AI_AUDIO_CODEC_WAV

  • 同时 WAV 的采样率/位深,要和 ai_player 配置匹配(默认 16kHz/16bit/mono)

六、3.12.16 用片内 Flash 的可行性结论

不可行,原因:

  1. 3.12.16 时代 T5 默认未开放 6MB+ 的连续用户分区,分区表里能给应用层用的只有 USER0 / USER1(< 256KB)。

  2. 即便强行修改 partition_table 抢占 OTA / APP 区域,会破坏 OTA 升级能力和系统鲁棒性,量产不允许。

  3. 3.12.16 已停维护,安全/Bug fix 不会回合到老分支。

如果你必须本地(不接 SD),唯一现实方案是:换更大模组 + 外挂 SPI NOR Flash(比如 16MB Flash 通过 SPI 接到 T5 空闲 GPIO,自己实现简单 file-like 缓存层),属于定制方案,需要硬件配合,不在标准 SDK 流程里。

七、推荐做法(最佳实践)

  1. 留在 3.13.6(最新稳定版),不回退 3.12.16

  2. 硬件加 TF 卡座,开启 TUYA_FILE_SYSTEM + FILE_SYSTEM_LFS_SD

  3. 67MB 三个文件放 /t5_fs/music/

  4. wukong_audio_play_local() 文件路径模式播放,零网络/零 HTTP 缓冲问题

  5. URL 模式只用于真正的在线流媒体(不是本地资源)

需要哪部分的完整 demo(make.yaml 宏配置 / 板级 SD 卡引脚 / 完整 main 调用例子),告诉我具体场景我再给。

Post Reply