Командная строка ffmpeg для записи (и записи) аудио и видео в 720p с карты decklink с использованием Windows 7

Я пытаюсь захватить аудио и видео с карты захвата черной магии с помощью Windows 7 @720p, но я не могу правильно настроить параметры командной строки ffmpeg.

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

Это информация о потоке для текущего источника видео/аудио, подключенного к порту hdmi карты decklink

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

В конечном итоге мне нужно будет отобразить это видео на экране. И одновременно сможете запускать и останавливать запись, пока просмотр продолжает играть.

Моя идея состояла в том, чтобы использовать ffmpeg для захвата видео и аудиосигнала и передать его сетевому потоку (например, 127.0.0.1:6666). Затем используйте VLC-плеер для отображения потока (предварительный просмотр). И в конечном итоге запустите и/или остановите другой ffmpeg, чтобы сохранить тот же поток на диск.

В моем сознании это работает, но я не эксперт по аудио/видео, поэтому, если кто-нибудь с большим опытом может помочь, я был бы признателен.

Update:

Мне удалось отобразить видео с помощью ffplay со следующей командой:

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

Следующий шаг - это потоковая передача, чтобы я мог просматривать поток (предварительный просмотр) с помощью VLC.

Пытался использовать эту команду:

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

Что не дает никаких ошибок, так, похоже, работает. Но когда я пытаюсь открыть поток в VLC, я получаю следующую ошибку:

Требуется SDP: Для получения потока RTP требуется описание в формате SDP. Обратите внимание, что rtp://URI не могут работать с динамическим форматом полезной нагрузки RTP (65).

После небольшого чтения кажется, что я не должен передавать потоки в rtp://, а скорее в udp://

Команда

:

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

И когда я пытаюсь открыть его сейчас в VLC, я не получаю никаких ошибок, никаких предупреждений, но также и видео.

Время для чтения.

Ответ 1

Наконец, он работал. Моя настройка работает на одной машине.

Для получения видео и подачи его через UDP я использую следующую команду:

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"
  • -f dshow сообщает ffmpeg, что нам нужно использовать direct show.
  • -video_size 1280x720 устанавливает размер источника, так как я использую источник 720p60, это он.
  • 702000k действительно важно, так как без него буфер реального времени будет заполнен в считанные секунды.
  • -framerate 60 сообщает ffmpeg, что источник использует 60 кадров в секунду.
  • Опция: video="Decklink Video Capture":audio="Decklink Audio Capture" сообщает ffmpeg использовать это устройство в качестве ввода, но, указав их таким образом, отставание между аудио и видео будет значительно меньше (и/или ушло).
  • -r 30 заставляет вывод быть 30fps вместо 60fps в источнике.
  • -threads 4 делает то, что вы думаете, использует 4 потока.
  • -vcodec libx264 кодирует исходный поток в h264 во время трансляции.
  • -crf 0 устанавливает "коэффициент постоянной скорости" (шкала квантователя) равным 0, что означает отсутствие потерь.
  • -preset ultrafast означает, что у нас нет никакого терпения, поэтому используйте как можно меньше сжатия. Это вызывает высокий битрейт, но это прекрасно для моих целей.
  • -f mpegts указывает, что ffmpeg использует пакеты MPEG-TS, это заставит ffmpeg использовать формат mpeg с постоянным битрейтом, так как сам mpeg обычно является переменным битрейтом.
  • Наконец, опция udp://239.255.12.42:6666 указывает, что мы хотим транслировать этот поток на многоадресный адрес 239.255.12.42, используя порт 6666 через udp. Причина, по которой я решил использовать многоадресный адрес здесь, - это просто потому, что мне нужно отображать поток (предварительный просмотр) и записывать одновременно с минимальной обработкой. Это не позволяет мне копировать аудио- и видеопоток на два разных сетевых адреса.

Для захвата этого видео с помощью проигрывателя VLC я открываю следующий сетевой потоковый адрес:

udp://@239.255.12.42:6666

Наконец, для записи потока я создаю новый процесс и выдаю следующую команду:

ffmpeg -y -threads 4 -i udp://239.255.12.42:6666 -map 0 -acodec copy -vcodec copy output.mkv
  • Параметр -y предназначен для перезаписи файла, если он существует без вопросов.
  • Опция -threads 4 делает то, что вы думаете, она использует 4 потока.
  • -i udp://239.255.12.42:6666 подключается к потоку, который мы передаем.
  • -map 0 сообщает ffmpeg, что нам нужны все потоки (как видео, так и аудио).
  • -acodec copy и -vcodec copy существуют, чтобы гарантировать, что потоки берутся как есть, вместо того, чтобы делать какое-либо сжатие/транскодирование.

Единственное, что осталось сделать (это работа, выполняемая atm), - создать для этого С# gui. Основной рабочий процесс будет состоять в том, чтобы вызвать процесс потока, когда загружается форма. Используйте vlc com + control для отображения видео в приложении.

Затем, когда кнопка записи нажата, введите другой процесс для записи и остановите этот процесс, чтобы завершить запись.

Тем не менее, я останавливаю поток, когда начинаю запись, что делает запись/обнаружение более плавным. Если поток остается включенным и я начинаю запись, потребуется некоторое время, прежде чем процесс записи "настроится" на поток. Остановив поток, начиная запись (которая ничего не сделает до тех пор, пока поток не вернется) и не начнет поток снова, запись автоматически выйдет из первого кадра.

Эта небольшая задержка/мерцание полностью приемлема для моих целей.