GStreamer实现H.264音视频复用流传输及同步存文件方案
问题背景
我有一台运行Linux系统的嵌入式设备,搭载图像传感器与麦克风,当前使用GStreamer处理采集到的原始音视频数据。
当前已调通音视频采集存储为MP4文件的管线,可将视频编码为H.264格式、音频编码为AAC格式后封装保存:
gst-launch-1.0 -v v4l2src \ ! video/x-raw,width=2560,height=720,framerate=30/1,format=GRAY8 \ ! queue \ ! videocrop right=1280 \ ! videoconvert \ ! vpuenc_h264 \ ! h264parse \ ! mpegtsmux name=mux \ ! filesink location=/run/media/mmcblk2p4/test.mp4 sync=false async=false \ alsasrc device="hw:0,0" \ ! audio/x-raw,format=S16LE,rate=22050,channels=1 \ ! queue \ ! audioconvert \ ! avenc_aac \ ! mux.
硬件输出原生视频为双倍宽度720p规格(分辨率2560×720),通过videocrop元件裁剪为1280×720分辨率,其中vpuenc_h264为设备所用SoC配套的硬件H.264编码器。
目前已实现纯视频网络流传输,可用管线如下:
gst-launch-1.0 -v v4l2src \ ! video/x-raw,width=2560,height=720,framerate=30/1,format=GRAY8 \ ! videocrop left=0 right=1280 \ ! videoconvert \ ! vpuenc_h264 \ ! h264parse \ ! rtph264pay \ ! udpsink host=192.168.5.2 port=5000 sync=false async=false
当前需要实现音视频复用后的网络流传输,已知mpegtsmux与rtph264pay元件不兼容,因对GStreamer可选插件不熟悉,提出两个问题:
- 是否存在可兼容
rtph264pay的音视频复用元件,能够实现音视频复用后的H.264流传输? - 是否可以借助
tee等元件,实现同一份复用后的音视频流同时用于网络传输与本地文件存储,避免两次复用造成的资源浪费?
解答
问题1:音视频RTP传输的适配方案
这里先明确一个基础逻辑:rtph264pay的定位是裸H.264基本码流(ES流)的RTP打包元件,输入必须是未复用的纯H.264数据,不存在能直接接在rtph264pay前端的音视频复用元件。要实现音视频同步的RTP网络传输,有两种成熟落地的方案:
- 方案一:音视频分别打包RTP,分端口传输
视频路径沿用现有逻辑,经rtph264pay打包后发5000端口;音频编码为AAC后,通过rtpmp4apay做RTP打包,发5002端口。接收端分别对两个端口的RTP流解包,再做音视频同步即可。该方案延迟最低,适合对实时性要求极高的场景。 - 方案二:MPEG-TS复用后统一RTP打包,单端口传输
直接复用已经调通的mpegtsmux逻辑,先把编码后的H.264视频、AAC音频复用为MPEG-TS流,再通过rtpmp2tpay把整路TS流打包为RTP包,走单个UDP端口传输。该方案不需要单独处理音视频同步、端口映射问题,适配成本极低,是嵌入式音视频传输场景的最常用方案,全程不需要用到rtph264pay元件。
问题2:流同时输出网络与本地存储的实现
完全可以通过tee元件实现,编码、复用环节全程只执行一次,不会额外占用硬件编码器和CPU资源,资源占用和单路输出基本一致。
核心逻辑是:mpegtsmux输出的TS流仅生成一份,通过tee拆分为两个独立分支,一个分支走RTP打包发网络,另一个分支直接写入本地存储即可。
可直接参考的完整管线如下:
gst-launch-1.0 -v v4l2src \ ! video/x-raw,width=2560,height=720,framerate=30/1,format=GRAY8 \ ! queue \ ! videocrop right=1280 \ ! videoconvert \ ! vpuenc_h264 \ ! h264parse \ ! mpegtsmux name=mux \ ! tee name=t \ t. ! queue ! rtpmp2tpay ! udpsink host=192.168.5.2 port=5000 sync=false async=false \ t. ! queue ! filesink location=/run/media/mmcblk2p4/test.ts sync=false async=false \ alsasrc device="hw:0,0" \ ! audio/x-raw,format=S16LE,rate=22050,channels=1 \ ! queue \ ! audioconvert \ ! avenc_aac \ ! mux.
配置时注意两个细节:
tee拆分后的每个分支都必须单独加queue元件,避免不同分支的数据流处理速度差导致互相阻塞- 本地存储优先用TS格式,抗损坏能力强,嵌入式设备异常断电不会导致整个文件无法播放。如果必须输出MP4格式,可在文件存储分支的
queue后增加mp4mux元件再接filesink即可。
内容的提问来源于stack exchange,提问作者David C.
相关产品推荐
相关产品推荐

