使用Gstreamer在录制音频+视频的同时显示无音频视频

Posted

技术标签:

【中文标题】使用Gstreamer在录制音频+视频的同时显示无音频视频【英文标题】:Using Gstreamer to display audio-less video while recording audio+video 【发布时间】:2013-04-16 13:03:37 【问题描述】:

我的 Logitech C920 网络摄像头提供以 h264 编码的视频流。我正在使用this "capture" tool 访问数据:

这样我就可以观看实时视频了:

/usr/local/bin/capture -d /dev/video0 -c 100000 -o | \
  gst-launch-1.0 -e filesrc location=/dev/fd/0 \
                    ! h264parse \
                    ! decodebin\
                    ! xvimagesink sync=false

...或将流记录为原始 h264 文件:

/usr/local/bin/capture -d /dev/video0 -c 100000 -o | \
  gst-launch-0.10 -e filesrc location=/dev/fd/0 \
                     ! h264parse \
                     ! mp4mux \
                     ! filesink location=/tmp/video.mp4

...但我一生都无法弄清楚如何同时做这两个。录制时在屏幕上实时显示有时很有用,所以我想完成这项工作。 花了几个小时寻找一种同时抓取和筛选的方法,但没有运气。与tees 和queues 混在一起是无济于事的。

猜想将 ALSA 音频 (hw:2,0) 加入其中也是一种奖励,但我可以用一种丑陋的 hacky 方式解决这个问题。现在,即使 hw:2,0 是 Audacitu 或 arecord 中的有效输入,我也得到了这个,例如:

Recording open error on device 'hw:2,0': No such file or directory
Recording open error on device 'plughw:2,0': No such file or directory

所以回顾一下:很想把这两个视频片段放在一起,如果音频也能工作的话。我觉得自己像个新手。

提前感谢您提供的任何帮助。

编辑:非工作代码:

/usr/local/bin/capture -d /dev/video1 -c 100000 -o | \
     gst-launch-1.0 -e filesrc location=/dev/fd/0 ! tee name=myvid ! h264parse ! decodebin \
     ! xvimagesink sync=false myvid. ! queue ! mux. alsasrc device=plughw:2,0 ! \
     audio/x-raw,rate=44100,channels=1,depth=24 ! audioconvert ! queue ! mux. mp4mux \
     name=mux ! filesink location=/tmp/out.mp4 

...导致这个:

WARNING: erroneous pipeline: could not link queue1 to mux 

编辑:尝试了 umlaeute 的建议,得到了一个几乎空的视频文件和一个冻结的实时视频帧。修复启用音频的代码中的两个小错误(双引号拼写错误,未将音频编码为与 MP4 兼容的任何内容。在audioconvert 之后添加avenc_aac 做到了这一点)后,有/无音频没有区别。错误输出:

Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstAudiosrcClock
Redistribute latency...
ERROR: from element /GstPipeline:pipeline0/GstMP4Mux:mux: Could not multiplex stream.
Additional debug info:
gstqtmux.c(2530): gst_qt_mux_add_buffer (): /GstPipeline:pipeline0/GstMP4Mux:mux:
DTS method failed to re-order timestamps.
EOS on shutdown enabled -- waiting for EOS after Error
Waiting for EOS...
ERROR: from element /GstPipeline:pipeline0/GstFileSrc:filesrc0: Internal data flow error.
Additional debug info:
gstbasesrc.c(2809): gst_base_src_loop (): /GstPipeline:pipeline0/GstFileSrc:filesrc0:
streaming task paused, reason error (-5)

编辑: 好的,umlaeute 的更正代码可以完美运行,但前提是我使用的是 v4l2src 而不是转换工具。现在,这意味着抓取 MJPEG 流而不是 H264 流。我的鼻子没有皮肤,虽然我想我更喜欢更现代的工作流程。所以无论如何,这就是实际工作的方法,输出一个 MJPEG 视频文件和一个实时“取景器”。不是很优雅,但很实用。感谢您的所有帮助!

gst-launch-1.0 -e v4l2src device=/dev/video1 ! videorate ! 'image/jpeg, width=1280, height=720, framerate=24/1' ! tee name=myvid \    
      ! queue ! decodebin ! xvimagesink sync=false \     
      myvid. ! queue ! mux.video_0 \    
      alsasrc device="plughw:2,0" ! "audio/x-raw,rate=44100,channels=1,depth=24" ! audioconvert ! lamemp3enc ! queue ! mux.audio_0 \    
      avimux name=mux ! filesink location=/tmp/out.avi

【问题讨论】:

tee 应该可以正常工作,请发布不工作的管道 对,这两个部分中的每一个都可以单独工作。我不能做的是让他们一起工作。上面添加了非工作示例(我的最佳镜头)。 出于好奇,你为什么不用v4l2src来代替抓包工具呢? 好问题。这是因为我得到了相机,去寻找可以处理它的 Linux 软件,并在了解 gstreamer 之前找到了捕获的东西。而且我仍然不知道如何在没有该工具的情况下从 gstreamer 中的 cam 中获取 h264 编码的数据。这里是 gstreamer 的新手,边走边学。 另外,最近在 *** 上的帖子表明“捕获”仍然是要走的路:***.com/questions/15787967/… 【参考方案1】:

在自动组合多个不同的流时(例如使用mp4mux),gstreamer 通常有点愚蠢。 在这种情况下,您通常不仅应该将流发送到命名元素,还应该发送到特定的 pad(使用 elementname.padname 表示法;element. 表示法实际上只是命名元素中“任何”pad 的简写)。

另外,您似乎忘记了 mp4muxer 的 h264parse(如果您查看视频所采用的路径,它真的归结为 filesrc ! queue ! mp4mux,这可能有点粗糙)。

虽然我无法测试管道,但我想像下面这样的东西应该可以解决问题:

 /usr/local/bin/capture -d /dev/video1 -c 100000 -o | \
   gst-launch-1.0 -e filesrc location=/dev/fd/0 ! h264parse ! tee name=myvid \
     ! queue ! decodebin ! xvimagesink sync=false  \
     myvid. ! queue  ! mp4mux ! filesink location=/tmp/out.mp4

对于音频,它可能更复杂,尝试这样的事情(显然假设您可以使用alsasrc device="plughw:2,0" 元素读取音频)

 /usr/local/bin/capture -d /dev/video1 -c 100000 -o | \
   gst-launch-1.0 -e filesrc location=/dev/fd/0 ! h264parse ! tee name=myvid \
     ! queue ! decodebin ! xvimagesink sync=false  \
     myvid. ! queue ! mux.video_0 \
     alsasrc device="plughw:2,0" ! "audio/x-raw,rate=44100,channels=1,depth=24"" ! audioconvert ! queue ! mux.audio_0 \
     mp4mux name=mux ! filesink location=/tmp/out.mp4

【讨论】:

非常有前途,感谢您的建议。它还没有完全奏效,但也许隧道尽头有光。新代码仍然出错,生成一个 48 字节的文件,其中包含基本的 mp4 标头和一帧实时视频。在上面的最后一次编辑中添加了相关的错误输出。

以上是关于使用Gstreamer在录制音频+视频的同时显示无音频视频的主要内容,如果未能解决你的问题,请参考以下文章

Gstreamer 录制带音频的视频

sh 简单的gstreamer管道,用于将从网络摄像头捕获的视频录制到OGG,同时在屏幕上显示视频。

使用 gstreamer 在 android 上录制音频(使用 Qt5)

GTK3.0中如何使用gstreamer同时播放视频和音频

如何使用 GStreamer 以编程方式创建视频(来自 RGB 和 PCM)?

同时录制视频和播放音频文件