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

时间:2013-04-16 13:03:37

标签: audio video gstreamer video-recording

我的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

...但我不能为我的生活弄清楚如何同时做两件事。在录制时在屏幕上显示实时馈送有时很有用,所以我想做这个工作。 花了几个小时和几个小时寻找一种方法同时抓住和屏幕,但没有运气。 teequeue的任何麻烦都无济于事。

猜猜将ALSA音频(hw:2,0)加入其中也是一个奖励,但我可以用一种丑陋的黑客方式解决这个问题。现在,即使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兼容的任何内容。在avenc_aac之后添加audioconvert执行该操作)。错误输出:

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

1 个答案:

答案 0 :(得分:0)

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

另外,您似乎忘记了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