Bildrate beim Screencasting

701
Anmol Singh Jaggi

Ich versuche, den Bildschirm mit ffmpeg mit folgendem Befehl aufzuzeichnen :

ffmpeg -f x11grab -s 1366x768 -framerate 30 -i :0.0 -c:v libx264 -b:v 1000k out.mp4 

was ich von hier gelernt habe .

Aber ich kann nicht verstehen, was frameratein diesem Zusammenhang bedeutet.

Hier ist was ich denke :

Wenn wir einen Satz von Bildern, die in einem Verzeichnis gespeichert sind, in ein Video wie hier erwähnt konvertieren, hätte eine Framerate von Folgendes 30bedeutet: 'Zeigen Sie die ersten 30 Bilder in der ersten Sekunde des Videos an, die nächsten 30 Bilder in der nächsten Sekunde und so ein, bis alle Bilder aufgebraucht sind ' .
Beispiel: Wenn wir 90 Bilder hätten, hätte das resultierende Video 3 Sekunden gedauert.

In gleicher Weise sollte während des Screencastings Folgendes passieren:

Angenommen, meine Bildschirmaktualisierungsrate beträgt 60 Hz, werden 60 Bilder pro Sekunde erzeugt und in einem Puffer gespeichert.
Da ffmpegjedoch eine Framerate von 30 gegeben wurde, nimmt er die ersten 30 Bilder (Bilder # 1 - # 30) aus dem Puffer und erzeugt 1 Sekunde Video, nimmt dann Bilder # 31 - # 60 und erzeugt die nächste Sekunde Video .
Das bedeutet, dass während 1 Sekunde der Aufnahme 2 Sekunden Video produziert werden.


Um diese Theorie zu testen, habe ich folgendes Experiment durchgeführt:

Ich lief eine grafische Stoppuhr auf dem Bildschirm und ließ sie genau 10 Sekunden laufen, während gleichzeitig die Stoppuhr von 1-10 aufgenommen wurde.

Nach meiner Theorie hätte entweder das produzierte Video eine Dauer von 20 Sekunden haben müssen und eine komplette Stoppuhrzählung von 1 bis 10 ergeben, oder um die Videozeit gleich der Aufnahmezeit zu halten, hätte ffmpeg ein Video von 10 Sekunden generiert und nur gezeigt Die Hälfte der Stoppuhr zählt von 1 bis 5 (die ersten 30 * 10 = 300 Frames von insgesamt 600 Frames, die von der Grafikkarte gleichzeitig erzeugt wurden).

Aber keiner der beiden oben genannten Fälle ist passiert. Stattdessen betrug die Länge des Videos 10 Sekunden und der Inhalt war genau so, wie der Bildschirm während der Aufnahme aussah, dh die Stoppuhrzählung ging von 1 bis 10.

Ich wiederholte dasselbe Experiment mit einer Framerate von 10 anstelle von 30 und fand die gleichen Ergebnisse, d. H. Die Videolänge betrug 10 Sekunden und die Stoppuhrzählung wurde von 1 bis 10 angezeigt.

Was ist also falsch an meiner Theorie?


Die einzige andere Theorie, an die ich denken konnte und die mit meinen Beobachtungen übereinstimmt, lautet:

Da ffmpeg bei einem Eingangsstrom von 60 Hz mit einer Framerate von 30 aufnehmen muss, überspringt es jedes andere Bild während der Videoproduktion.
Das heißt, es verwendet Bild # 1, # 3, # 5 ... # 60, um 1 Sekunde Video zu erzeugen.

Ich bin mir jedoch nicht sicher, ob dies richtig ist.


Meine Systemkonfiguration:

  • OS: Ubuntu 16.04

  • ffmpeg-Version:
    ffmpeg version 2.8.6-1ubuntu2 Copyright (c) 2000-2016 the FFmpeg developers built with gcc 5.3.1 (Ubuntu 5.3.1-11ubuntu1) 20160311 configuration: --prefix=/usr --extra-version=1ubuntu2 --build-suffix=-ffmpeg --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared --disable-stripping --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzvbi --enable-openal --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-libx264 --enable-libopencv libavutil 54. 31.100 / 54. 31.100 libavcodec 56. 60.100 / 56. 60.100 libavformat 56. 40.101 / 56. 40.101 libavdevice 56. 4.100 / 56. 4.100 libavfilter 5. 40.101 / 5. 40.101 libavresample 2. 1. 0 / 2. 1. 0 libswscale 3. 1.101 / 3. 1.101 libswresample 1. 2.101 / 1. 2.101 libpostproc 53. 3.100 / 53. 3.100

0
Deine 2. Theorie ist richtig. FFmpeg versucht, zeitliche Beziehungen beizubehalten, sodass ein 60-fps-Feed, der für den Empfang von 30 fps konfiguriert ist, die Hälfte der Frames reduziert. Gyan vor 7 Jahren 1
Vielen Dank @ Mulvya. Kannst du mir noch etwas sagen - Die beiden Videoausgänge (mit fps 30 und 10) haben die gleiche Dateigröße. Ich verstehe, dass dies daran liegen könnte, dass beide Videos die gleiche Bitrate haben. Aber dann bedeutet das, dass im 10-fps-Video die Bits / Bilder mehr sind und daher jedes Bild mehr * gestochen scharf * (mehr Farbtiefe) ist als das 30-fps-Bild? Anmol Singh Jaggi vor 7 Jahren 0
Im Allgemeinen ja. Wenn die Bitrate jedoch hoch genug ist und die Bewegung selten ist, werden Sie keinen großen Unterschied bemerken. Gyan vor 7 Jahren 0
Da ich meine Antwort habe, möchte ich die Frage schließen. Möchten Sie die Antwort schreiben oder soll ich es selbst tun? Anmol Singh Jaggi vor 7 Jahren 0

1 Antwort auf die Frage

1
Gyan

FFmpeg ist ein zeitbasierter Medienprozessor und bemüht sich als solcher, die zeitliche Beziehung der Eingabe aufrechtzuerhalten, sofern nicht anders angegeben.

Die framerateOption für das x11grabGerät legt die Erfassungsrate fest. Wenn pro Sekunde weniger oder mehr Frames bereitgestellt werden, wird die Differenz von ffmpeg dupliziert bzw. verworfen.