读取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文件播放不同步,原因如下:
由以上原因导致合成的AVI音视频文件在播放时视频部分与音频部分不同步。
解决方法是分别在音频、视频数据流中增加一个queue
元件,此元件在gstreamer中会创建一个队列,并将元件前后的数据处理用多线程的方式完成,并会根据各自数据的消耗速率来进行同步,这样就可以完成音视频文件合成的同步。
首先通过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音视频文件的命令如下:
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,然后再进行合成。命令如下:
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文件属性
当使用音频裸数据进行视频文件合成时,在文件属性的比特率
这一项上将无法展示,没有数据值。
由于AVI支持32000
采样率的音频数据输入,因此AVI文件在播放时不会发生声音畸变。
将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
进行缓冲同步。
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文件。
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 编码
首先使用音频裸数据进行合成
因为罗技C920摄像头仅支持到32000
最大采样率,但是flvmux元件默认的音频数据输入为44100
,需要audioparse
元件将音频数据转换为符合flvmux
元件的格式;因此合成后的flv视频文件在播放时,声音会发生畸变,在用rtmpsink推流后播放时也会出现变声。命令如下:
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视频文件,查看文件属性。命令如下:
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.
以上命令使用音频裸数据进行合成,数据量偏大,可以使用MP3 编码元件将音频数据压缩后进行合成。命令如下:
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.
这里有一个问题推流后,在页面播放时,很不流畅,会出现断断续续的现象,原因有待查明。
合成flv格式视频,使用音频裸数据。命令如下:
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 格式,命令如下:
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.
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.
测试了这么多命令,下一篇将用代码实现这些命令。