Das Kopieren von h.264-Videos von TS in MP4 ändert Bildrate und Zeit

Ich habe eine große MPEG-TS-Datei, die ich mit dem folgenden Befehl in MP4 konvertiere. Wenn ich im Video sowohl in der MP4- als auch in der TS-Datei nach der gleichen Zeit suche, wird die MP4-Datei einige Frames hinter der TS-Datei liegen. Dies wird zunehmend schlimmer, je weiter ich in dem Video suche.

c:\>ffmpeg -y -r 30 -i full-ts.ts -c:v copy -r 30 -an full.mp4
ffmpeg version N-69040-gb23a866 Copyright (c) 2000-2015 the FFmpeg developers
  built on Jan 12 2015 22:02:37 with gcc 4.9.2 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --
enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinge
r --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-
libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --enable-zlib
  libavutil      54. 16.100 / 54. 16.100
  libavcodec     56. 20.100 / 56. 20.100
  libavformat    56. 18.101 / 56. 18.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5.  7.100 /  5.  7.100
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  3.100 / 53.  3.100
Input #0, mpegts, from 'full-ts.ts':
  Duration: 00:11:25.75, start: 1.424000, bitrate: 3407 kb/s
  Program 1
    Metadata:
      service_name    : Service01
      service_provider: FFmpeg
    Stream #0:0[0x100]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 30 fps, 30 tbr, 90k tbn, 60 tbc
    Stream #0:1[0x101]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 125 kb/s
Output #0, mp4, to 'full.mp4':
  Metadata:
    encoder         : Lavf56.18.101
    Stream #0:0: Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 30 fps, 30 tbr, 15360 tbn, 30 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame=20419 fps=0.0 q=-1.0 Lsize=  251660kB time=00:11:25.59 bitrate=3007.0kbits/s
video:251446kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.084929%

Ich bin verwirrt, warum die TBN im Ausgabestrom so groß ist. Ich habe -copyts, -copytb, alle -vsynch-Optionen ausprobiert, aber ich kann keine Suchzeiten erhalten, die auf dem MP4 übereinstimmen. Außerdem zeigt die MP4 eine Bildrate von 29,78, während die TS-Datei mit ffprobe solide 30/1 ist.

ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=avg_frame_rate full.mp4
streams_stream_0_avg_frame_rate="5227264/175529"

ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=avg_frame_rate full-ts.ts
programs_program_0_streams_stream_0_avg_frame_rate="30/1"
streams_stream_0_avg_frame_rate="30/1" 

Irgendeine Idee, wie ich die Suche in beiden Containern dazu bringen kann, denselben Frame anzuzeigen? Bitte helfen Sie!

Was passiert, wenn Sie die Eingabe entfernen -r 30? Was ist überhaupt der Grund dafür? Außerdem aktivieren Sie den Stream-Kopiermodus , -c:v copywodurch die Ausgabe -r 30ignoriert wird.
@LordNeckbeard - es ändert ein paar Dinge in der Ausgabe, aber ich habe immer noch das Suchproblem. Siehe log @ gist.github.com/andypryor/3b1f123b4c8d6ed3975c , Danke für die Erklärung, dass -r 30 nicht benötigt wird, ich habe seine Verwendung falsch verstanden, dachte, ich könnte die mp4-Bildrate erzwingen.
So wie ich es verstehe, speichert mp4 nirgendwo eine Framerate, sondern nur Zeiten zwischen einzelnen Frames. ffprobe sieht sich also die Bildzeiten der ersten paar Bilder an und geht davon aus, dass der Rest des Videos gleich ist. Ich habe jedoch keine Idee, um Ihr Problem tatsächlich zu lösen. Außer vielleicht versuchen Sie etwas anderes als ffmpeg, wie MP4Box. Oder sogar mkvmerge zu einer .mkv, um zu sehen, ob das anders funktioniert. (Und versuchen Sie vielleicht, ffmpeg zu etwas anderem als mp4 zu muxen. Der mp4-Muxer von ffmpeg ist möglicherweise nicht perfekt.)
Die Standardvideobildrate beträgt 29,97, wenn Sie in 30 fps konvertieren, sehen Sie schließlich eine Drift: filmdoctor.net/2010/06/drop-frame-vs-non-drop-frame
tbn des Ausgabestreams ist zu klein 15k. 90k sollten es sein. Scheint, als ob das Verwerfen des Audiostreams die Ursache des Problems ist.
@incBrain das tbnist kein Problem. Die tbnfür TS ist 90kunabhängig von der Framerate des Videostreams fest und FFmpeg generiert eine tbn tbr x 512für MOV/MP4-Formate, wobei tbrdie Codec-Framerate ist. Audio spielt hier keine Rolle, da tbnes sich auf die Videozeitskala bezieht.
@Mulvya tnx für die Info. Weißt du, warum sie sich entschieden haben tbr x 512? Warum 512?

Antworten (1)

Laut einem Kommentar hier sollte das Entfernen des Flags -r dies ordnungsgemäß tun. Sie haben auch ein weiteres -r-Flag für die Eingabe. Entfernen Sie beide, und der Stream sollte ordnungsgemäß so wie er ist in einen neuen Container kopiert werden; Möglicherweise müssen Sie auch diesen Schalter -an (Audio deaktivieren) entfernen. Da bin ich mir nicht sicher:

ffmpeg -y -i full-ts.ts -c:v copy full.mp4

Wenn dies fehlschlägt, können Sie auch per Kommentar hier ein anderes Ausgabecontainerformat ausprobieren.