FFmpeg Basics

Bei FFmpeg handelt es sich um eine mächtige Sammlung an freien Computerprogrammen und Programmbibliotheken, die digitales Video- und Audiomaterial aufnehmen, konvertieren, senden, filtern und in verschiedene Containerformate verpacken können. FFmpeg wird zu meist über die Kommandozeile bedient, es bestehen aber auch unterschiedliche grafische Oberflächen für die unterschiedlichsten Einsatzzwecken. Zum Beispiel Videoschnitt Programme, welche auf FFmpeg aufbauen oder Programme um Videos von zum Beispiel DVDs herunter zu bekommen. Auf dieser Seite beschäftigen wir uns mit dem streamen eines Desktops mithilfe FFmpeg auf der Kommandozeile. 
 
 Download und Installation 
 FFmpeg steht für verschiedene Betriebssystemen zur Verfügung und kann von der offiziellen Seite, sowie aus den Paketquellen des jeweiligen Paketmanagers heruntergeladen werden. 
 Windows 
 
 Installer herunterladen und ausführen: FFmpeg : https://ffmpeg.org/download.html#build-windows GitHub Source : https://github.com/obsproject/obs-studio/releases 
 Aus dem Quellcode kompilieren Dokumentation: https://trac.ffmpeg.org/wiki/CompilationGuide 
 
 macOS 
 
 Installer herunterladen und ausführen: FFmpeg : https://ffmpeg.org/download.html#build-mac GitHub Source : https://github.com/obsproject/obs-studio/releases 
 Aus dem Quellcode kompilieren Dokumentation: https://trac.ffmpeg.org/wiki/CompilationGuide Mittels brew installieren: 
 brew install ffmpeg 
 
 macOS 
 
 Installer herunterladen und ausführen: FFmpeg : https://ffmpeg.org/download.html#build-mac GitHub Source : https://github.com/obsproject/obs-studio/releases 
 Aus dem Quellcode kompilieren Dokumentation: https://trac.ffmpeg.org/wiki/CompilationGuide Mittels brew installieren: 
 brew install ffmpeg 
 
 GNU/Linux 
 
 details 
 Die Installation für Linux kann auf verschiedenen Wegen erfolgen. 
 Ubuntu :  
 
 sudo apt update
sudo apt install ffmpeg 
 
 Arch Linux und Manjaro: 
 
 details 
 sudo pacman -S ffmpeg 
 Im AUR befinden sich verschiedene PKBUILDs um FFmpeg in unterschiedlichen Ausführungen zu bauen: 
 
 ffmpeg-full 
 
 Die aktuelle stabile Version von FFmpeg wird komplett aus dem Quellcode gebaut. 
 
 
 ffmpeg-full-git 
 
 Der aktuelle Release Canidate von FFmpeg wird komplett aus dem Quellcode gebaut. 
 
 
 ffmpeg-amd-full 
 
 FFmpeg wird in der aktuellsten stabilen Version für AMD Hardware gebaut. 
 
 
 ffmpeg-amd-full-git 
 
 Der aktuelle Release Canidate von FFmpeg wird für AMD Hardware gebaut. 
 
 
 ffmpeg-cuda 
 
 FFmpeg wird in der aktuellen stabilen Version mit CUDA (Nvidia) Unterstützung gebaut. 
 
 
 
 
 Debian: 
 
 details 
 sudo apt update
sudo apt install ffmpeg 
 
 Fedora: 
 
 details 
 sudo dnf -y install ffmpeg 
 
 Gentoo: 
 
 details 
 emerge --ask media-video/ffmpeg 
 
 NixOS: 
 
 details 
 https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/libraries/ffmpeg-full/default.nix 
 
 OpenMandriva Lx4 
 
 details 
 dnf install ffmpeg 
 
 Solus 
 
 details 
 eopkg install ffmpeg 
 
 Void 
 
 details 
 sudo xbps-install ffmpeg 
 
 Einführung 
 Es bestehen unterschiedliche Möglichkeiten mittels FFmpeg zu streamen. Der Einsatzzweck kann hierbei sehr unterschiedlich sein. Zum Beispiel soll ein bestehender RTMP Stream abgegriffen und umgeleitet werden, oder es befinden sich Videos auf einem Server, welche gestreamt werden sollen, damit der eigene PC nicht dauerhaft laufen muss. 
 Für diesen Wikiartikel wurde FFmpeg in Version n5.0.1 unter Arch Linux verwendet. Die Syntax, Optionen oder Argumente können je nach Version und Betriebssystem abweichen. 
 Als Beispiel Zielserver wird eine eigene Owncast Instanz gewählt. 
 Lokales Video streamen 
 Um mit FFmpeg ein lokales Video an ein Zielserver zu streamen muss an FFmpeg die Quelle mittels -i angegeben werden, sowie das Ziel zum Schluss angehangen werden. Dazwischen können Optionen gesetzt werden. Zum Beispiel, ob das Video vor dem streamen konvertiert werden soll. 
 ffmpeg -re -i inputfile.mp4 -c:v copy -c:a copy -f flv rtmp://127.0.0.1:1935/live/<streamkey> 
 Mit dem Befehl von oben liest ffmpeg die datei inputfile.mp4 ein und sendet das Video als flv zum Zielserver, welcher via RTMP auf Port 1935 erreichbar ist. Folgende Optionen wurden an FFmpeg mit angeheftet: 
 -re Der Input wird mit nativer Bildwiederholungsrate eingelesen. -i Mittels dieser Option wird der Pfad zur Datei gesetzt. 
 Wichtig. Der Dateiname darf keine Leerzeichen haben. FFmpeg hat hiermit Probleme, auch wenn man diese escaped. 
 -c:v copy Gibt an, dass der Video Codec beibehalten werden soll und FFmpeg nichts en/decodieren muss. -a:v copy Wie beim Video Codec wird auch der Audio Codec beibehalten. -f flv Mit dieser Option wird das Format FLV erzwungen, welches zwingend beim RTMP Streams ist. 
 
 Die Optionen -c:v copy und  -a:v copy sind wichtig zu setzen, sollte der jeweilige Computer langsamer en/decodieren, als mit 1x Geschwindigkeit. Im Fall einer langsamen berechnung des Videos, wird FFmpeg den Stream abbrechen, da das Video langsamer berechnet wird als FFmpeg senden kann und somit Frames erwartet, welche FFmpeg noch nicht kennt. Es kommt zu einem Broken Pipe und connection reset by peer . 
 Weitere Optionen 
 Sollte eine Grafikkarte vorhanden sein, mit welcher ein reencoding schnell genug durchgeführt werden kann, kann das Video während des streamens entsprechend auf Größe und Format gebracht werden. Dies ist besonders interessant, falls man das Video nicht im Vorfeld skaliert hat und die Bandbreite im Upload begrenzt ist. 
 -video_size 1280x720 Gibt die Ausgabeauflösung an -c:v libx264 mit der Option wird der H264 Codec benutzt -preset veryfast Das vorgefertigte Profil für eine schnelle Berechnung, anstelle von Qualität wird benutzt -b:v 3000k Die Bitrate des Videos wird auf 3000 KB/s eingestellt -maxrate 3000k Die maximale Bitrate des Videos entspricht 3000 KB/s -bufsize 6000k Die Buffer größe muss das doppelte der maximalen Bitrate entsprechen. -g 60 Die g Option stellt die Group Of Picture länge an. Hohe werte verursachen eine größere Kompression. -c:a aac Als Audio Ausgabe Codec soll aac benutzt werden -b:a 128k Dies stellt ein mit welcher Bitrate das Audio im Video gesendet werden soll. 192KB/s entsprich CD Qualität -ar 44100 Dies stellt die Samplerate Hz ein. 
 Streamen von Webcam und Mikrofon (Linux) 
 Falls eine USB Webcam gestreamt werden muss die Audioquelle, sowie die Video-Hardware angegeben werden. Um die Audio Hardware zu bestimmen, nutzen wir $ aplay --list-devices und listen jegliche Hardware auf. 
 $ aplay -l
**** Liste der Hardware-Geräte (PLAYBACK) ****
Karte 0: PCH [HDA Intel PCH], Gerät 0: ALC892 Analog [ALC892 Analog]
 Sub-Geräte: 0/1
 Sub-Gerät #0: subdevice #0
Karte 1: NVidia [HDA NVidia], Gerät 3: HDMI 0 [HDMI 0]
 Sub-Geräte: 1/1
 Sub-Gerät #0: subdevice #0
Karte 1: NVidia [HDA NVidia], Gerät 7: HDMI 1 [HDMI 1]
 Sub-Geräte: 1/1
 Sub-Gerät #0: subdevice #0
Karte 1: NVidia [HDA NVidia], Gerät 8: HDMI 2 [HDMI 2]
 Sub-Geräte: 1/1
 Sub-Gerät #0: subdevice #0
Karte 1: NVidia [HDA NVidia], Gerät 9: HDMI 3 [HDMI 3]
 Sub-Geräte: 1/1
 Sub-Gerät #0: subdevice #0
Karte 1: NVidia [HDA NVidia], Gerät 10: HDMI 4 [HDMI 4]
 Sub-Geräte: 1/1
 Sub-Gerät #0: subdevice #0
Karte 1: NVidia [HDA NVidia], Gerät 11: HDMI 5 [HDMI 5]
 Sub-Geräte: 1/1
 Sub-Gerät #0: subdevice #0
Karte 1: NVidia [HDA NVidia], Gerät 12: HDMI 6 [HDMI 6]
 Sub-Geräte: 1/1
 Sub-Gerät #0: subdevice #0
Karte 2: Creative [HDA Creative], Gerät 0: ALC898 Analog [ALC898 Analog]
 Sub-Geräte: 0/1
 Sub-Gerät #0: subdevice #0
Karte 3: Device [USB Advanced Audio Device], Gerät 0: USB Audio [USB Audio]
 Sub-Geräte: 0/1
 Sub-Gerät #0: subdevice #0 
 In der Ausgabe können wir sehen, welche Audio-Hardware vom Betriebssystem erkannt wurde und zur Verfügung steht. Nun müssen wir die passende Karte und Subdevice wählen. In diesem Beispiel will ich die Karte 3, das USB Mikrofon benutzen. Sprich, meine Hardware ist die 3,0 . 
 Alternative Möglichkeiten die Hardware zu definieren kann hier nachgelesen werden: https://en.wikibooks.org/wiki/Configuring_Sound_on_Linux/HW_Address 
 Nun muss ich die Video-Hardware Bestimmen, welche genutzt werden soll. Diese befindet sich unter /dev/video* . Diese wird als Input mit -i definiert. In meinen Fall ist es die Webcam unter dem Pfad /dev/video2 . Nun muss zusätzlich das Input Format, sowie das ausgehende Videoformat gewählt werden. Der Input wird mit -input_format yuyv422 eingestellt. Dieses Format kommt von der Webcam und sollte für den ausgehenden Stream in yuv420p mit -vf "format=yuv420p" umgewandelt werden. Mit der Kombination aus den vorherigen Befehlen und zusätzlichen Optionen sieht der gesamte Befehl wie folgt aus: 
 ffmpeg -f alsa -ac 2 -i hw:3,0 \
 -f v4l2 -framerate 60 -video_size 1280x720 -input_format yuyv422 -i /dev/video2 \
 -c:v libx264 -preset veryfast -b:v 1984k -maxrate 1984k -bufsize 3968k \
 -vf "format=yuv420p" -g 60 -c:a aac -b:a 128k -ar 44100 \
 -f flv rtmp://127.0.0.1:1935/live/<streamkey>