web-dev-qa-db-fra.com

Ligne de commande ffmpeg pour capturer (et enregistrer) l'audio et la vidéo en 720p à partir d'une carte Decklink à l'aide de Windows 7

J'essaie de capturer de l'audio et de la vidéo à partir d'une carte de capture blackmagic decklink en utilisant Windows 7 @ 720p, mais je ne parviens pas à obtenir les bons paramètres de ligne de commande 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 = "Capture vidéo Decklink"

[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 = "Capture audio Decklink"

[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

Il s'agit des informations de flux pour ma source vidéo/audio actuelle, connectée au port HDMI de la carte 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

En fin de compte, je devrai afficher cette vidéo à l'écran. Et en même temps, vous pouvez démarrer et arrêter l'enregistrement, tandis que l'aperçu continue de jouer.

Mon idée était d'utiliser ffmpeg pour capturer le signal vidéo et audio et le transmettre à un flux réseau (par exemple 127.0.0.1:6666). Utilisez ensuite le lecteur VLC pour afficher le flux (l'aperçu). Et finalement, démarrez et/ou arrêtez un autre ffmpeg pour enregistrer ce même flux sur le disque.

Dans mon esprit, cela fonctionne, mais je ne suis pas un expert audio/vidéo, donc si quelqu'un avec plus d'expérience pouvait aider, je l'apprécierais.

Mise à jour:

J'ai pu afficher la vidéo en utilisant ffplay, avec la commande suivante:

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

La prochaine étape est de le diffuser afin que je puisse voir le flux (prévisualisation) avec VLC.

J'ai essayé d'utiliser cette commande:

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

Ce qui ne donne aucune erreur, semble donc fonctionner. Mais lorsque j'essaie d'ouvrir le flux dans VLC, j'obtiens l'erreur suivante:

SDP requis: une description au format SDP est requise pour recevoir le flux RTP. Notez que les URI rtp: // ne peuvent pas fonctionner avec le dynamique RTP format de charge utile (65 ).

Après un peu de lecture, il semble que je ne devrais pas diffuser en continu sur rtp: // mais plutôt sur udp: //

Le commandement est devenu:

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

Et quand j'essaye de l'ouvrir maintenant dans VLC, je ne reçois aucune erreur, aucun avertissement, mais aussi aucune vidéo.

Il est temps de lire davantage.

15
Huron

Je l'ai finalement fait fonctionner. Ma configuration fonctionne sur une seule machine.

Pour prendre la vidéo et la servir via UDP, j'utilise la commande suivante:

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"
  • Le -f dshow Indique à ffmpeg que nous devons utiliser le show direct.
  • -video_size 1280x720 Définit la taille de la source, puisque j'utilise une source 720p60, c'est tout.
  • 702000k Est vraiment important car sans lui le tampon en temps réel serait plein en quelques secondes.
  • -framerate 60 Indique à ffmpeg que la source utilise 60fps.
  • L'option: video="Decklink Video Capture":audio="Decklink Audio Capture" Indique à ffmpeg d'utiliser ces périphériques comme entrée, mais en les spécifiant de cette manière, le décalage entre l'audio et la vidéo sera sensiblement moindre (et/ou disparu).
  • -r 30 Force la sortie à 30fps au lieu de 60fps dans la source.
  • -threads 4 Fait ce que vous pensez, utilisez 4 fils.
  • -vcodec libx264 Code le flux source en h264 lors de la diffusion.
  • -crf 0 Définit le "facteur de taux constant" (échelle de quantification) à 0, ce qui signifie sans perte.
  • -preset ultrafast Signifie que nous n'avons aucune patience, utilisez donc le moins de compression possible. Cela provoque un débit binaire élevé, mais cela me convient parfaitement.
  • L'option -f mpegts Indique à ffmpeg d'utiliser des paquets MPEG-TS, cela "forcera" ffmpeg à utiliser un format mpeg à débit constant, car mpeg lui-même est normalement à débit variable.
  • Enfin, l'option udp://239.255.12.42:6666 Spécifie que nous voulons diffuser ce flux vers l'adresse de multidiffusion 239.255.12.42 en utilisant le port 6666 sur udp. La raison pour laquelle j'ai choisi d'utiliser une adresse de multidiffusion ici est simplement parce que je dois afficher le flux (prévisualisation) et enregistrer en même temps, avec le moins de traitement possible. Cela m'empêche d'avoir à copier le flux audio et vidéo vers deux adresses réseau différentes.

Pour capturer cette vidéo à l'aide du lecteur VLC, j'ouvre l'adresse de streaming réseau suivante:

udp://@239.255.12.42:6666

Enfin, pour l'enregistrement du flux, je lance un nouveau processus et émets la commande suivante:

ffmpeg -y -threads 4 -i udp://239.255.12.42:6666 -map 0 -acodec copy -vcodec copy output.mkv
  • L'option -y Sert à toujours écraser le fichier s'il existe sans poser de questions.
  • L'option -threads 4 Fait ce que vous pensez, elle utilise 4 threads.
  • Le -i udp://239.255.12.42:6666 Se connecte au flux que nous diffusons.
  • Le -map 0 Indique à ffmpeg que nous avons besoin de tous les flux (vidéo et audio).
  • -acodec copy Et -vcodec copy Sont là pour garantir que les flux sont pris tels quels, au lieu de faire une compression/transcodage.

La seule chose qui reste à faire (qui est un work in progress atm) est de créer un c # gui pour cela. Le workflow de base consistera à générer le processus de flux lors du chargement du formulaire. Utilisez le contrôle vlc com + pour afficher la vidéo dans l'application.

Ensuite, lorsque le bouton d'enregistrement est enfoncé, lancez un autre processus pour enregistrer et arrêtez ce processus pour terminer l'enregistrement.

Cependant, j'arrête le flux lorsque je commence à enregistrer, cela rend l'enregistrement/détection beaucoup plus fluide. Si le flux reste activé et que je commence à enregistrer, il faudra un certain temps avant que le processus d'enregistrement puisse "se brancher" sur le flux. En arrêtant le flux, en démarrant l'enregistrement (qui ne fera rien tant que le flux ne sera pas réactivé) et en redémarrant le flux, l'enregistrement reprendra sans problème à partir de la première image.

Ce petit retard/scintillement est totalement acceptable pour mes besoins.

31
Huron