Wie kann man 4k auf 1080p mit ffmpeg heruntersampeln und dabei die Qualität beibehalten?

Ich habe einige 4K-Aufnahmen mit 3840 x 2160 im MP4-Format, die ich auf 1080p reduzieren muss. Ich versuchte es mit Laufen

ffmpeg -i orig.mp4 -vf scale=1920:1080 smaller.mp4  

Das Ergebnis ist jedoch von sehr schlechter Qualität, da das gesamte Bild aus quadratischen "Kacheln" besteht, als ob ich 4: 1 vergrößern würde.

Hier ist die Ausgabe der Ausführung dieses Befehls:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'origs/P1000003.MP4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp42avc1
    creation_time   : 2015-02-19 17:10:38
  Duration: 00:05:14.48, start: 0.000000, bitrate: 95903 kb/s
    Stream #0.0(und): Video: h264 (High), yuvj420p, 3840x2160 [PAR 1:1 DAR 16:9], 95792 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc
    Metadata:
      creation_time   : 2015-02-19 17:10:38
    Stream #0.1(und): Audio: aac, 48000 Hz, stereo, s16, 125 kb/s
    Metadata:
      creation_time   : 2015-02-19 17:10:38
Incompatible pixel format 'yuvj420p' for codec 'mpeg4', auto-selecting format 'yuv420p'
[buffer @ 0x22a3420] w:3840 h:2160 pixfmt:yuvj420p
[scale @ 0x22a3ce0] w:3840 h:2160 fmt:yuvj420p -> w:1920 h:1080 fmt:yuv420p flags:0x4
Output #0, mp4, to '1-short.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp42avc1
    creation_time   : 2015-02-19 17:10:38
    encoder         : Lavf53.21.1
    Stream #0.0(und): Video: mpeg4, yuv420p, 1920x1080 [PAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 25 tbn, 25 tbc
    Metadata:
      creation_time   : 2015-02-19 17:10:38
    Stream #0.1(und): Audio: libvo_aacenc, 48000 Hz, stereo, s16, 200 kb/s
    Metadata:
      creation_time   : 2015-02-19 17:10:38
Stream mapping:
  Stream #0.0 -> #0.0
  Stream #0.1 -> #0.1
Press ctrl-c to stop encoding
frame=  125 fps=  6 q=31.0 Lsize=     968kB time=5.00 bitrate=1586.7kbits/s    
video:842kB audio:123kB global headers:0kB muxing overhead 0.421047%

Ich weiß aus Erfahrung, dass ffmpeg ein hervorragendes Tool ist, also muss ich die Optionen/Parameter irgendwie vermasseln ...

Wie kann ich das machen?

Bitte zeigen Sie die vollständige Konsolenausgabe Ihres Befehls. Sie können einfach ein kurzes Segment codieren, also fügen Sie es hinzu -t 10, um eine 10-Sekunden-Ausgabe zu erzeugen. Warum willst du runterskalieren? Was ist der Anwendungsfall für Ihre skalierte Ausgabe? Diese Informationen helfen mir, eine genauere Antwort zu geben.
@LordNeckbeard Ich habe gerade die Konsolenausgabe hinzugefügt. Ich möchte herunterskalieren, damit ich diese Clips leichter mit Leuten teilen kann, die mit mir arbeiten.
Sieht so aus, als ob einige Sachen weggelassen wurden. Ich suche auch nach den Versionsinformationen und wie es konfiguriert wurde. Kannst du die ganze Ausgabe zeigen?
Ich werde trotzdem eine Antwort mit zusätzlichen Informationen geben, wenn die vollständige Konsolenausgabe bereitgestellt wird.
Vergessen Sie nicht -c:a copy, da Sie den Audiostream nicht neu codieren möchten oder müssen. Verwenden Sie -map 0diese Option, um Kapitelmetadaten oder andere Dinge zu kopieren. (ffmpeg nimmt standardmäßig nur 1 vid + 1 aud.)
Außerdem -sws_flags lanczos+print_infowird ein besserer Skalierungsalgorithmus als der Standard verwendet (bilinear, denke ich). Die Antwort von stlb deckt den Videocodierungsteil des Prozesses ab.
@PeterCordes Alternativ scale=1920:-2:flags=lanczos. -2Ich wollte auch die For-Skala in meiner nicht vorhandenen Antwort erwähnen . Für diejenigen, die es nicht wissen, können Sie -2Breite oder Höhe eingeben, und es wird automatisch der richtige Wert bereitgestellt, während das Seitenverhältnis beibehalten und der Wert durch 2 teilbar gemacht wird (erforderlich von libx264 für yuv420p-Ausgaben).
-sws_flagswird Lanczos zum Skalieren von Chroma verwenden, wenn zum Beispiel von 4:4:4: auf 4:2:0 oder umgekehrt gewechselt wird. Daher denke ich, dass es keine schlechte Idee ist, es jederzeit in Ihrer Befehlszeile zu haben, falls Sie etwas tun, das automatisch einen Skalierungsfilter einfügt. Aber ja, automatisch berechnete Höhe = Gewinn. Sie erhalten nicht immer perfekt quadratische Pixel in Ihrer Ausgabe, wenn die erforderliche Höhe kein Vielfaches von 2 (oder sogar eine ganze Zahl) ist, aber ffmpeg legt das Anzeige-Seitenverhältnis in der Ausgabe fest, damit die Spieler es korrekt skalieren, wenn nach oben oder unten skalieren.

Antworten (3)

Die Standardeinstellungen für ffmpeg sind von sehr niedriger Qualität, und da Sie keinen Codec oder Qualitätsparameter angeben, werden nur die Standardeinstellungen verwendet (ich weiß nicht, warum die Entwickler das nicht beheben, weil es viele Fragen in Foren aufwirft überall).

Bearbeiten : Die Standardeinstellungen sind jetzt ganz normal. Mit einem neueren (wie später als 2017) Build von ffmpeg müssen Sie nicht mehr als Eingabe- und Ausgabedateien angeben, um gute brauchbare Ergebnisse zu erzielen. Sie können natürlich nach Herzenslust zwicken.

Versuchen Sie , den Befehl hinzuzufügen.-c:v libx264 -crf 20 -preset slow

  • -c:v libx264weist ihn an, den libx264-Encoder zu verwenden, dies ist jetzt die Standardeinstellung, es ist nicht erforderlich, ihn anzugeben
  • crf 20verwendet den Quantisierer Constant Rate Factor (was paradoxerweise variable Bitrate, aber konstante Qualität bedeutet) mit einem Wert von 20 (ziemlich gute Qualität; niedriger ist bessere Qualität / größere Dateien, höher ist schlechter / kleiner) – Standard ist 23,
  • Die slowVoreinstellung ist eine Abkürzung für eine Reihe von Encoder-Einstellungen, was bedeutet, dass sie etwas mehr Aufwand erfordert als die Standardeinstellung (mittel). Beachten Sie, dass die Geschwindigkeitsvoreinstellungen nicht die Qualität der codierten Datei ändern, sondern nur die Effizienz, was bedeutet, dass eine langsamere Codierung zu einer kleineren Datei mit derselben Qualität führt und eine schnellere Codierung zu einer größeren Datei mit derselben Qualität.

Sie können diese Einstellungen optimieren, siehe H.264-Kodierungsleitfaden für Anweisungen, an welchen Knöpfen Sie drehen müssen.

Und wenn Sie das Audio so verwenden, wie es ist, fügen Sie hinzu c:a copy. Dadurch wird eine direkte Kopie des Audiostreams ohne Neucodierung erstellt.

Die Voreinstellungen hängen vom Encoder ab. libx264 wird normalerweise standardmäßig für die MP4-Ausgabe verwendet und erzeugt eine Ausgabe in guter Qualität ohne zusätzliche Optionen, aber der ffmpeg-Build in der Frage scheint diesen Encoder nicht zu unterstützen und verwendet daher den alten Encoder mpeg4, der MPEG-4 Part 2-Video erzeugt, und Die Standardeinstellungen dafür waren während seiner Blütezeit vernünftiger (z. B. für 320 x 240 usw.).
Es ist gut zu hören, dass libx264 jetzt die Standardeinstellung ist.
Ich würde sagen, crf 20 ist verdammt gut. 18 ist funktional verlustfrei. Ich mache die meisten meiner Videos mit 23.
Die meisten meiner Arbeiten werden auf Wiedergabegeräten angezeigt, die lokal von einer SD-Karte arbeiten. Ich muss nicht viel für die Größe optimieren, also lasse ich die Qualität so hoch wie möglich. Ich stimme zu, ich würde es herunterwählen, wenn ich über das Internet liefern würde.
Das hat mir nicht geholfen. Ich habe immer noch eine blockartige Verrücktheit, wo immer im Video Bewegung auftritt. crf von 18, voreingestellt auf langsam. 2,7k -> 1080p.
@rewolf poste eine Frage, anstatt sie in den Kommentaren zu stellen.
@stib Ich stelle keine Frage. Ich sage, dass dies keine definitive Antwort auf das gestellte Problem ist (oder eine der gleichen Art). Das ist nützlich für andere in der gleichen Position.
Was ist, wenn die Qualität bereits niedriger als 1080 ist und wir sie nicht hochskalieren möchten?
@OliverDixon Ich bin mir nicht sicher, was du fragst. Wenn die Auflösung niedriger als 1080p ist und Sie sie nicht hochskalieren möchten, können Sie sie in ihrer aktuellen Auflösung anzeigen.
@stib Ich habe eine Lösung mit 'min' gefunden. Ich habe Leistungsprobleme damit gesehen, weil Videos mit geringer Qualität versucht haben, von Benutzern hochzuskalieren.

Konvertieren Sie 4k in 1080 (keine Codec-Änderung)

ffmpeg -i input4kvid.mp4 -vf scale=1920:1080 -c:a copy output1080vid.mp4

h.264 in h.265 umwandeln (keine Auflösungsänderung)

ffmpeg -i input.mp4 -c:v libx265 -vtag hvc1 -c:a copy output.mp4

Konvertieren Sie 4k (h.264) in 1080 (h.265)

  • Herunterskalieren + Änderung des Komprimierungscodecs
ffmpeg -i input.mp4 -c:v libx265 -vtag hvc1 -vf scale=1920:1080 -crf 20 -c:a copy output.mp4

Optionen erklärt

-iEingabedateiname oder Dateipfad

-c:v libx265 -vtag hvc1Komprimierung auswählen. Standard istlibx264

-vf scale=1920:1080Angabe der Ausgabeauflösung

-c:a copyKopieren Sie Audio so, wie es ohne Komprimierung ist

-preset slowBitten Sie den Komprimierungsalgorithmus, sich mehr Zeit zu nehmen und nach mehr Bereichen für die Komprimierung zu suchen. Standard ist medium. Andere Optionen sind faster, fast, medium, slow,slower

-crf 20Kompressionsqualität

-crf 0hohe Qualität, geringe Komprimierung, große Datei

-crf 23Ursprünglich

-crf 51niedrige Qualität, hohe Komprimierung, kleine Datei

Verwenden Sie avconv , wenn Sie möchten:

avconv -i 4kfile.mp4 -s hd1080 -c:v libx264 -c:a copy fullhdfile.mp4