You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GStreamer分离RTMP音视频经共享内存传输时音频读取停滞问题

问题根因

你当前音频链路卡死的核心原因是**mp4mux/qtdemux组合不适用于实时流式透传场景**:

  • 即使开启streamable=true参数,mp4mux仍需要攒够对应moov box元数据才会输出可被解析的完整数据;
  • qtdemux在未获取到完整moov头之前,不会向下游输出任何音频缓冲区;
  • 共享内存传输没有常规流的EOS(流结束)信号,qtdemux会一直等待未拿到的元数据,直接进入停滞状态,这就是你观察到的shmsrc读取音频无响应的现象。

你不需要对音频做二次处理,完全没必要额外加mp4容器做中间层,额外的mux/demux操作只会增加延迟和故障点。

可行解决方案

方案1:直接透传带ADTS头的AAC帧(推荐,零额外开销)

AAC格式本身支持带ADTS同步头的流式传输,不需要容器承载就能识别帧边界,是音频透传场景的最优选择。

修正后接收端音频链路

将原接收端的mp4mux相关逻辑替换为:

demux.audio ! aacparse output-header=true ! queue ! shmsink socket-path=/tmp/foo sync=true wait-for-connection=false shm-size=10000000

aacparse的output-header=true参数会强制给每帧AAC加上ADTS同步头,下游不需要容器就能直接切分帧。

修正后发送端音频链路

将原发送端的qtdemux相关逻辑替换为:

shmsrc socket-path=/tmp/foo ! audio/mpeg, mpegversion=4, stream-format=adts ! aacparse ! queue ! mux.audio

该方案无额外封装/解封装开销,延迟最低,完全不会出现元数据等待导致的卡死问题。

方案2:换用实时友好的容器(特殊场景使用)

如果因业务要求必须用容器承载共享内存内的音频数据,替换掉mp4/mov格式,选用天生支持实时流的容器组合:

  • 可选组合1:flvmux streamable=true 搭配 flvdemux
  • 可选组合2:matroskamux streamable=true 搭配 matroskademux
    以上两类mux拿到一帧数据就会立刻输出,不需要攒元数据,不会出现demux等头卡死的问题。
    以flv组合为例,接收端音频链路:
demux.audio ! aacparse ! queue ! flvmux streamable=true ! shmsink socket-path=/tmp/foo sync=true wait-for-connection=false shm-size=10000000

发送端音频链路:

shmsrc socket-path=/tmp/foo ! flvdemux ! aacparse ! queue ! mux.audio
额外排查方向

如果替换链路后仍有异常,按以下顺序排查:

  • 时间戳对齐校验:视频经过重编码后会生成新的时间戳,必须保证重编码后的视频时间戳和透传的音频时间戳同源对齐,否则flvmux会持续等待时间戳匹配的帧,出现链路停滞。可在音频、视频链路末端分别接入fakesink dump=true,确认两类缓冲区都在持续正常输出。
  • 共享内存参数调整:10MB大小的共享内存完全足够承载AAC音频流(常规AAC码率仅128~320kbps,10MB可缓存数十秒的音频数据),不要设置过大的shm-size,避免出现写入指针偏移异常。
  • 本地链路验证:先将shmsink/shmsrc替换为同进程内的链路直接对接fakesink/flvmux,排除编解码、封装逻辑本身的问题后,再切回跨进程共享内存链路。

内容的提问来源于stack exchange,提问作者BetaVersion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 02:01:12