SDK 3.13.6 无法播放指定 HTTPS MP3 链接

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


Post Reply
Gus1
Posts: 2

版本:
TuyaOS 3.13.6

平台:
T5

问题描述:
AI聊天对话时触发,儿童故事“龙的眼睛” 无法播放/无反应。

链接:
https://polysense.tuyacn.com/audio/musi ... 50a1d9.mp3

是否必现:

日志:
[05-26 21:49:23.746 ty E][0x60fa495c][decoder_mp3.c:134] MP3Decode failed, ret=-6, offset=3303, in_len=4096
[05-26 21:49:23.752 ty E][0x60fa495c][decoder_mp3.c:134] MP3Decode failed, ret=-6, offset=11, in_len=4085
[05-26 21:49:24.030 ty D][0x60f62068][gsensor.c:509] [tuya_imu]accel_x:-1039, accel_y:38, accel_z:7
[05-26 21:49:24.331 ty D][0x60f62068][gsensor.c:509] [tuya_imu]accel_x:-1037, accel_y:28, accel_z:2
[ONBOARD_MIC] data_size: 256000(Bytes), 62KB/s
[RAW_READ] data_size: 128000(Bytes), 31KB/s
[RAW_WRITE] data_size: 46906(Bytes), 11KB/s
[ONBOARD_SPK] data_size: 46080(Bytes), 11KB/s
[WIFI_TX] data_size: 128000(Bytes), 31KB/s
[WIFI_RX] data_size: 122612(Bytes), 29KB/s
[05-26 21:49:24.485 ty E][0x60fa495c][decoder_mp3.c:134] MP3Decode failed, ret=-9, offset=3432, in_len=3919
[05-26 21:49:24.631 ty D][0x60f62068][gsensor.c:509] [tuya_imu]accel_x:-1033, accel_y:59, accel_z:10
[05-26 21:49:24.849 ty E][0x60fa495c][decoder_mp3.c:134] MP3Decode failed, ret=-9, offset=3422, in_len=3289
[05-26 21:49:24.931 ty D][0x60f62068][gsensor.c:509] [tuya_imu]accel_x:-1035, accel_y:39, accel_z:-1
[05-26 21:49:25.226 ty E][0x60fa495c][decoder_mp3.c:134] MP3Decode failed, ret=-9, offset=3328, in_len=3975
[05-26 21:49:25.286 ty D][0x60f62068][gsensor.c:509] [tuya_imu]accel_x:-1034, accel_y:39, accel_z:5
[05-26 21:49:25.611 ty D][0x60f62068][gsensor.c:509] [tuya_imu]accel_x:-1038, accel_y:42, accel_z:13
[05-26 21:49:25.742 ty D][0x28052634][wukong_audio_aec_vad.c:123] ################ [vad stop] ################

[05-26 21:49:25.912 ty D][0x60f62068][gsensor.c:509] [tuya_imu]accel_x:-1031, accel_y:40, accel_z:12
[05-26 21:49:26.212 ty D][0x60f62068][gsensor.c:509] [tuya_imu]accel_x:-1036, accel_y:31, accel_z:1
[05-26 21:49:26.512 ty D][0x60f62068][gsensor.c:509] [tuya_imu]accel_x:-1043, accel_y:36, accel_z:1
[05-26 21:49:26.520 ty D][0x28052634][wukong_audio_aec_vad.c:111] speexdsp process time: aec->7(ms), count = 3501

[05-26 21:49:26.523 ty D][0x28052634][wukong_audio_aec_vad.c:131] rnn_date_version: 25082101

[05-26 21:49:26.524 ty D][0x28052634][wukong_audio_aec_vad.c:132] rnn vad process time: rnn vad->2(ms), flag=2, count = 3501

[05-26 21:49:26.671 ty D][0x60fa495c][tls_transporter.c:93] tls transporter close socket fd:2
[05-26 21:49:26.671 ty D][0x60fa495c][tcp_transporter.c:173] tcp transporter close socket fd:2
[05-26 21:49:26.672 ty D][0x60fa495c][tls_transporter.c:101] tls transporter close tls handler:0x60eea078
[05-26 21:49:26.673 ty D][0x60fa495c][tuya_tls.c:1272] TUYA_TLS Disconnect ENTER
[05-26 21:49:26.674 ty D][0x60fa495c][tuya_tls.c:1297] TUYA_TLS Disconnect Success
[05-26 21:49:26.674 ty D][0x60fa495c][tuya_tls.c:990] tuya_tls_connect_destroy.
[05-26 21:49:26.683 ty E][0x60fa495c][decoder_mp3.c:123] MP3FindSyncWord not find!
[05-26 21:49:26.685 ty N][0x60fa495c][svc_ai_player.c:256] ai player BG eof
[05-26 21:49:26.685 ty D][0x60fa495c][svc_ai_player.c:117] stop player BG
[05-26 21:49:26.685 ty D][0x60fa495c][svc_ai_playlist.c:54] playlist player state 0 index 0 count 1 loop 0 single 0
[05-26 21:49:26.685 ty D][0x60fa495c][wukong_audio_player.c:72] wukong audio player -> player music event: 0
[05-26 21:49:26.686 ty D][0x60fa495c][wukong_audio_player.c:79] wukong audio player -> stop event
[05-26 21:49:26.686 ty D][0x60fa495c][wukong_ai_mode_wakeup.c:378] [====ai_wakeup] event type: 30
[05-26 21:49:26.686 ty D][0x60fa495c][wukong_ai_mode_wakeup.c:484] mode wakeup state change from SPEAK to LISTEN
[05-26 21:49:26.686 ty D][0x60fa495c][svc_ai_playlist.c:336] clear playlist playing 0
[05-26 21:49:26.687 ty D][0x60fa495c][wukong_audio_player.c:112] [player_event] cmd: 0, state: 0
[05-26 21:49:26.687 ty D][0x60fa495c][wukong_playback_ctrl.c:828] [playback] state -> stopped (cur_id:0 switching:0 auto:1)
[05-26 21:49:26.687 ty N][0x60fa495c][wukong_playback_ctrl.c:854] [playback] song ended, scheduling auto-next
[05-26 21:49:26.690 ty D][0x60f6768c][servo.c:124] servo smooth motion stopped at 90°
[05-26 21:49:26.690 ty D][0x60f6768c][wukong_ai_mode_wakeup.c:142] [====ai_wakeup] listen
[05-26 21:49:26.690 ty D][0x60f6768c][tuya_ai_toy.c:920] [====ai_toy] idle timer ctrl enable:1
[05-26 21:49:26.690 ty D][0x60f6768c][tuya_ai_toy.c:908] [====ai_toy] lowpower timer ctrl enable:0
[05-26 21:49:26.691 ty N][0x60f6768c][wukong_audio_input_board.c:359] wukong audio input -> mode is 1, wakeup set to 1, vad flag is 2!
[05-26 21:49:26.826 ty D][0x60f62068][gsensor.c:509] [tuya_imu]accel_x:-1032, accel_y:39, accel_z:-19
[05-26 21:49:27.127 ty D][0x60f62068][gsensor.c:509] [tuya_imu]accel_x:-1045, accel_y:41, accel_z:5
[05-26 21:49:27.428 ty D][0x60f62068][gsensor.c:509] [tuya_imu]accel_x:-1047, accel_y:38, accel_z:8
[05-26 21:49:27.488 ty N][0x60f6bc6c][wukong_playback_ctrl.c:773] [
auto_next_thread_func] auto-play-next triggered
[05-26 21:49:27.488 ty N][0x60f6bc6c][wukong_playback_ctrl.c:1596] [playback] next: end of playlist (cur id:0 "龙的眼睛")
[05-26 21:49:27.489 ty N][0x60f6bc6c][wukong_playback_ctrl.c:787] [__auto_next_thread_func] auto-play-next: local end, fetching more via music_list


Tags:
愚者千虑必有一得
Posts: 940

Re: SDK 3.13.6 无法播放指定 HTTPS MP3 链接

问题概述

T5 平台 TuyaOS 3.13.6 在 wukong AI 故事播放链路下,对 polysense.tuyacn.com/audio/music/...50a1d9.mp3 这条 HTTPS MP3 资源调用 helix mp3 解码反复返回 -6 / -9,整段输入缓冲被丢弃,上层因取数据失败主动断开 TLS,从而表现为故事"无声/无反应"。TLS 关闭是结果,不是原因——根因在解码侧。

根因分析

  1. 错误码语义(apps/tuyaos_demo_wukong_ai/src/miscs/audio_player/src/decoder/helix/include/mp3dec.h):

    • ret = -6ERR_MP3_INVALID_FRAMEHEADER,帧头校验失败
    • ret = -9ERR_MP3_INVALID_HUFFCODES,Huffman 解码错位
      两者通常意味着字节流在帧边界发生了错位,或资源本身的帧头不符合 helix 解码器的容忍度(VBR、非标 padding、异常采样率/比特率)。
  2. 日志特征:offset=3303 / 3328 / 3422 / 3432 反复在同一窗口失败,in_len 随每次返回 0 被重置后又装入新数据,但同步字总落在同一坏点。

  3. 关键代码缺陷 —— decoder_mp3.c:120-135

    Code: Select all

       ret = MP3Decode(ctx->decoder, &in_buf, &in_len, out_buf, 0);
       if (ret != ERR_MP3_NONE) {
           if (ret == ERR_MP3_INDATA_UNDERFLOW || ret == ERR_MP3_MAINDATA_UNDERFLOW)
               return temp_len;          // 等更多数据,OK
           else {
               TAL_PR_ERR("MP3Decode failed, ret=%d, offset=%d, in_len=%d", ret, offset, in_len);
               return 0;                 // ❌ 直接丢弃整段输入,且无重同步
           }
       }

    MP3FindSyncWord 仅在入口调用一次。一旦遇到坏帧,整段 in_len 字节全被丢弃;下一批数据进来后又从同一坏点开始,循环失败。没有"跳过 1 字节再 resync"的恢复路径

  4. TLS 断开链路:上层 player 在多次 MP3Decode failed 后判定流不可用 → 主动 cancel 下载 → tls_transporter close socket fd:2 / tuya_tls Disconnect。这与"数据被截断"无关,常见误判方向。

  5. 用户描述其它 MP3 链接可播,仅这一条故事必现,佐证为「资源兼容性 + 解码器无重同步」双因

解决方案

方案 A(推荐,端侧修复,根治)—— 给 decoder_mp3_process 加帧重同步

文件:apps/tuyaos_demo_wukong_ai/src/miscs/audio_player/src/decoder/decoder_mp3.c,约 120–135 行。

Code: Select all

DECODE_MORE:
    offset = MP3FindSyncWord(in_buf, in_len);
    if (offset < 0) {
        return 0;
    }
    in_buf += offset;
    in_len -= offset;

    ret = MP3Decode(ctx->decoder, &in_buf, &in_len, (SHORT_T *)out_buf, 0);
    if (ret != ERR_MP3_NONE) {
        if (ret == ERR_MP3_INDATA_UNDERFLOW || ret == ERR_MP3_MAINDATA_UNDERFLOW)
            return temp_len;

        /* 新增:坏帧时跳过 1 字节,尝试重新同步,避免整段丢弃 */
        TAL_PR_ERR("MP3Decode failed, ret=%d, offset=%d, in_len=%d, try resync", ret, offset, in_len);
        if (in_len > 1) {
            in_buf += 1;
            in_len -= 1;
            temp_len = in_len;
            goto DECODE_MORE;
        }
        return 0;
    }

可选加一个连续坏帧计数(如 >= 8 才彻底放弃),防止恶意流死循环。

方案 B(业务侧规避,零端侧改动)—— 资源标准化重转码

helix 是定点轻量解码器,对 VBR / 非标 MP3 兼容性弱。建议 polysense 端在生成故事音频时统一规格:

Code: Select all

ffmpeg -i src.mp3 -codec:a libmp3lame -b:a 64k -ar 22050 -ac 1 -write_xing 0 out.mp3

要点:CBR、采样率 ∈ {16k, 22.05k, 44.1k}、单声道、去除非标 tag。批量替换该故事池后端侧立刻可播。

推荐 A+B 同时上线:A 提升端侧鲁棒性,B 解决全量资源兼容性。

验证方法

  1. ffprobe -v error -show_streams <url> 对失败链接抓帧信息,确认是否 VBR / 异常采样率。
  2. 烧录修改后固件,复测同一 URL:
    • 故事可播放(首尾允许少量丢帧/噪声);
    • 日志中 MP3Decode failed 显著下降;
    • 不再出现 tls_transporter close 跟随解码失败的链路。
  3. 对资源做方案 B 重转码后,用未修改固件复测应直接通过。

风险与回退

  • 适用版本:TuyaOS 3.13.x / wukong_ai demo(其它 SDK 版本若使用同一 helix 解码器同样适用)。
  • 风险:重同步循环若不加坏帧计数上限,理论上可能在完全损坏的流上长时间空转占 CPU。务必加 MAX_BAD_FRAMES 阈值(建议 8–16)。
  • 回退:方案 A 仅修改 1 个文件,git revert 即可;方案 B 在云端切换回旧资源即可。
  • 与 TLS、网络栈无关,无需改动 transporter 层。

如果方便,可以贴一段播放该 URL 时的完整下载链路日志(audio_player / 下载线程)以及该 mp3 的 ffprobe 输出,能进一步确认资源是否 VBR,方便我给出精确的最小复现补丁。

Post Reply