Wie kann ich in FFMPEG gezielt nach einem AVC MPEG-TS-Stream suchen?

Wie kann ich in FFMPEG gezielt nach einem AVC MPEG-TS-Stream suchen?

Ich habe mehrere Videoaufnahmen von Full HD IPTV-Kanälen, die ich mit VLC gespeichert habe. Diese Stream-Dumps sind als MPEG-TS-Dateien gespeichert und enthalten AVC-codiertes Video mit MPEG-Audio.

Ich möchte aus diesen Aufnahmen bestimmte Clips extrahieren, basierend auf bildgenauen Schnittpunkten. Es fällt mir jedoch schwer, die genauen Millisekunden-Zeitstempel zu bestimmen, die ich weitergeben mussFFMPEG-ssund Parameter , -toum die gewünschten Schnittpunkte genau zu erreichen. Folgendes habe ich bisher versucht:

Versuch 1

Mein erster Versuch bestand darin, die .tsDateien zu laden inAvidemuxda es eine bequeme Einzelbildsuche ermöglicht und den Zeitstempel des aktuellen Einzelbilds in der erforderlichen Genauigkeit anzeigt. Wenn ich jedoch den Zeitstempel eines Einzelbilds, nach dem ich suche (im Format HH:MM:SS.mmm), in dasFFMPEGParameter, wird der Schnitt tatsächlich um mehrere Frames verschoben, manchmal über eine Sekunde. Die Abweichung ist für jede Datei unterschiedlich und kann positiv oder negativ sein.

Dann fiel mir auf, dass bei den meisten dieser Aufnahmen das erste BildAvidemuxzeigt tatsächlich einen Zeitstempel an, der nicht Null ist (z. B. 00:00:00.280oder sogar 00:00:00.216). Ich nahm an, dassVLCstartet die Aufnahme sofort, aberAvidemuxignoriert alles bis zum ersten I-Frame. Ich wundere mich 00:00:00.216jedoch immer noch über einen Zeitstempel wie , da diese Videos 25 fps haben und 216 nicht einmal ein Vielfaches von 40 ms ist.

Bildbeschreibung hier eingeben

Versuch 2

Ich habe einen Zwei-Durchgang-Prozess ausprobiert, bei dem ich das Video einmal kodieren würde, wobei ich die Kodierung etwas früher als den gewünschten Schnitt beginnen und etwas nach dem gewünschten Ende beenden würde. Ich würde dann verwendenAvidemuxdie überzähligen Frames am Anfang und Ende des Videos zu zählen und die Schnittpunkte nach nFrames * 40 msinnen zu verschieben. Die Ergebnisse waren jedochTrotzdemnicht präzise, ​​es würde dazu führen, dass ich das Video manchmal um zu wenige, manchmal um zu viele Frames kürze.

Vertrauensverlust inAvidemuxoder zumindest zu dem Schluss, dass einige Berechnungen anders durchgeführt werden alsFFMPEG, dachte ich, der sicherste Weg wäre, dasselbe Tool zum Festlegen der Schnittpunkte zu verwenden, das ich auch zum eigentlichen Schneiden des Videos verwende.

Versuch 3

Ich habe versucht, einzelne Frames um die gewünschten Schnittpunkte herum mit FFMPEG zu extrahieren, indem ich dieselben -ssParameter -towie beim Schneiden des Videos verwendete, aber nur einen Bereich in der Nähe der gewünschten Schnittpunkte auswählte und die Frames in Bilddateien schrieb. Ich würde auch einen Filter verwenden, um den genauen Zeitstempel jedes Frames einzubrennen, der bestimmt wird durchFFMPEG, direkt in das Bild. So könnte ich einfach die gewünschten Schnittpunkte ablesen und für die eigentliche Kodierung verwenden. Meine Kommandozeile würde dann etwa so aussehen:

ffmpeg.exe -i input.ts -ss 00:00:29.000 -to 00:00:31.000 -vf drawtext=fontfile=roboto.ttf:fontsize=40:text='%{pts\:hms}':[email protected]:x=10:y=10 image%03d.png

Dann suche ich nach der genauen PNG-Datei, bei der der Schnitt sein soll, schaue mir den Zeitstempel an und wenn dort steht 00:00:30.160, ist das der Zeitstempel, den ich für den -sseigentlichen Schnitt verwenden würde.

Bildbeschreibung hier eingeben

DiesTrotzdemhat nicht funktioniert und meine Schnittpunkte liegen immer noch mehrere Frames früher oder später als die extrahierten PNGs.FFMPEGDie Ausgabe von Videos in Bilder scheint die Berechnung der Zeitstempel zu beeinflussen, da diese nicht übereinstimmen.


Bisher habe ich noch keine Möglichkeit gefunden, einen langwierigen binären Suchvorgang zu vermeiden, um manuell die genauen Zeitstempel zu finden, an denen die Schnitte sein müssen. Das ist besonders mühselig, weil ich die benötigten Zeitstempel nur durch „Full-Decode-Seeks“ (also durch Verwendung -ssnach dem Eingabeparameter und nicht davor) erhalten kann und es sehr lange dauern kann, eine Position nach mehreren Stunden einer Aufnahme zu suchen.

Wie finde ich den Zeitstempel, den ich brauche, um einen Frame-genauen Schnitt zu erhalten?FFMPEGin einem MPEG-Transportstrom, ohne die Videosegmente mehrfach dekodieren, schneiden und speichern zu müssen, um sie dann manuell näher zu bringen?

Hier ist dasMedieninformationauf einer der Aufnahmen, falls diese Hinweise darauf enthält, dass mit den Streams selbst etwas nicht stimmt:

General
ID                                       : 1 (0x1)
Complete name                            : C:\Users\…\vlc-record-2021-03-09-00h23m11s.ts
Format                                   : MPEG-TS
File size                                : 2.31 GiB
Overall bit rate mode                    : Variable

Video
ID                                       : 256 (0x100)
Menu ID                                  : 1 (0x1)
Format                                   : AVC
Format/Info                              : Advanced Video Codec
Format profile                           : High@L4
Format settings                          : CABAC / 4 Ref Frames
Format settings, CABAC                   : Yes
Format settings, Reference frames        : 4 frames
Codec ID                                 : 27
Width                                    : 1 920 pixels
Height                                   : 1 080 pixels
Display aspect ratio                     : 16:9
Frame rate                               : 25.000 FPS
Standard                                 : Component
Color space                              : YUV
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Scan type                                : Interlaced
Scan type, store method                  : Separated fields
Scan order                               : Top Field First
Color range                              : Limited
Color primaries                          : BT.709
Transfer characteristics                 : BT.709
Matrix coefficients                      : BT.709

Audio
ID                                       : 257 (0x101)
Menu ID                                  : 1 (0x1)
Format                                   : MPEG Audio
Format version                           : Version 1
Format profile                           : Layer 2
Codec ID                                 : 3
Bit rate mode                            : Constant
Bit rate                                 : 128 kb/s
Channel(s)                               : 2 channels
Sampling rate                            : 48.0 kHz
Compression mode                         : Lossy
Delay relative to video                  : -248 ms

Menu
ID                                       : 4096 (0x1000)
Menu ID                                  : 1 (0x1)
List                                     : 256 (0x100) (AVC) / 257 (0x101) (MPEG Audio)
Service name                             : Service01
Service provider                         : FFmpeg
Service type                             : digital television

Zusätzliche Information:Die Zeitstempelabweichung ist für jede Datei unterschiedlich, aber innerhalb jeder Datei konstant. Das heißt, wenn ich mehrere Schnitte in einem Video machen muss und für einen Schnitt feststelle, dass der Zeitstempel in den mitFFMPEGist immer 160 ms niedriger als das, was ich verwenden muss -ss. Ich kann denselben Offset für die restlichen Schnitte in derselben Datei verwenden und es wird präzise sein.

verwandte Informationen