Du bist nicht eingeloggt! Möglicherweise kannst du deswegen nicht alles sehen.
  (Noch kein mods.de-Account? / Passwort vergessen?)
Zur Übersichtsseite
Hallo anonymer User.
Bitte logge dich ein
oder registriere dich!
 Moderiert von: hitmiccs


 Thema: Aufnehmen und Encoden unter Linux ( ffmpeg, x264 & co )
erste ungelesene Seite | letzter Beitrag 
a1ex

a1ex_small2
ffmpeg, x264 & co
Mit dem Einzug von Steam für Linux und der aktuellen Welle an Spielen die tatsächlich ohne Kopfzerbrechen nativ laufen wollte ich unbedingt meine LP Aufnahme auch auf Linux verlegen. Bei dem Thema kann man sich direkt auch mit Encoden und Streamen beschäftigen.

In allen Fällen gibt es mehr als einen Weg das zu bewerkstelligen und ich bezweifle, dass meine aktuellen gebastelten Skripte dafür der Weisheit letzter Schluss sind. Ich hoffe daher, dass ich nicht der Einzige bin den das interessiert und man sich hier in Sammelthreadform austauschen und mögliche Lösungen hervorheben kann.


  • Aufnehmen
    Probleme: durch X oder OpenGL? Welcher lossless Codec? Welche Software? Aufnahmeregionen/Fensterauswahl?

  • Encoden
    Probleme: Lösungen für Banner/Logos/Überleitungen ohne AVSkript. Geeignete Software, Bedienbarkeit.

  • Audio
    Nachbearbeiten mit ffmpeg oder sox. Alternativen? Typische Anwendungsfälle?
[Dieser Beitrag wurde 2 mal editiert; zum letzten Mal von a1ex am 15.09.2014 19:02]
15.09.2014 15:16:40  Zum letzten Beitrag
[ zitieren ] [ pm ] [ diesen post melden ]
Ratatoskr

Arctic
ffmpeg für alles
Also hier mal mein Shellskript, dass ich für die Aufnahme von Ascii-Spielen benutzt habe:
http://pastebin.com/x360NrZF
(benötigt xwininfo, device namen anpassen)

Einfach das Fenster anklicken, was aufgenommen werden soll. Der auskommentierte ffmpeg-Befehl nimmt nur das Mikro über alsa auf. Die Ascii-Spiele hatten keinen eigenen Ton. Das hat ganz gut funktioniert.

Der 2. ffmpeg-Befehl nimmt den Systemsound und das Mikro in separaten Spuren per pulseaudio auf. Meine Soundkarte hat kein mix device oder wie das heißt, deswegen geht das nicht rein über alsa (irgendwie mit virtuellen device reinconfen soll's doch gehen). Bei einer Aufnahme eines Amigaemulators (oder war's C64??) war das Video und der System/Spielsound leider leicht asynchron. Ka, warum.

Die 2 Audiospuren kann man dann mit folgenden Filtern zusammenführen:
 
Code:
[0:1] [0:2] amerge, pan=stereo:c0<a*c0+b*c2:c1<a*c1+b*c3 [audio]

a und b sind die jeweiligen Lautstärkeanpassungen.

Ein vollständiges Beispiel (cataclysm, ascii-roguelike):
http://pastebin.com/wF5sP9q1
Das Beispiel ist vllt. etwas verwirrend, da grab2.mkv nur eine Mikrophonspur hat. grab1.mkv hat erst Mikro, dann Systemsound.

Von -g würde ich inzwischen abraten, weil das Spulen damit verschlechtert wird. Nicht das hier irgendjemand skippen wöllte...

Für OpenGL-Spiele würde ich eher glc empfehlen:
https://wiki.archlinux.org/index.php/GLC
15.09.2014 17:45:19  Zum letzten Beitrag
[ zitieren ] [ pm ] [ diesen post melden ]
a1ex

a1ex_small2
... ffmpeg für alles #2
Das Encoden habe ich schon immer unter Linux erledigt. In der Regel hatte ich pro Letsplay ein Skript das ich angepasst und mehr oder weniger weitergeschleift habe. Der Weg war dabei ein dump des Rohstreams in x264 zu pipen, wobei die Skalierung und Umwandlung früher mencoder, dann ffmpeg und vielleicht noch irgendwas zwischendurch erledigt hat.

ffmpeg erschlägt einen anfangs ein wenig, allerdings kann es dafür auch richtig viel anstellen. Desktop grabben? Kein Problem mit x11grab. Stream nach twitch o.ä.? Einfach die URL als Output angeben. Bearbeiten? Es gibt Filterchains.

Meine aktuellen Skripte die ich für Journey Down erneuert habe finden sich auf github.
Der Versuch Einstellungen automatisch auf vernünftige Defaults zu setzen und etwas übersichtlicher Optionen für den Benutzer zusammenzufassen ist glaube ich noch sehr ausbaufähig. Aber was dort im Kern passiert möchte ich hier kurz erläutern.


Aufnehmen des Desktops und getrennter Tonspuren

FFmpeg besitzt die Option den X11 output abzugreifen. Vermutlich wäre ein OpenGL Grabber für das Spielefenster sinnvoller.
Zudem lassen sich mehrere Inputs in eine einzelne Datei mappen, was ich nutze um Audioinput auf getrennten Spuren zu halten. Anpassen von Stimme und Spielsound ist dann anschließend gut möglich. Ein zweites Mikro könnte ich von der Onboardkarte vermutlich zusätzlich getrennt capturen.

 
Code:
ffmpeg \
    -f x11grab -s ${res} -r ${fps} -i :0.0 \
    -f pulse -i ${device1} \
    -f pulse -i ${device2} \
    -c:v libx264 -qp 0 -preset ultrafast -map 0 \
    -c:a:0 pcm_s16le -map 1 \
    -c:a:1 pcm_s16le -map 2 \
    -y ${out}

-f
wählt als Eingangsformat den X Display Grabber für das Hauptdisplay
:0.0
. FFmpeg nimmt soweit ich weiß von sich aus 25 fps, wenn nichts gegeben ist, oder man setzt die Wiederholrate explizit durch
-r
.

Mein Audio geht durch den pulseaudio Server, für andere Fälle müsste man noch recherchieren. Die Audiogeräte spuckt einem ein
pactl list
aus, dort kann man dann gezielt den Output Monitor und Input Kanal für die gewünschte PCI Karte suchen. Bei mir zB
alsa_output.pci-0000_04_04.0.analog-stereo.monitor
. Ich vermute eigentlich dass man auch gezielt den Ton aus bestimmten Programmen über Pulse bekommen müsste, habe allerdings noch nicht danach geschaut.

Für den Lossless Encode nehme ich hier x264 mit konstantem, verlustfreien Quantisierer. Mein Test mit ffv1 wurde leider immer asynchron. Mehr hatte ich nicht probiert peinlich/erstaunt

Audio wird in leicht zu verarbeitendem Format gespeichert, der Trick ist eigentlich nur der
-map
Befehl, der die Spuren alle in die danach genannte Ausgabedatei verteilt. $out könnte hier zum Beispiel myrecording.mkv sein.

Sehr unschön an der Lösung ist, dass man offensichtlich zum Starten und Stoppen des Skripts das Konsolenfenster mitfilmt und die Sache nicht Hotkeytauglich ist. Diese paar Sekunden werden erst beim Encoden abgeschnitten.


Encoden mit Filterchain

Man kann ja nicht mit ansehen wie die ganzen AVSkript Nutzer sich schöne Effekte basteln und selbst nicht damit spielen können. Jedes Video in einem richtigen Editor anfassen ist auch keine schöne Variante.

Entsprechend habe ich mir so etwas mit ffmpeg Filtern gebaut:

 
Code:
ffmpeg \
    -i ./recording.mkv \
    -loop 1 -r 1 -i ./cfg/logo_mods.png \
    -filter_complex \

Die Bauchbinde bekommt ein Bild, welches wir zu einem Stream machen und als Input mit angeben.
Danach beginnt die Filterdefinition.

Das schöne an komplexen Filtern ist, dass jeder Eingang und Ausgang ordentlich benannt wird und entsprechend mehere möglich sind. "," reicht dabei direkt von einem an den anderen Filter weiter, wobei hier für Übersicht und mehere Kanäle Knoten ";" benutzt werden:
 
Code:
"[0:v] trim=4:56,setpts=expr='PTS-STARTPTS' [v]; 
[v] crop=1920:1080 [v]; 
[v] scale=-1:720:flags=spline [v]; 
[v] fade=in:start_time=4:duration=1,fade=out:start_time=53:duration=1 [v];

Wir nehmen also unsere Aufnahme und schneiden die oben bemängelten Sekunden ab. Dabei muss man die Timestamps korrigieren.
Schwarze Balken werden abgeschnitten und das Bild herunterskaliert.
Danach kommt ein Ein- und Ausblendeffekt von einer Sekunde über das Video.
Eigentlich reicht das.

 
Code:
[v] split [v][banner];
[1:v] trim=duration=9,scale=1.3*in_w:-1:flags=spline [logo];
[banner] drawbox=220:540:in_w-220:42:t=42:color=0x222e3abb [banner];
[banner][logo] overlay=40:480:shortest=1 [banner];
[banner] drawtext=font='Sans':fontsize=37:fontcolor=white:borderw=2:bordercolor=black:x=220:y=546:text='Jetzt mit Banner' [banner];
[v][banner] blend=all_expr='if(lte(T,6),B,A*(if(between(T,6,9),(T-6)/3,1))+B*(1-(if(between(T,6,9),(T-6)/3,1))))':repeatlast=0 [v];
[v] fps=25,format=yuv420p [v]" \

Der Spaß ist nun einen Banner mit Text zu malen. Den Zeilen nach:
Wir splitten den Stream in das Basisvideo und einen Stream zum Bemalen.
Der Logostream wird auf die nötige Zeit gekürzt und skaliert.
Die Box hinter dem Text wird gemalt.
Das Logo wird über die Box gelegt. Dieser Stream endet dabei mit dem gekürzten Logostream.
Der Text wird über beides gesetzt.

Damit haben wir einen Videostream mit Banner und den Originalen.
Ein Blendfilter übernimmt dann kontrolle über das Anzeigen und Ausblenden des kürzeren Videos mit Bauchbinde. Hier ist wieder wichtig den Filter zu beenden, da es ziemlich auf die Geschwindigkeit geht.
Am Ende wird noch das Richtige Format und die Ausgabefps gesetzt, hier egal, da wir vermutlich auch mit 25 aufgenommen haben.


 
Code:
-codec:v libx264 -crf 21 -preset veryslow \
-map [v] -f rawvideo -y ./video.264

Der Encode ist selbsterklärend,
-map
hilft wieder dem gewünschten Stream den Weg in die Ausgabedatei zu zeigen.

Ich habe mal grob gerundete Zahlenwerte eingesetzt um es etwas lesbarer zu machen.


Und was bringt das?

Spielerei. Ein Video lässt sich allerdings recht einfach encoden. Mit irgend einer bequemen Screencap Software hat man plötzlich einen wirklich komfortablen Prozess.

Ich denke ich werde hier die Idee von Ratatoskr verwenden und über xwinfo die Fensterauswahl erlauben. Nur beenden kann das auch noch nicht…

Getrennte Audiospuren sind allerdings großartig und erlauben das Editieren in Audacity. In meinem Skript muss man sich entweder selbst überlegen was man mit den Spuren anstellt, oder sie werden mit amix zusammen durch faac gejagt als hätte man sie zusammen aufgenommen. faac ist allerdings sowieso Mist, das ist eher so zum Testen da drin. Ich bin mir allerdings nicht sicher ob der Aufruf dazu überhaupt stimmt momentan.


edit1
hat Ratatoskr auch gut gemacht, libfdk_aac kann man nehmen sofern es einkompiliert wurde, sonst besser den neroAacEnc extern.


edit2
tatsächlich hat der Code hier einen extremen Memory Leak durch die Filter. Hinter einem neuen Knoten weiter auf einen beendeten Stream malen scheint nicht gut zu gehen.
[Dieser Beitrag wurde 4 mal editiert; zum letzten Mal von a1ex am 15.09.2014 23:51]
15.09.2014 18:39:18  Zum letzten Beitrag
[ zitieren ] [ pm ] [ diesen post melden ]
Ratatoskr

Arctic
Aha, du behandelst die Soundspuren extern. Das wollte ich auch machen. Um zum Beispiel das Rauschen des Mikros mit sox zu unterdrücken. Leider wurde das dann asynchron. Ich weiß bis heute nicht warum. Deswegen habe ich den encode mit einen Rutsch durchgezogen. Muss ich nochmal probieren. neroAac soll ja auch noch etwas besser sein.

Das mit dem Banner sieht auch sehr interessant aus. Mir war das zu umständlich.

Wie ich sehe, hast du ja fast alles durchgeskriptet. Wahrscheinlich auch sehr sinnvoll, wenn man mehr als 3 Videos erstellt. Muss ich alles mal genauer ansehen.

Ich habe kurzzeitig mit mlt[1] rumgespielt. Das wird auch von kdenlive[2] und anderen Videoeditoren verwendet. Ich hatte es mir hauptsächlich wegen den Transitionen angesehen. Das kann soweit ich weiß kein filter in ffmpeg: Übergangseffekte von einem Video in ein anderes. Das geht bei mlt sehr einfach.

Ich hatte bloß immer das Problem, dass er das Bild irgendwie skaliert hat. Was bei reinen Textspielen zu unschönen Verwaschungen führt.

[1] http://www.mltframework.org/
[2] http://www.kdenlive.org/
15.09.2014 21:25:11  Zum letzten Beitrag
[ zitieren ] [ pm ] [ diesen post melden ]
a1ex

a1ex_small2
Ein simples Überblenden zwischen zwei Videos mache ich dort oben ja. Man muss das nur etwas vorsichtig handhaben, damit der Blend Filter garantiert nur einen Stream durchreicht solange er nicht gebraucht wird.

Ich mache extern mit sox ein Kompressor auf die Stimme und passe danach die Lautstärke der Spuren zueinander an, ja. Asynchron wurde da nie was.

Die Videoeditoren sehen gut aus, sowas wird natürlich sinnvoll wenn man mehr Produktionsaufwand in ein Video steckt, ich versuche das eigentlich gering zu halten.
15.09.2014 22:35:02  Zum letzten Beitrag
[ zitieren ] [ pm ] [ diesen post melden ]
Ratatoskr

Arctic
Das Problem bei dem blend-Filter:
 

Output terminates when shortest input terminates



Ich möchte aber 2 Videos aneinander hängen und einen Übergangseffekt. Das geht meines Wissens nur, indem man Ende und Anfang abschneidet, den Effekt auf die Schnippsel anwendet, und dann alle 3 Teile (1.Video, Übergang, 2.Video) konkateniert.

Was bringt denn der Kompressor auf der Kommentarspur? Nervig hohe Töne ausblenden?
16.09.2014 0:11:32  Zum letzten Beitrag
[ zitieren ] [ pm ] [ diesen post melden ]
a1ex

a1ex_small2
Ich meine der Default ist den letzten Frame des kürzeren Videos zu wiederholen. Aber ich kann den Fall auch mal "übersichtlich" einzeln nachstellen.

Den Kompressor habe ich so einstellt dass er das Grundrauschen möglichst leiser macht oder garnicht durchlässt, während die Stimme selbst schlicht brutal gequetscht wird. Damit ist es egal wie laut ich ins Mikrofon spreche oder huste, am Ende ist alles ziemlich identisch peinlich/erstaunt
16.09.2014 0:27:35  Zum letzten Beitrag
[ zitieren ] [ pm ] [ diesen post melden ]
 Thema: Aufnehmen und Encoden unter Linux ( ffmpeg, x264 & co )


mods.de - Forum » Let's play im pOT » 

Hop to:  

Thread-Tags:
| tech | impressum