Genaue Audioauswahl

Wie wähle ich das Audio aus, das einem Satz von durch Filter ausgewählten Videoframes entspricht?

Im Moment nehme ich z. B. 1 von 100 Bildern eines Videos (das mit 15 fps läuft) mit dem FFMpeg select-Filter ab. Wenn ich versuche, das Audio dieser Frames mit dem Filter auszuwählen aselect, entspricht die Gesamtaudiodauer nicht der Videodauer (2 oder 3 Sekunden Unterschied, je nachdem, welche Frames ich ausgewählt habe). Die Audioabtastrate wird als 22050 Hz aufgeführt.

Ich habe versucht, verschiedene -vsyncund -asyncKombinationen zu verwenden, aber es hat keinen Unterschied gemacht. Gibt es eine genauere Art der Verwendung aselect?

Ein kurzer Beispielbefehl:

ffmpeg -i %INPUT% -vf select='between(n\,200\,399)',setpts='PTS-STARTPTS' -af aselect='between(n\,200\,399)',asetpts='PTS-STARTPTS'-y test.mkv

wobei „INPUT“ der Name einer Datei ist, die komprimiertes Video und Audio enthält. Ich teste mit der Datei AV36_1.avi, die auf dieser Seite gefunden wird, auf der Videobeispiele gehostet werden. Ich bekomme eine Videodauer von 13,3 Sekunden und eine Audiodauer von 12 Sekunden.

Ausgang:

ffmpeg version N-77045-ga16243a Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 5.2.0 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-av
isynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enab
le-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --
enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-l
ibilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enab
le-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --en
able-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --ena
ble-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc
 --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enabl
e-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --
enable-lzma --enable-decklink --enable-zlib
  libavutil      55.  9.100 / 55.  9.100
  libavcodec     57. 16.101 / 57. 16.101
  libavformat    57. 19.100 / 57. 19.100
  libavdevice    57.  0.100 / 57.  0.100
  libavfilter     6. 20.100 /  6. 20.100
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
Guessed Channel Layout for  Input Stream #0.1 : stereo
Input #0, avi, from 'AV36_1.avi':
  Duration: 00:00:32.93, start: 0.000000, bitrate: 2372 kb/s
    Stream #0:0: Video: indeo5 (IV50 / 0x30355649), yuv410p, 320x240, 2058 kb/s,
 15 fps, 15 tbr, 15 tbn, 15 tbc
    Metadata:
      title           : Steyr.avi ┬ΦΣσε #1
    Stream #0:1: Audio: adpcm_ms ([2][0][0][0] / 0x0002), 22050 Hz, 2 channels,
s16, 176 kb/s
    Metadata:
      title           : Sound Forge 4.0 Audio
Output #0, avi, to 'test.avi':
  Metadata:
    ISFT            : Lavf57.19.100
    Stream #0:0: Video: mpeg4 (FMP4 / 0x34504D46), yuv420p, 320x240, q=2-31, 200
 kb/s, 15 fps, 15 tbn, 15 tbc
    Metadata:
      title           : Steyr.avi ┬ΦΣσε #1
      encoder         : Lavc57.16.101 mpeg4
    Stream #0:1: Audio: mp3 (libmp3lame) (U[0][0][0] / 0x0055), 22050 Hz, stereo
, s16p
    Metadata:
      title           : Sound Forge 4.0 Audio
      encoder         : Lavc57.16.101 libmp3lame
Stream mapping:
  Stream #0:0 -> #0:0 (indeo5 (native) -> mpeg4 (native))
  Stream #0:1 -> #0:1 (adpcm_ms (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
frame=   98 fps=0.0 q=9.6 size=     294kB time=00:00:09.03 bitrate= 266.1kbits/s
frame=  200 fps=0.0 q=11.7 Lsize=     525kB time=00:00:13.33 bitrate= 322.5kbits
/s
video:429kB audio:72kB subtitle:0kB other streams:0kB global headers:0kB muxing
overhead: 4.625268%

Ich glaube, ich verwende den Aselect-Filter falsch ...

Fügen Sie Ihre verwendete Befehlszeile und die Konsolenausgabe ein.
@Mulvya fertig :)
Bitte formatieren Sie die Konsole neu, wie die erste Box hier .
Ihr Befehl wählt alle Frames von Nr. 200 bis Nr. 399 aus, nicht 1 von 100, und Ihre Beispieldatei wird als "Sehr seltsames AVI-Beispiel mit einer von r20118 behobenen Streuliste" angezeigt. Versuchen Sie es vielleicht mit einem vernünftigen Beispiel. Ich teste mich am Abend und melde mich wieder
Die genaue Auswahl spielt keine Rolle, der Punkt ist, dass die entsprechende Audioauswahl eine große Dauerabweichung hat. Dieses triviale Beispiel sollte weniger mögliche Komplikationen mit sich bringen als eine kompliziertere Auswahl von Frames (wie not(mod(n,100)) -vsync 0). Es wäre auch schwieriger, die entsprechenden Audioframes auszuwählen.
Sieht nach einem bekannten Problem aus: superuser.com/q/866144/114058
@Mulvya Inzwischen glaube ich, dass ich herausgefunden habe, dass es an der Differenz der Audio-Framerate liegt. Ich nahm an, dass es gleich der Videoframerate ist. Das Problem in Ihrem Link geht davon aus, dass die Audio-Framerate 48 fps beträgt, da die Abtastfrequenz 48 kHz betrug. Aber es scheint, dass beide Annahmen gefährlich sind. In diesem Fall beträgt die Audioframerate etwa 21,8 fps. Indem ich die aselectFrames mit einem Faktor korrigiere, 21.8/15erhalte ich eine viel genauere Audiospur. Ein paar Millisekunden Unterschied. :D
Wenn aselect Audio-Frames als Referenz verwendet, versuchen Sie es mit 22.05/15 und ob es dadurch genauer wird
@Mulvya Nein, die Audio-Framerate beträgt nicht 22,05 fps. Laut ffprobe ist es 22311/1024.

Antworten (1)

Dieser Befehl, der eine tReferenz für verwendete aselect, hat bei mir funktioniert:

ffmpeg -i AV36_1.avi -vf "select=between(n\,200\,399),setpts=PTS-STARTPTS" -af "aselect=between(t\,(200/15)\,(399/15)),asetpts=PTS-STARTPTS" -y test.mkv

Wenn Sie (Frames) verwenden möchten, nmüssen Sie die Framegröße des Audiocodecs kennen, z. B. 1024 Samples für AAC, variabel für MP3 usw

Cool, aber diese Konvertierung funktioniert nicht, wenn das Video eine variable Framerate hat. Die Informationen zu den Sample-Größen von Audioframes sind interessant. Ich dachte, die Samplingrate (in diesem Fall 22050 Hz) wäre im Laufe der Zeit immer konstant.
Die Abtastrate ist konstant, aber komprimierte Audiostreams stückeln nSamples frames, die nicht den Videoframegrenzen entsprechen. Ihre Methode funktioniert auch nicht für VFR, da die Audio-Framerate, die Sie von ffprobe erhalten, CFR ist. Ein Weg zu einer allgemeinen Lösung besteht darin, die PTS des ersten und des letzten ausgewählten Videoframes zu erhalten und dann die äquivalenten Zeiten an das aselect-Filter zu liefern.
Dann scheinen Zeitstempel der sicherste Weg zu sein. Würde also ein mp3-Frame mit 100 Samples zehnmal länger dauern als ein Frame mit 10 Samples? Wenn aselectnur ganze Audioframes ausgewählt werden können, könnte dies die Genauigkeit einschränken. Aber mein Bauch sagt mir, dass aselectSamples statt Frames ausgewählt werden (zumindest wenn Zeitstempel verwendet werden).
Nein. Hängt von der Abtastrate ab. Wenn Sie eine Rate von 48000 Hz haben, entspricht ein typischer MP3-Frame mit 1152 Samples 0,04166 Sekunden Audio. Wenn 24000 Hz, dann 0,0833 s.
aber ein typisches MP3-Frame existiert nicht, da sie eine variable Framegröße haben ... also haben einige Frames 1500 Samples, andere 900 usw. Ah, aber die Zeitstempel sind möglicherweise nicht so linear wie bei Video.