Gstreamer USB摄像头音视频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音视频文件的命令如下:
在这里插入图片描述
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进行缓冲同步。

imx6q嵌入式平台操作示例

在这里插入图片描述
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 编码

合成可同步推流的rtmp流

Ubuntu16.04 PC平台操作示例

首先使用音频裸数据进行合成
因为罗技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.
这里有一个问题推流后,在页面播放时,很不流畅,会出现断断续续的现象,原因有待查明。

imx6q嵌入式平台操作示例

合成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.

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

在这里插入图片描述
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.

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

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: Linux是一种常用的开源操作系统,而USB摄像头则是Linux系统下常用的一种摄像设备。通过在Linux系统上安装相应的驱动程序,可以使USB摄像头正常工作,并且通过命令行工具或者图形化界面来实现对摄像头的控制和调节。 而RTMP则是一种流媒体协议,主要用于实时的音视频传输和播放。在Linux系统中,可以通过安装FFmpeg等工具来实现RTMP协议的使用,从而将USB摄像头采集的视频流传输到云端进行直播或者点播等操作。 在使用Linux USB摄像头进行RTMP传输时,需要注意以下几点:首先,需要合理设置摄像头的分辨率、帧率等参数,以保证传输效果。其次,需要选择合适的网络带宽和传输速度,以保证视频的清晰度和流畅度。最后,需要选择合适的直播平台或者播放器,以兼容RTMP协议并支持Linux系统的使用。 总之,Linux USB摄像头RTMP协议的结合可以满足用户在视频直播、视频监控等方面的需求,具有很高的应用价值和推广空间。 ### 回答2: Linux USB摄像头可以通过一些软件(如Cheese、Guvcview、VLC等)来访问和使用。如果要将其视频流以RTMP协议传输到网络上,就需要用到一些工具和库。 首先是FFmpeg,这是一个开源的多媒体处理库,它支持各种编码格式和网络协议。我们可以使用FFmpeg来捕获USB摄像头的视频流,然后编码和推流到网络上。 其次是librtmp,这是一个开源的RTMP协议库,可以实现RTMP协议的推流和拉流功能。我们可以使用FFmpeg中的librtmp模块来推送RTMP流到服务器上。 最后是一些脚本或者自动化工具,可以对FFmpeg的推流命令进行封装或者简化,从而简化推流的操作和管理。 总之,使用Linux USB摄像头推送RTMP流需要的工具和库并不复杂,只需要掌握好一些基本概念和命令,就能够完成这个任务。 ### 回答3: Linux支持的USB摄像头在使用RTMP流媒体传输协议时非常方便。RTMP(Real-Time Messaging Protocol)是Adobe采用的基于TCP的实时流媒体传输协议,因此可以使用许多开源工具和库,如FFmpeg和GStreamer等,将USB摄像头流式传输到RTMP服务器。 使用Linux和FFmpeg或GStreamer实现USB摄像头RTMP流媒体传输,需要以下步骤: 1. 安装所需的软件包,例如FFmpeg或GStreamer。 2. 将USB摄像头连接到Linux设备上。 3. 在命令行中输入命令来打开USB摄像头: ·对于FFmpeg: ```ffmpeg -f v4l2 -i /dev/video0 -f flv rtmp://server-url/stream-key``` ·对于GStreamer: ```gst-launch-1.0 v4l2src ! videoconvert ! x264enc ! flvmux ! rtmpsink location=rtmp://server-url/stream-key``` 4. 将“server-url”替换为RTMP服务器的地址,将“stream-key”替换为流的名称或密钥。 5. 测试是否成功,可以使用流查看器来查看或者在浏览器输入rtmp://server-url/stream-key地址进行播放。 在Linux上使用USB摄像头RTMP流的形式发送视频,可以实现许多应用,例如视频会议、直播和视频监控等。使用Linux和开源软件,可以轻松地实现这些方案并将其集成到现有的基础设施中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值