ffmpeg segment nach videozeit anstelle von wandzeit

1932
studog

Ich habe ein System, das Video auf Platte aufzeichnet, und manchmal hat das System einen Fehler. Ich versuche, das Aufnahmesystem im Labor ohne die eigentliche Kamera neu zu erstellen (es ist teuer und es gibt keine Ersatzteile), um zu versuchen, das Verwendungsmuster zu replizieren, das den Fehler verursacht.

Ich habe Probleme, ffmpeg zu zähmen.

Hintergrund:

Das Video wird fortlaufend in einem Thread von einer rtsp: //-URL erfasst, die von der angeschlossenen Kamera mit dem folgenden Befehl bereitgestellt wird:

ffmpeg -i rtsp://192.168.0.10/h264 -c copy -map 0 -f segment -segment_time 900 -segment_format mp4 -segment_atclocktime 1 -strftime 1 /tmp/capture-%s.mp4 

Dies funktioniert und produziert Videodateien mit einer Dauer von 15 Minuten wie erwartet.

Problem:

Im Labor habe ich weder die Kamera noch den Stream rtsp: //. Ich habe stattdessen eines der Capture-MP4s aus dem realen System kopiert und benutze das stattdessen als Eingabe für ffmpeg. So etwas wie:

ffmpeg -stream_loop -1 -i capture-1469547000.mp4 -c copy -map 0 -f segment **-** -segment_format mp4 -strftime 1 /tmp/captest-%s.mp4 

Der -stream_loop -1Parameter macht das, was erwartet wird: Er liest aus der Eingabedatei (Dauer 15 Minuten) und erzeugt einen unendlichen Ausgabestrom. Dies ist eine vernünftige Annäherung an das Lesen aus dem Stream rtsp: //.

Was ich nicht herausfinden kann, ist, welche Parameter verwendet werden müssen, damit dieses Laborsystem das Video in Abschnitte von 15 Minuten Länge teilt, genau wie das reale System. Was ich erwarte, ist eine Folge von Ausgabedateien, die ungefähr die gleiche Größe wie die Eingabedatei haben.

Versuch Nr. 1

Die Verwendung -segment_time 900scheint, entweder a) den Wanduhrwert von 15 Minuten verwenden zu wollen oder b) ignoriert zu werden. Da das Kopieren von einer vorhandenen MP4-Datei viel schneller ist als das Kopieren aus dem Stream rtsp: //, enthält die Capture-Datei viele Kopien des Originals.

Versuch Nr. 2

Ich habe diesen Befehl verwendet

ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 capture-1469547000.mp4 

um zu bestimmen, dass die Eingabedatei 13494 Frames hat.

Die Verwendung -segment_frames 13494scheint ignoriert zu werden und die Ausgabe ist überhaupt nicht segmentiert.

Versuch Nr. 3

Ich habe eine Menge der ffmpeg-Dokumentation gelesen und fehlt, was ich brauche oder es existiert nicht.

Die Verwendung -ss *position* -t *duration*macht keine kontinuierliche Aufzeichnung und Segmentierung der Ausgabe.

Bitte um Hilfe

Welche Parameter sollte ich verwenden, um die Segmentierung auf a) zu bringen und b) 15 Minuten Videodauer sind?

Mögliche Komplikation

Die Zeitstempel (DTS?) Im Beispiel-MP4 sind nicht "gut", da dieser Fehler kontinuierlich erzeugt wird:

[Segment @ 0x2abc7c0] Nicht monotoner DTS im Ausgangsstrom 0: 0; bisher: 80990160, aktuell: -74730276972; Änderung in 80990161. Dies kann zu falschen Zeitstempeln in der Ausgabedatei führen.  DTS 191648787, nächste: -830336344130 st: 0 ungültiges Ablegen  PTS 191648787, nächste: -830336344130 ungültiges Ablegen von st: 0 

Ich brauche die resultierenden Videodateien jedoch nicht, um tatsächlich abzuspielen oder intakt zu sein. Daher ignoriere ich dies, es sei denn, dies hat Auswirkungen auf die Segmentierung, die ich neu erstellen muss.

Weitere Informationen

ffmpeg-Version:

\ # / usr / share / local / bin / ffmpeg -version  ffmpeg version N-79587-g9f9c833 Copyright (c) 2000-2016 der FFmpeg-Entwickler  gebaut mit gcc 4.8 (Ubuntu / Linaro 4.8.2-16ubuntu4)  Konfiguration: --prefix = / home / t / dev / j / Drittanbieter / ffmpeg /../ build --cross-prefix = / usr / bin / arm-linux-gnueabihf-cpu = armv7-a - -disable-shared --enable-static --enable-gpl --enable-pthreads --enable-nonfree --enable-libx264 --enable-filters --extra-libs = -static --extra-cflags = - static --enable-cross-compile --target-os = linux --disable-inline-asm --arch = armv7 --disable-debug --disable-altivec --disable-sse --disable-armv6 --disable -armv6t2 --disable-mmx --disable-neon --disable-amd3dnow --disable-thumb --extra-ldflags = -L / home / t / dev / j / Drittanbieter / ffmpeg /../ build / lib --extra-cflags = -I / home / t / dev / j / Drittanbieter / ffmpeg / ../ build / include --extra-ldflags = -L / home / t / dev / j / Drittanbieter / ffmpeg / libavcodec --extra-ldflags = -L / home / t / dev / j / Drittanbieter / ffmpeg / libavdevice --extra-ldflags = -L / home / t / dev / j / Drittanbieter / ffmpeg / libavfilter --extra-ldflags = -L / home / t / dev / j / Drittanbieter / ffmpeg / libavformat --extra-ldflags = -L / home / t / dev / j / Drittanbieter / ffmpeg / libavresample --extra-ldflags = -L / home / t / dev / j / Drittanbieter / ffmpeg / libavutil - extra-ldflags = -L / home / t / dev / j / Drittanbieter / ffmpeg / libswscale --extra-ldflags = -lx264 --extra-ldflags = -lm --extra-ldflags = -ldl --extra- cflags = '- fpic -mthumb'-fpic -mthumb '-fpic -mthumb '  Libavutil 55. 22.101 / 55. 22.101  libavcodec 57. 38.100 / 57. 38.100  libavformat 57. 34.103 / 57. 34.103  libavdevice 57. 0,101 / 57 0,101  libavfilter 6. 44.100 / 6. 44.100  libswscale 4. 1.100 / 4. 1.100  libswresample 2. 0,101 / 2 0,101  libpostproc 54. 0,100 / 54 0,100 
2

2 Antworten auf die Frage

0
Gyan

segment_timesollte arbeiten. Es bezieht sich auf die Segmentdauer, nicht auf die Wanduhr.

Die Platzierung der Keyframes wird möglicherweise behindert. Versuchen Sie es daher

ffmpeg -fflags +genpts -i capture-1469547000.mp4 -c copy -map 0 -f segment -segment_time 900 -segment_format mp4 -break_non_keyframes 1 -strftime 1 /tmp/capture-%s.mp4 

Ich habe die Option stream_loop entfernt, da derzeit ein Zeitstempel-Generierungsfehler im Zusammenhang mit der Verwendung vorliegt. Das kann auch hier stören.

Wenn Sie einen wirklich langen Stream zum Arbeiten benötigen, verwenden Sie den concat Demuxer.

Erstellen Sie eine Textdatei

file 'capture-1469547000.mp4' file 'capture-1469547000.mp4' file 'capture-1469547000.mp4' file 'capture-1469547000.mp4' file 'capture-1469547000.mp4' file 'capture-1469547000.mp4' file 'capture-1469547000.mp4' file 'capture-1469547000.mp4' 

Und dann verwenden

ffmpeg -f concat -i list.txt -c copy ... 
Vielen Dank für die Hilfe, sehr geschätzt. Der concat Demuxer funktioniert. Die Verwendung von `-break_non_keyframes 1` ändert das Verhalten nicht. :-( Alle Kombinationen von x {, break_non_keyframes} das Verhalten ist das gleiche: Es wird ein erstes Segment erstellt, das etwa dreimal so groß ist wie _size_ der Eingabedatei (ich habe gestern nicht lange genug gewartet), und das zweite Segment scheint ungebunden zu wachsen, zumindest auf mehr als 3x das _size_ des ersten Segments. Die Videozeit der Eingabe wird nicht respektiert. Ich werde diese "nicht-monotonen DTS" -Fehler genauer betrachten. studog vor 7 Jahren 0
0
studog

Ich habe eine funktionierende Lösung.

Die Hauptursache

Die Beispiel-Capture-Datei, die ich gespeichert habe, erwies sich als nicht gut für die gewünschten Zwecke (ein unendlicher Eingabestream), obwohl es sich sonst um eine gute Videodatei handelt (sie läuft gut, obwohl sie nicht gesucht werden kann). Das Problem scheint mit den Zeitstempeln und möglicherweise einem oder mehreren Fehlern des Segmentmuxers zu zusammenhängen.

Die Lösung

ich rannte

ffmpeg -i capture-1469547000.mp4 -c copy captemp.mp4 

Mit captemp.mp4stattdessen bekomme ich einen guten Strom entweder mit stream_loop oder concat muxer.

Ich bin nicht sicher, was der Unterschied zwischen capture-1469547000.mp4 und captemp.mp4 ist. AtomicParsley zeigt, dass captemp.mp4 im 'elst'-Atom 12 Byte kürzer ist.

Ein weiterer Blick auf mein ursprüngliches Setup und das Hinzufügen segment_listwar aufschlussreich: Die Segmente wurden korrekt aber sehr schnell generiert. Sie wurden lediglich an die vorhandene Segmentdatei angehängt, anstatt eine neue zu erstellen. Das ist zum Teil die Schuld von ...

möglicher Fehler in der Laufzeit

Ich habe strftimemit einem %sFormat verwendet. Es stellte sich heraus, dass die strftime-Zeit die Uhrzeit des Host-Computers und nicht die Uhrzeit innerhalb des Videosegments verwendet. Dies gilt sogar im "Arbeitsfall"; Ich habe %dstattdessen auf die Formatierung des Segment- Muxers umgestellt.

Dies ist wahrscheinlich ein Fehler, weshalb sich die Segmente im Nichtarbeitsfall aneinander anhingen.

Ich bin ziemlich sicher, dass die Verwendung des -reFlags dieses Problem durch Verlangsamen der Verarbeitung lösen würde, aber ich möchte eine beschleunigte Verarbeitung. Also habe ich das nicht probiert.