Optimale Parameter für FFMPEG, um die Dateigröße zu erhalten

2395
Budius

Die Idee ist also: Ich möchte every.single.video in ein 1 Terabyte-Laufwerk umwandeln, in ein Format, das mein Chromecast abspielen kann ( https://developers.google.com/cast/docs/media ) und ich werde es tun Ich lasse meinen nicht so neuen PC gerne für ein paar Tage (Wochen?) arbeiten. Großartig, FFMPEG zur Erlösung.

Ein kleiner Hintergrund: Ich bin ein Android / Java-Entwickler (sehr aktiv im StackOverflow) und ich weiß, irgendwann muss ich nur ein Batch-Skript oder eine schnelle Java-Befehlszeile kodieren (weil ich mit Java etwas vertraut bin.) ), um den Job zu erledigen, aber ich bin mir immer noch nicht sicher, welche Argumente in meiner FFMPEG-Befehlszeile verwendet werden sollen.

Meine Bedürfnisse sind also: - Video-Codec: H.264 High Profile Level 5 - Audio-Codec: HE-AAC, LC-AAC, MP3 (ehrlich zu Gott, ich kenne den Unterschied nicht, vielleicht ist eine AAC besser? ) gleich bleiben - ich möchte auf jeden Fall die langsame oder langsamere (für bessere Qualität) verwenden - ich möchte auf jeden Fall den 2-Pass mit variabler Bitrate verwenden (für bessere Qualität)

All das habe ich in den Tutorials und Handbüchern gesehen, wie ich es erreichen kann, jetzt den Teil, den ich wirklich nicht sicher bin:

Ich möchte, dass die endgültige Dateigröße ungefähr der des Originals entspricht. Das liegt daran, dass das Laufwerk zu etwa 80% belegt ist und ich möchte es nicht durch einfaches Konvertieren auffüllen. Im Skript werde ich die Datei neu codieren und das Original löschen, damit alles ohne Probleme weiterläuft.

Wie komme ich also von filesize zu video_bitrate und audio_bitrate, um sie in das Skript einzufügen?

ps .: Ich bin gleichermaßen glücklich mit der Handbremse, wenn jemand weiß, wie er die gleiche Aufgabe erfüllt.

danke im voraus für die hilfe.

0

1 Antwort auf die Frage

2
stib

Der ffmpeg-Befehl, den Sie benötigen, sieht so aus:

ffmpeg -i input.foo -c:v libx264 -profile:v high -level 5 -preset slow -b:v $videobitrate -an -pass 1 output.bar; ffmpeg -y -i input.foo -c:v libx264 -profile:v high -level 5 -preset slow -b:v $videobitrate -b:a $audiobitrate -pass 2 output.bar 

libx264 ist der h264-Encoder, und alle Optionen werden von ffmpeg an ihn übergeben, sie sind ziemlich selbsterklärend. Der erste Durchlauf benötigt kein Audio, daher die -an. Sie können die Ausgabe an / dev / null weiterleiten, wenn Sie möchten. Ich verwende einfach die Option -y im zweiten Durchlauf, sodass die temporäre Datei ohne Rückfrage überschrieben wird. Der Audio-Codec ist standardmäßig aac, sodass Sie ihn nicht angeben müssen.

ffprobe kann Ihnen helfen, den Wert von $ videobitrate und $ audiobitrate zu erhalten (ich gehe von einer posix-Umgebung aus, andernfalls wird es% videobitrate% und% audiobitrate% sein). Sie müssen etwas sed, awk oder perl voodoo machen, um die Werte in eine Form zu bringen, die Sie verwenden können. Hier ist die Ausgabe von ffprobe auf einem zufälligen mp4 auf meinem Rechner:

ffprobe version 2.1.3 Copyright (c) 2007-2013 the FFmpeg developers built on Feb 12 2014 22:10:38 with Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn) configuration: --prefix=/usr/local/Cellar/ffmpeg/2.1.3 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-nonfree --enable-hardcoded-tables --enable-avresample --enable-vda --cc=clang --host-cflags= --host-ldflags= --enable-libx264 --enable-libfaac --enable-libmp3lame --enable-libxvid --enable-libfreetype --enable-libtheora --enable-libvorbis --enable-libvpx --enable-librtmp --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-aacenc --enable-libass --enable-ffplay --enable-libspeex --enable-libschroedinger --enable-libfdk-aac --enable-openssl --enable-libopus --enable-frei0r --enable-libcaca --enable-libopenjpeg --extra-cflags='-I/usr/local/Cellar/openjpeg/1.5.1/include/openjpeg-1.5 ' libavutil 52. 48.101 / 52. 48.101 libavcodec 55. 39.101 / 55. 39.101 libavformat 55. 19.104 / 55. 19.104 libavdevice 55. 5.100 / 55. 5.100 libavfilter 3. 90.100 / 3. 90.100 libavresample 1. 1. 0 / 1. 1. 0 libswscale 2. 5.101 / 2. 5.101 libswresample 0. 17.104 / 0. 17.104 libpostproc 52. 3.100 / 52. 3.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'loop.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf55.19.104 Duration: 00:00:19.56, start: 0.000000, bitrate: 201 kb/s Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 400x226 [SAR 226:225 DAR 16:9], 129 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default) Metadata: handler_name : VideoHandler Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 75 kb/s (default) Metadata: handler_name : SoundHandler 

ärgerlich speichert ffprobe alles auf stderr, also müssen sie es nach stdout umleiten. Ich werde dir nicht sagen, wie man Eier saugt, dein Sed-Fu ist vielleicht besser als meines, aber für die, die spät kamen, um die Bitrate für den ganzen Shebang im obigen Beispiel zu erhalten, könntest du Folgendes tun:

videobitrate=$(ffprobe input.foo 2>&1|grep bitrate |sed "s/.*bitrate: \([0-9]*\) \([km]*\).*/\1\2/") 

und für das audio:

audiobitrate=$(ffprobe input.foo 2>&1|grep Audio|sed "s/.* \([0-9]*\) \([km]*\)b\/s.*/\1\2/") 

Ich bin mir nicht sicher, warum die Bitrate des Audios angegeben wurde, nicht aber das Video. Dies liegt möglicherweise daran, dass ich normalerweise mit einem konstanten Ratenfaktor komprimiere (konstante Qualität statt konstanter Bitrate). Sie müssen die ffprobe-Ausgabe in Ihren Filmen überprüfen. Von da an liegt es an Ihnen, das in die Variablen umzuwandeln, die Sie brauchen. Beachten Sie, dass ffmpeg Zahlen wie 100k oder 3m analysiert.

Ich habe die gesamte Antwort nicht einmal gelesen und verarbeitet, aber ich habe sie nur aus Zeit- und Arbeitsaufwand bekräftigt, um eine vollständige Antwort zu erarbeiten. Ich werde dieses kleine Projekt an diesem oder nächsten Wochenende ausgraben und wir werden sehen, wie es läuft. Danke vielmals! Mit freundlichen Grüßen! Budius vor 10 Jahren 0
Ich habe ein paar Folgefragen: 1) Es ist also nur die ursprüngliche Bitrate zu kopieren, und das Material sollte am Ende die gleiche Größe haben? Ich habe ehrlich gesagt etwas komplexeres erwartet, froh zu wissen, dass es nicht so ist. 2) Wenn es so einfach ist, gibt es auf dem FFMPEG keine Option, die "same_bitrate" sagt? 3) Soll die Bitrate für den 1. Durchlauf nicht höher sein als der letzte Durchlauf? Danke noch einmal. Budius vor 10 Jahren 0
Nun, size = Bitrate x length, also haben sie die gleiche Dateigröße. Die Bitrate ist jedoch nicht das Hauptanliegen, sondern die Qualität. Der komplizierende Faktor ist, dass die Qualität von der Effizienz der Komprimierung sowie von der Art des Inhalts abhängt. Wenn die Originale mit einem weniger effizienten Codec codiert werden, z. B. bei MPEG2-Video in Standardauflösung (wie bei einer DVD), die mit etwa 5 MB / s codiert wird, ist der Speicherplatz für mit h264 codierte Kopien ähnlicher Qualität erforderlich viel kleiner; 1 MB / s könnte es tun. stib vor 10 Jahren 0
... Es gibt keinen einfachen Weg, dies zu beurteilen, ohne es zu testen, aber es gibt einen besseren Ansatz, nämlich mit konstanter Qualität zu kodieren, anstatt sich auf die Bitrate zu konzentrieren. Die konstante Qualitätseinstellung von ffmpeg libx264 wird mit -crf aufgerufen (steht für Constant Rate Factor, was immer dies bedeutet). Ein ganzzahliger Wert bestimmt die Qualität, beginnend bei 1 für nahezu verlustfrei und bis zu etwa 31 für Mist. Um mit einer DVD-ähnlichen Qualität zu codieren, verwenden Sie -crf 20. stib vor 10 Jahren 0
Oh, und nochmal: die Zwei-Pass-Sache. Zwei Durchgänge bedeuten im Wesentlichen, dass das Filmmaterial durchläuft, um zu ermitteln, wo sich die Teile befinden, die die höchste Bitrate benötigen, bevor die Kodierung durchgeführt wird. Die verfügbare Bitrate kann dann entsprechend aufgeteilt werden. Wenn Sie also eine statische Aufnahme mit wenig Action haben, werden weniger b / s als bei der Chase-Szene benötigt. Sie werden feststellen, dass eine Protokolldatei erstellt wird. Diese wird zur Bestimmung der Bitrate verwendet. stib vor 10 Jahren 0
Hallo. Danke für all die Tipps. Ja, am Ende gebe ich einfach jede Batch-Sache auf und mache einfach eine einfache Java-Benutzeroberfläche (ich werde wahrscheinlich irgendwann GitHub verwenden, ich bin mir sicher, dass mehr Leute daran interessiert sein werden). In Bezug auf die Sonde fand ich dies heraus http://stackoverflow.com/questions/7708373/get-ffmpeg-information-in-friendly-way, um es als nettes, einfach zu verwendendes JSON-Objekt zu verwenden. Das gibt mir sogar die Möglichkeit, den aktuellen Codec richtig zu überprüfen, um ihn nur bei Bedarf neu zu codieren. Budius vor 10 Jahren 0