splitmuxsink无法读取matroskademux音频及GStreamer管线调试求助
GStreamer 音视频合并与分段输出问题
初始管线的无音频问题
用户构建了将摄像头视频与麦克风音频合并后输出完整文件和分段文件的管线:
gst-launch-1.0 -v libcamerasrc ! 'video/x-raw,width=1920,height=1080,framerate=30/1' ! v4l2convert ! clockoverlay time-format="%A | %d %B %Y | %H:%M:%S" ! v4l2h264enc extra-controls="controls, h264_profile=4, video_bitrate=2000000" ! 'video/x-h264,profile=high,level=(string)4' ! h264parse ! mux. \ alsasrc device=hw:1,0 ! queue ! audioconvert ! lamemp3enc ! mux. \ matroskamux name=mux ! tee name=t \ t. ! queue ! matroskademux ! splitmuxsink location="splitvideo-%02d.mkv" max-size-bytes=100000000 max-files=80 muxer=matroskamux \ t. ! queue ! filesink location=fullvideo.mkv
问题:fullvideo.mkv包含音频,但分段生成的splitvideo-%02d.mkv无音频。
原因分析
splitmuxsink的核心特性是以第一个流入的媒体流作为分段触发基准,且仅处理该基准流同步的其他流。在这个管线中:
matroskademux会异步输出视频和音频流,视频流通常会先到达splitmuxsink;splitmuxsink在初始化阶段仅识别到视频流的caps,将其设为分段基准,后续到达的音频流会被忽略;- 此外,
matroskademux与splitmuxsink之间无同步机制,音频流可能因时序问题被丢弃。
分路管线的链接问题
用户尝试将视频和音频分别通过tee分路,同时输出完整文件和分段文件:
gst-launch-1.0 -v libcamerasrc ! 'video/x-raw,width=1920,height=1080,framerate=30/1' ! v4l2convert ! clockoverlay time-format="%A | %d %B %Y | %H:%M:%S" ! v4l2h264enc extra-controls="controls, h264_profile=4, video_bitrate=2000000" ! 'video/x-h264,profile=high,level=(string)4' ! h264parse ! tee name=videoTee \ alsasrc device=hw:1,0 ! queue ! audioconvert ! lamemp3enc ! tee name=audioTee \ splitmuxsink location="%02d.mkv" max-size-bytes=100000000 max-files=80 muxer=matroskamux name=splitVideosMux \ matroskamux name=fullVideoMux ! filesink location=fullvideo.mkv \ audioTee. ! queue ! fullVideoMux. \ videoTee. ! queue ! fullVideoMux. \ audioTee. ! queue ! splitVideosMux. \ videoTee. ! queue ! splitVideosMux.
错误提示:WARNING: erroneous pipeline: could not link queue3 to splitVideosMux,移除queue后管线可正常运行,但存在丢帧/音频不同步隐患。
原因分析
splitmuxsink的sink pad是动态请求式pad:它不会预先创建固定的sink pad,而是在接收到媒体流时,根据流的类型(视频/音频)动态生成对应的pad。
- 直接连接
audioTee. ! splitVideosMux.时,GStreamer会触发splitmuxsink动态创建对应音频类型的sink pad,完成链接; - 加入
queue后,queue的src pad是静态的,而此时splitmuxsink尚未生成对应的动态pad,GStreamer无法完成静态pad与动态pad的自动匹配,导致链接失败。
解决方案
1. 修正分路管线(添加queue且保证链接成功)
在gst-launch中,可通过先链接视频流触发splitmuxsink创建pad,再链接音频流的方式,同时保留queue:
gst-launch-1.0 -v libcamerasrc ! 'video/x-raw,width=1920,height=1080,framerate=30/1' ! v4l2convert ! clockoverlay time-format="%A | %d %B %Y | %H:%M:%S" ! v4l2h264enc extra-controls="controls, h264_profile=4, video_bitrate=2000000" ! 'video/x-h264,profile=high,level=(string)4' ! h264parse ! tee name=videoTee \ alsasrc device=hw:1,0 ! queue ! audioconvert ! lamemp3enc ! tee name=audioTee \ matroskamux name=fullVideoMux ! filesink location=fullvideo.mkv \ splitmuxsink location="%02d.mkv" max-size-bytes=100000000 max-files=80 muxer=matroskamux name=splitVideosMux \ # 先链接视频流,触发splitmuxsink创建视频pad videoTee. ! queue ! splitVideosMux. \ # 再链接音频流,此时splitmuxsink已能识别音频类型并创建对应pad audioTee. ! queue ! splitVideosMux. \ # 完整文件的链接 videoTee. ! queue ! fullVideoMux. \ audioTee. ! queue ! fullVideoMux.
或者使用capsfilter明确指定流类型,提前告知splitmuxsink需要创建的pad类型:
gst-launch-1.0 -v libcamerasrc ! 'video/x-raw,width=1920,height=1080,framerate=30/1' ! v4l2convert ! clockoverlay time-format="%A | %d %B %Y | %H:%M:%S" ! v4l2h264enc extra-controls="controls, h264_profile=4, video_bitrate=2000000" ! 'video/x-h264,profile=high,level=(string)4' ! h264parse ! tee name=videoTee \ alsasrc device=hw:1,0 ! queue ! audioconvert ! lamemp3enc ! tee name=audioTee \ splitmuxsink location="%02d.mkv" max-size-bytes=100000000 max-files=80 muxer=matroskamux name=splitVideosMux \ matroskamux name=fullVideoMux ! filesink location=fullvideo.mkv \ audioTee. ! queue ! fullVideoMux. \ videoTee. ! queue ! fullVideoMux. \ audioTee. ! queue ! capsfilter caps="audio/mpeg,mpegversion=1,layer=3" ! splitVideosMux. \ videoTee. ! queue ! capsfilter caps="video/x-h264,profile=high,level=(string)4" ! splitVideosMux.
2. 避免先合流再解复用的低效方案
初始管线中先合流再解复用的方式既低效又容易导致流丢失,建议直接采用分路管线的方案,让视频和音频流分别进入对应的muxer,保证同步性和完整性。
内容的提问来源于stack exchange,提问作者Łukasz Zaroda
相关产品推荐
相关产品推荐

