Gstreamer USB摄像头音视频AVI文件合成与rtmp推流

文章目录

  • gstreamer音视频同步问题
  • 合成可同步播放的AVI文件
    • Ubuntu16.04 PC平台操作示例
    • 添加视频时间戳
    • imx6q嵌入式平台操作示例
  • 合成可同步推流的rtmp流
    • Ubuntu16.04 PC平台操作示例
    • imx6q嵌入式平台操作示例
  • 同时完成AVI文件合成与rtmp推流

之前关于Gstreamer的文章要么只操作音频,要么只操作视频,现在需要同时操作音视频,分别完成音视频文件合成与推流。

gstreamer音视频同步问题

读取USB摄像头的音频数据文章中使用Gstreamer命令行工具,合成的AVI音视频文件在播放时音视频不同的问题现已查明。
gst-launch-1.0 -e avimux name=mux1 ! filesink location=test.avi \ v4l2src device=/dev/video0 ! video/x-h264, framerate=30/1, width=640, height=360 ! mux1. \ alsasrc device=hw:2,0 ! audio/x-raw, rate=32000, channels=2, layout=interleaved, format=S16LE ! mux1.
此命令行合成的音视频AVI文件播放不同步,原因如下:

  • 此命令行生成的管道在avimux元件之前有两个数据源,分别是音频数据、视频数据
  • 音频数据的生成速度与H264视频数据的生成速度不一致
  • 在进行AVI文件合成时,数据的消耗速率不一致

由以上原因导致合成的AVI音视频文件在播放时视频部分与音频部分不同步。
解决方法是分别在音频、视频数据流中增加一个queue元件,此元件在gstreamer中会创建一个队列,并将元件前后的数据处理用多线程的方式完成,并会根据各自数据的消耗速率来进行同步,这样就可以完成音视频文件合成的同步。

合成可同步播放的AVI文件

Ubuntu16.04 PC平台操作示例

首先通过arecord -l命令查看USB摄像头生成的音频设备文件
card 1: C920 [HD Pro Webcam C920], device 0: USB Audio [USB Audio] 子设备: 1/1 子设备 #0: subdevice #0
因此USB的音频设备为hw:1,0
Gstreamer合成AVI音视频文件的命令如下:
Gstreamer USB摄像头音视频AVI文件合成与rtmp推流_第1张图片
gst-launch-1.0 -e avimux name=mux1 ! filesink location=test.avi v4l2src device=/dev/video0 ! video/x-h264, framerate=30/1, width=640, height=360 ! queue ! mux1. alsasrc device=hw:1,0 ! audio/x-raw, rate=32000, channels=2, layout=interleaved, format=S16LE ! queue ! mux1.
此命令直接读取USB摄像头的视频H264帧、音频裸数据(pcm数据)合称为AVI文件,

由于以上命令中音频数据未经过编码压缩,因此合成后的AVI文件偏大,可以在命令中加入音频编码元件,将音频编码为MP3,然后再进行合成。命令如下:
Gstreamer USB摄像头音视频AVI文件合成与rtmp推流_第2张图片
gst-launch-1.0 -e avimux name=mux1 ! filesink location=test.avi v4l2src device=/dev/video0 ! video/x-h264, framerate=30/1, width=640, height=360 ! queue ! mux1. alsasrc device=hw:1,0 ! audio/x-raw, rate=32000, channels=2, layout=interleaved, format=S16LE ! lamemp3enc ! queue ! mux1.

以下图片是查看合成后的AVI文件属性
Gstreamer USB摄像头音视频AVI文件合成与rtmp推流_第3张图片
当使用音频裸数据进行视频文件合成时,在文件属性的比特率这一项上将无法展示,没有数据值。
由于AVI支持32000 采样率的音频数据输入,因此AVI文件在播放时不会发生声音畸变。

添加视频时间戳

Gstreamer USB摄像头音视频AVI文件合成与rtmp推流_第4张图片
将H264帧解码后,加时间戳,然后再编码,最后合成为AVI文件
gst-launch-1.0 -e avimux name=mux1 ! filesink location=test.avi v4l2src device=/dev/video0 ! video/x-h264, framerate=30/1, width=640, height=360 ! avdec_h264 ! queue ! clockoverlay ! x264enc ! queue ! mux1. alsasrc device=hw:1,0 ! audio/x-raw, rate=32000, channels=2, layout=interleaved, format=S16LE ! queue ! lamemp3enc ! queue ! mux1.

在一些命令测试过程中如出现以下情况:

警告:来自组件 /GstPipeline:pipeline0/GstAlsaSrc:alsasrc0:Can't record audio fast enough
额外的调试信息:
gstaudiobasesrc.c(869): gst_audio_base_src_create (): 
/GstPipeline:pipeline0/GstAlsaSrc:alsasrc0:
Dropped 35840 samples. 
This is most likely because downstream can't keep up and is consuming samples too slowly.
警告:来自组件 /GstPipeline:pipeline0/GstAlsaSrc:alsasrc0:Can't record audio fast enough

说明音视频数据没有达到同步状态,需要在一些数据变换中间添加queue进行缓冲同步。

imx6q嵌入式平台操作示例

Gstreamer USB摄像头音视频AVI文件合成与rtmp推流_第5张图片
gst-launch-1.0 -e avimux name=mux1 ! filesink location=test.avi v4l2src device=/dev/video0 ! video/x-h264, framerate=30/1, width=640, height=360 ! queue ! mux1. alsasrc device=hw:2,0 ! audio/x-raw, rate=32000, channels=2, layout=interleaved, format=S16LE ! queue ! mux1.
此命令直接读取USB摄像头的视频H264帧、音频裸数据(pcm数据)合称为AVI文件。

Gstreamer USB摄像头音视频AVI文件合成与rtmp推流_第6张图片
gst-launch-1.0 -e avimux name=mux1 ! filesink location=test.avi v4l2src device=/dev/video0 ! video/x-h264, framerate=30/1, width=640, height=360 ! queue ! mux1. alsasrc device=hw:2,0 ! audio/x-raw, rate=32000, channels=2, layout=interleaved, format=S16LE ! imxmp3enc ! queue ! mux1.
imx6平台需要使用imxmp3enc元件进行MP3 编码

合成可同步推流的rtmp流

Ubuntu16.04 PC平台操作示例

首先使用音频裸数据进行合成
因为罗技C920摄像头仅支持到32000 最大采样率,但是flvmux元件默认的音频数据输入为44100,需要audioparse元件将音频数据转换为符合flvmux元件的格式;因此合成后的flv视频文件在播放时,声音会发生畸变,在用rtmpsink推流后播放时也会出现变声。命令如下:
Gstreamer USB摄像头音视频AVI文件合成与rtmp推流_第7张图片
gst-launch-1.0 -e flvmux name=mux1 ! rtmpsink location=rtmp://192.168.1.102:1935/live0 v4l2src device=/dev/video0 ! video/x-h264, framerate=30/1, width=640, height=360! h264parse ! queue ! mux1. alsasrc device=hw:1,0 ! audio/x-raw, rate=32000, channels=2, layout=interleaved, format=S16LE ! audioparse ! queue ! mux1.

可以将rtmpsink元件给为filesink元件,合成一个flv视频文件,查看文件属性。命令如下:
Gstreamer USB摄像头音视频AVI文件合成与rtmp推流_第8张图片
gst-launch-1.0 -e flvmux name=mux1 ! filesink location=test.flv v4l2src device=/dev/video0 ! video/x-h264, framerate=30/1, width=640, height=360! h264parse ! queue ! mux1. alsasrc device=hw:1,0 ! audio/x-raw, rate=32000, channels=2, layout=interleaved, format=S16LE ! audioparse ! queue ! mux1.
Gstreamer USB摄像头音视频AVI文件合成与rtmp推流_第9张图片
以上命令使用音频裸数据进行合成,数据量偏大,可以使用MP3 编码元件将音频数据压缩后进行合成。命令如下:
Gstreamer USB摄像头音视频AVI文件合成与rtmp推流_第10张图片
gst-launch-1.0 -e flvmux name=mux1 ! rtmpsink location=rtmp://192.168.1.102:1935/live0 v4l2src device=/dev/video0 ! video/x-h264, framerate=30/1, width=640, height=360! h264parse ! queue ! mux1. alsasrc device=hw:1,0 ! audio/x-raw, rate=32000, channels=2, layout=interleaved, format=S16LE ! queue ! audioparse ! lamemp3enc ! mpegaudioparse ! queue ! mux1.
这里有一个问题推流后,在页面播放时,很不流畅,会出现断断续续的现象,原因有待查明。

imx6q嵌入式平台操作示例

合成flv格式视频,使用音频裸数据。命令如下:
Gstreamer USB摄像头音视频AVI文件合成与rtmp推流_第11张图片
gst-launch-1.0 -e flvmux name=mux1 ! rtmpsink location=rtmp://192.168.1.102:1935/live0 v4l2src device=/dev/video0 ! video/x-h264, framerate=30/1, width=640, height=360 ! queue ! h264parse ! mux1. alsasrc device=hw:2,0 ! audio/x-raw, rate=32000, channels=2, layout=interleaved, format=S16LE ! queue ! audioparse ! mux1.

合成flv视频格式时,将音频数据编码为MP3 格式,命令如下:
Gstreamer USB摄像头音视频AVI文件合成与rtmp推流_第12张图片
gst-launch-1.0 -e flvmux name=mux1 ! rtmpsink location=rtmp://192.168.1.102:1935/live0 v4l2src device=/dev/video0 ! video/x-h264, framerate=30/1, width=640, height=360 ! queue ! h264parse ! mux1. alsasrc device=hw:2,0 ! audio/x-raw, rate=32000, channels=2, layout=interleaved, format=S16LE ! queue ! audioparse ! imxmp3enc ! mpegaudioparse ! queue ! mux1.

同时完成AVI文件合成与rtmp推流

Gstreamer USB摄像头音视频AVI文件合成与rtmp推流_第13张图片
gst-launch-1.0 -e avimux name=avimux ! filesink location=test.avi v4l2src device=/dev/video0 ! \ video/x-h264, framerate=30/1, width=640, height=360 ! queue ! tee name=h264tee ! \ queue ! avimux. h264tee. ! queue ! h264parse ! flvmux name=flvmux ! rtmpsink location='rtmp://192.168.1.102:1935/live0' \ alsasrc device=hw:2,0 ! audio/x-raw, rate=32000, channels=2, layout=interleaved, format=S16LE ! queue ! audioparse ! \ lamemp3enc ! tee name=mp3tee ! queue ! avimux. mp3tee. ! queue ! mpegaudioparse ! flvmux.

测试了这么多命令,下一篇将用代码实现这些命令。

你可能感兴趣的:(gstreamer,音视频)