ffmpeg command line for capturing (and recording)

2019-03-07 21:18发布

问题:

I am trying to capture audio and video from a blackmagic decklink capture card using Windows 7 @ 720p, but I cant seem to get the ffmpeg command line settings right.

ffmpeg -list_devices true -f dshow -i dummy

[dshow @ 02457a60] DirectShow video devices
[dshow @ 02457a60]  "Blackmagic WDM Capture"
[dshow @ 02457a60]  "Decklink Video Capture"
[dshow @ 02457a60] DirectShow audio devices
[dshow @ 02457a60]  "Decklink Audio Capture"

ffmpeg -list_options true -f dshow -i video="Decklink Video Capture"

[dshow @ 03c2ea20] DirectShow video device options
[dshow @ 03c2ea20]  Pin "Capture"
[dshow @ 03c2ea20]   pixel_format=uyvy422  min s=720x486 fps=29.97 max s=720x486 fps=29.97
[dshow @ 03c2ea20]   pixel_format=uyvy422  min s=720x486 fps=23.976 max s=720x486 fps=23.976
[dshow @ 03c2ea20]   pixel_format=uyvy422  min s=720x576 fps=25 max s=720x576 fps=25
[dshow @ 03c2ea20]   pixel_format=uyvy422  min s=720x486 fps=59.9402 max s=720x486 fps=59.9402
[dshow @ 03c2ea20]   pixel_format=uyvy422  min s=720x576 fps=50 max s=720x576 fps=50
[dshow @ 03c2ea20]   pixel_format=uyvy422  min s=1920x1080 fps=23.976 max s=1920x1080 fps=23.976
[dshow @ 03c2ea20]   pixel_format=uyvy422  min s=1920x1080 fps=24 max s=1920x1080 fps=24
[dshow @ 03c2ea20]   pixel_format=uyvy422  min s=1920x1080 fps=25 max s=1920x1080 fps=25
[dshow @ 03c2ea20]   pixel_format=uyvy422  min s=1920x1080 fps=29.97 max s=1920x1080 fps=29.97
[dshow @ 03c2ea20]   pixel_format=uyvy422  min s=1920x1080 fps=30 max s=1920x1080 fps=30
[dshow @ 03c2ea20]   pixel_format=uyvy422  min s=1280x720 fps=50 max s=1280x720fps=50
[dshow @ 03c2ea20]   pixel_format=uyvy422  min s=1280x720 fps=59.9402 max s=1280x720 fps=59.9402
[dshow @ 03c2ea20]   pixel_format=uyvy422  min s=1280x720 fps=60.0002 max s=1280x720 fps=60.0002

ffmpeg -list_options true -f dshow -i audio="Decklink Audio Capture"

[dshow @ 047fea20] DirectShow audio device options
[dshow @ 047fea20]  Pin "Capture"
[dshow @ 047fea20]   min ch=1 bits=16 rate= 48000 max ch=1 bits=16 rate= 48000
[dshow @ 047fea20]   min ch=2 bits=16 rate= 48000 max ch=2 bits=16 rate= 48000
[dshow @ 047fea20]   min ch=4 bits=16 rate= 48000 max ch=4 bits=16 rate= 48000
[dshow @ 047fea20]   min ch=6 bits=16 rate= 48000 max ch=6 bits=16 rate= 48000
[dshow @ 047fea20]   min ch=8 bits=16 rate= 48000 max ch=8 bits=16 rate= 48000
[dshow @ 047fea20]   min ch=10 bits=16 rate= 48000 max ch=10 bits=16 rate= 48000
[dshow @ 047fea20]   min ch=12 bits=16 rate= 48000 max ch=12 bits=16 rate= 48000
[dshow @ 047fea20]   min ch=16 bits=16 rate= 48000 max ch=16 bits=16 rate= 48000

This is the stream information for my current video/audio source, connected to the decklink card's hdmi port

Stream #0:0: Video: rawvideo (UYVY / 0x59565955), uyvy422(tv), 1280x720, 59.94 tbr, 10000k tbn, 59.94 tbc
Stream #0:1: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s

Ultimately I will need to display this video on screen. And simultaneously be able to start and stop recording, while the preview keeps playing.

My idea was to use ffmpeg to capture the video and audio signal and transmit this to a network stream (eg 127.0.0.1:6666). Then use VLC player to display the stream (the preview). And ultimately start and/or stop another ffmpeg to save that same stream to disk.

In my mind this works, but I am no audio/video expert so if anyone with more experience could help out, I would appreciate it.

Update:

I have been able to display the video using ffplay, with the following command :

ffplay -f dshow -video_size 1280x720 -rtbufsize 702000k -framerate 60 -i video="Decklink Video Capture":audio="Decklink Audio Capture" -threads 2

Next step is streaming it so I can view the stream (preview) with VLC.

Tried to use this command :

ffmpeg -f dshow -video_size 1280x720 -rtbufsize 702000k -framerate 60 -i video="Decklink Video Capture":audio="Decklink Audio Capture" -threads 2 -f mpegts rtp://127.0.0.1:6666?pkt_size=188?buffer_size=65535

Which does not give any errors, so appears to work. But when I try to open the stream in VLC I get the following error :

SDP required: A description in SDP format is required to receive the RTP stream. Note that rtp:// URIs cannot work with dynamic RTP payload format (65).

After a bit of reading it seems I should not be streaming to rtp:// but rather to udp://

Command became :

ffmpeg -f dshow -video_size 1280x720 -rtbufsize 702000k -framerate 60 -i video="Decklink Video Capture":audio="Decklink Audio Capture" -threads 2 -f mpegts udp://127.0.0.1:6666?pkt_size=188?buffer_size=65535

And when I try to open it now in VLC I get no error, no warning, but also no video.

Time for some more reading.

回答1:

Finally got it working. My setup has this all running on a single machine.

For taking the video and serving it via UDP I use the following command :

ffmpeg -f dshow -video_size 1280x720 -rtbufsize 702000k -framerate 60 -i video="Decklink Video Capture":audio="Decklink Audio Capture" -r 30 -threads 4 -vcodec libx264 -crf 0 -preset ultrafast -f mpegts "udp://239.255.12.42:6666"
  • The -f dshow tells ffmpeg we need to use direct show.
  • -video_size 1280x720 sets the source size, since I am using a 720p60 source, this is it.
  • 702000k is really important since without it the realtime buffer would be full in a matter of seconds.
  • -framerate 60 tells ffmpeg the source is using 60fps.
  • The option: video="Decklink Video Capture":audio="Decklink Audio Capture" tells ffmpeg to use those device as input, but by specifying them in this fashion, the lag between audio and video will be substantially less (and/or gone).
  • -r 30 forces the output to be 30fps instead of the 60fps in source.
  • -threads 4 does what you think, use 4 threads.
  • -vcodec libx264 encodes the source stream to h264 while broadcasting.
  • -crf 0 sets the "constant rate factor" (quantizer scale) to 0, meaning lossless.
  • -preset ultrafast means we dont have any patience, so use as little compression as possible. This causes a high bitrate, but that's fine for my purpose.
  • -f mpegts option tells ffmpeg to use MPEG-TS packets, this will "force" ffmpeg to use a constant bitrate mpeg format, since mpeg itself is normally variable bitrate.
  • Finally the option udp://239.255.12.42:6666 specifies that we want to broadcast this stream to the multicast address 239.255.12.42 using port 6666 over udp. The reason I chose to use a multicast address here is simply because I need to display the stream (preview) and record at the same time, with as least processing as possible. This prevents me from having to copy the audio and video stream to two different network addresses.

For capturing this video using VLC player, I open the following network streaming address :

udp://@239.255.12.42:6666

Finally for recording the stream I spawn a new process and issue the following command :

ffmpeg -y -threads 4 -i udp://239.255.12.42:6666 -map 0 -acodec copy -vcodec copy output.mkv
  • The -y option is for always overwriting the file if it exists without questions.
  • The -threads 4 option does what you think, it uses 4 threads.
  • The -i udp://239.255.12.42:6666 connects to the stream we are broadcasting.
  • The -map 0 tells ffmpeg that we need all streams (both video and audio).
  • The -acodec copy and -vcodec copy are there to ensure that the streams are taken as is, instead of doing any compression/transcoding.

The only thing left to do (which is a work in progress atm) is creating a c# gui for this. Basic workflow will be to spawn the stream process when the form loads. Use the vlc com+ control to display the video in the application.

Then when the record button is pushed, spawn another process to record and stop that process to end the recording.

I do however stop the stream when I start to record, this makes the recording/detection go much more smoothly. If the stream stays on and I start recording it will take some time before the recording process can "tune in" to the stream. By stopping the stream, starting the recording (which will do nothing until the stream is back on) and starting the stream again, the recording will pickup from the first frame without any problems.

This small delay/flicker is totally acceptable for my purposes.