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

3
我的Logitech C920网络摄像头提供了一个使用h264编码的视频流。我正在使用这个“捕获”工具访问数据:这里
因此,我可以观看实时视频:
/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

但我怎么也想不出如何同时做到这两点。有时,在录制时在屏幕上显示实时反馈可能会很有用,所以我希望能够实现这一点。

我花了好几个小时寻找一种同时抓取和屏幕录制的方法,但是没有成功。即使尝试了许多teequeue,也没有帮助。

如果能够将ALSA音频(hw:2,0)添加进来,那就更好了,但是我可以用一种丑陋的方式解决它。例如,在Audacity或者arecord中,hw:2,0是有效的输入:

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 

...leads to this:

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而非convert工具时才有效。目前,这意味着抓取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

1
tee 应该可以正常工作,请发布一个不起作用的管道。 - umläute
好的,这两部分中的每一部分都可以单独正常运行。我做不到的是让它们一起工作。上面添加了一个不起作用的示例(我最好的尝试)。 - Anders Bylund
出于好奇,为什么您不使用v4l2src而是使用捕获工具? - ensonic
很好的问题。这是因为我买了相机,寻找能够处理它的Linux软件,并在了解gstreamer之前找到了捕获工具。而且我仍然不知道如何在gstreamer中从摄像头中抓取h264编码数据而不使用该工具。我是一个完全的gstreamer新手,在学习的过程中逐步掌握。 - Anders Bylund
此外,stackoverflow 的最近帖子表明“capture”仍然是正确的选择:https://dev59.com/S2Uo5IYBdhLWcg3wvRtF - Anders Bylund
1个回答

0

在自动组合多个不同流(例如使用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

非常有前途,感谢您的建议。它还没有完全运行,但也许隧道尽头有光明。新代码仍然出现错误,生成一个带有基本mp4头和一帧实时视频的48字节文件。相关的错误输出已添加在上面的最后编辑中。 - Anders Bylund

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接