Come posso convertire il file .MTS (AVCHD) in .mp4 di ffmpeg senza ricodificare il flusso video H264?


20

Nota: ho pubblicato la stessa domanda su StackOverflow poco tempo prima, quando non ho ancora trovato questa comunità. Ripubblico perché la domanda è più adatta a questa comunità.

1. Cosa ho provato

Ho alcuni file .MTS (formato AVCHD) registrati con la mia videocamera AVCHD . Le sue specifiche sono le seguenti:

$ ffprobe 140612_Canon-00000.MTS 
ffprobe version 2.2.1 Copyright (c) 2007-2014 the FFmpeg developers
(snip)
Input #0, mpegts, from '140612_Canon-00000.MTS':
  Duration: 00:48:58.40, start: 0.800300, bitrate: 5563 kb/s
  Program 1 
    Stream #0:0[0x1011]: Video: h264 (High) (HDMV / 0x564D4448), 
      yuv420p, 1440x1080 [SAR 4:3 DAR 16:9], 
      29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0:1[0x1100]: Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, 
      stereo, fltp, 256 kb/s

Prestare attenzione alla parte del framerate / base dei tempi: 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc

Ora vorrei convertire questo file in file .mp4, senza ricodificare il flusso video H264 , d'altra parte, con la transcodifica del suo flusso audio in AAC . Quindi ho provato il seguente comando:

ffmpeg -i 140612_Canon-00000.MTS -t 60 -y -vcodec copy -acodec libfaac -ab 128k 140612_Canon-00001.MTS.mp4

2. Risultato

e le specifiche del file di output sono le seguenti:

$ ffprobe 140612_Canon-00000.MTS.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '140612_Canon-00000.MTS.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf55.33.100

  Duration: 00:01:00.04, start: 0.021333, bitrate: 4590 kb/s

    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 
        1440x1080 [SAR 4:3 DAR 16:9], 4448 kb/s, 
        59.94 fps, 59.94 tbr, 90k tbn, 59.94 tbc (default)
    Metadata:
      handler_name    : VideoHandler

    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 
        48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      handler_name    : SoundHandler

Guarda la parte del framerate / base dei tempi: 59.94 fps, 59.94 tbr, 90k tbn, 59.94 tbc . Sebbene ffmpeg abbia appena copiato il flusso video, framerate e timebase sono stati cambiati in due volte il valore .

Pertanto, quando apro e riproduco il file di output con QuickTime Player o VLC Player, l'audio non presenta alcun problema, tuttavia il flusso video non viene riprodotto correttamente. Il video viene riprodotto con la cornice in avanti e all'indietro più volte tremante.

3. Domanda

  1. Come posso convertire il file .MTS (AVCHD) in .mp4 di ffmpeg senza ricodificare correttamente il flusso video H264 ?
  2. Come posso mantenere i valori di framerate / timebase originali (fps / tbr / tbn / tbc) quando converto il contenitore con ffmpege il suo -vcodec copyswitch.
  3. Come posso impostare i valori di framerate / base dei tempi (fps / tbr / tbn / tbc) dalle opzioni della riga di comando di ffmpeg senza ricodificare un flusso video.

Qualche idea?


4. Aggiunta -r 29.97dell'opzione

Il professor Sparkles mi ha dato un consiglio da aggiungere -r 29.97. Ho provato che:

ffmpeg -i 140612_Canon-00001.MTS -t 60 -r 29.97 -y -vcodec copy -acodec libfaac -ab 128k 140612_Canon-00001.MTS.mp4

Tuttavia, il file di output ha ancora framerate / timebase errati:

Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 
1440x1080 [SAR 4:3 DAR 16:9], 4448 kb/s, 
59.94 fps, 59.94 tbr, 11988 tbn, 59.94 tbc (default)

5. Remux usando MP4Box

Ho provato demux e remux usando MP4Box, secondo i consigli del Professor Sparkles.

brew install mp4box

ffmpeg -i 140612_Canon-00000.MTS -t 60 -y \
  -vcodec copy -an 140612_Canon-00000.MTS.h264

ffmpeg -i 140612_Canon-00000.MTS -t 60 -y \
  -vn -acodec libfaac -ab 128k 140612_Canon-00000.MTS.aac

mp4box -add 140612_Canon-00000.MTS.h264:fps=29.97 \
  -add 140612_Canon-00000.MTS.aac \
  -new 140612_Canon-00000.MTS.mp4

e l'output era:

$ ffprobe 140612_Canon-00000.MTS.mp4

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '140612_Canon-00000.MTS.mp4':
(snip)
  Duration: 00:02:00.22, start: 0.000000, bitrate: 2293 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), 
          yuv420p, 1440x1080 [SAR 4:3 DAR 16:9], 2228 kb/s, 
          29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
    Metadata:
      creation_time   : 2014-07-14 00:38:23
      handler_name    : 140612_Canon-00000.MTS.h264:fps=29.97
       - Imported with GPAC 0.5.0-rev4065

    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 48000 Hz, 
          stereo, fltp, 125 kb/s (default)

Sembra un po 'avanti. Guarda la parte del framerate / base dei tempi: 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc . Questi corrispondono al flusso originale, ad eccezione ditbn (valore della base dei tempi dal contenitore).

Tuttavia, quando riproduco il file di output con Quicktime Player o VLC, il video viene riprodotto a metà velocità .

Sebbene il file originale abbia 90k tbn(90000 tick al secondo) e il nuovo file di output da MP4Box abbia 30k tbnun valore di appena un terzo di quello originale, il file di output viene riprodotto a metà velocità.

Non conosco il motivo per cui. Ma penso che il resto sia come posso aggiustare il tbnvalore.


5-b. Rapporto di MediaInfo sul file di output

Ho anche provato lo strumento MediaInfo sul file di output generato da 5. Remux usando MP4Box . L'output è qui: https://gist.github.com/kaorukobo/c5ab9eaa413dff6cd26a


6. Provare avconv

Volodya ha avconvfunzionato bene. Inoltre ho preparato un breve filmato di esempio (Canon-00006.MTS) registrato con la stessa fotocamera. Ok, proviamo:

brew install avconv
avconv -i Canon-00006.MTS -c:a copy -c:v copy -y Canon-00006.MTS.mp4
ffprobe Canon-00006.MTS.mp4

Le informazioni su ffprobe del file di output sono qui: https://gist.github.com/kaorukobo/5b53244ade2632ff1211 e le sue informazioni su framerate / timebase sono le seguenti: 59.94 fps, 59.94 tbr, 90k tbn, 59.94 tbc

Il file di output è stato riprodotto bene con VLC Player come riportato da Volodya. Tuttavia, aprendolo con Quicktime Player X, il video è stato riprodotto alla velocità normale ma con il suo fotogramma all'indietro ripetutamente ripetutamente.


7. Perché l'app "Free AVCHD to MOV" funziona?

Come ho già detto nel mio commento precedente , la funzione "rewrap to MOV" dell'app Free AVCHD to MOV ha funzionato bene, anche se non produce MP4 ma MOV.

Il software chiama internamente il proprio programma ffmpeg (o avconv) e ho visto quali opzioni gli sono state passate. È come mostrato di seguito:

/Applications/Free AVCHD to Mov.app/Contents/Resources/bin/com.geranium-soft.convert \
  -i /path/to/140710_Canon-00003.MTS \
  -map 0:0 -map 0:1 -c:a libfaac -vol 256 -b:a 128k -c:v copy \
  -sn -movflags faststart -threads 0 -pix_fmt yuv420p -y \
  /path/to/140710_Canon-00003.mov

Ho provato a passare le stesse opzioni (Estremamente uguale. Ho impostato il tipo di contenitore di output su MOV e ho rimosso anche l' -t 60interruttore.) Al programma ffmpeg e alla conversione. Ma il risultato è stato lo stesso riportato finora .

Comunque quella grande app ha risolto il mio problema su "Come posso convertire il file .MTS (AVCHD) in .mp4 senza ricodificare il flusso video H264?", Tranne "in .mp4" e "by ffmpeg". Ma sono ancora interessato al perché quell'app funziona bene, ma ffmpeg no.


Cosa intendi con "correttamente"? Forse rimuoverlo dal titolo. Vorrei aiutare ma non ho mai usato ffmpeg. Uso solo il codificatore multimediale degli strumenti di Adobe.
eLouai,

@eLouai Bene, ho corretto il titolo.
Kaorukobo,

Risposte:


8

Vedendo che nel testo della tua domanda hai iniziato a discutere di altre utilità, suppongo che non sei interessato a rimanere con ffmpeg, ma piuttosto a portare a termine il lavoro.

Nella mia esperienza con libav e MTS non ho avuto problemi con il framerate, i file vengono rimessi perfettamente a posto.

Ho appena tentato quanto segue con uno dei miei file:

avconv -i 00174.MTS -c:a copy -c:v copy 00174.mp4

Il file MP4 risultante è stato riprodotto correttamente con VLC.

Il mio file è MTS progressivo, non ho alcun layout interlacciato in giro, ma se necessario posso fare di più controllando con quello.

Rapporto sul test del file

L'antipasto di argomento è stato in grado di fornire un file, che è stato modificato da MTS a MP4 e non è stato riprodotto sul computer di quella persona con QuickTime Player (versione sconosciuta). Tuttavia, ha giocato con il lettore VLC di quell'individuo.

Non ho un computer Mac OS, ma l'ho provato con Ubuntu. L'ho giocato su Ubuntu su VLC (2.0.8) e GNOME Video (un tempo chiamato Totem) (3.8.2); entrambi giocano perfettamente.

Ho quindi chiesto a un mio amico, che è su un Mac, di giocarci. È su Mavericks (10.9.4) e ha giocato bene con QuickTime Player 10.3 (727.4).

In questo momento sembra essere un problema con il lettore particolare o un problema con le impostazioni di configurazione sul computer. Ed è probabilmente meglio tentare di aggiornare alla versione più recente di QTP, possibilmente rimuovendo prima la versione corrente e cancellando completamente la vecchia configurazione.

Un'altra possibilità

Quando ho avuto una vecchia macchina ho avuto alcuni file bitrate alti riprodotti in modo errato in alcuni lettori, ed era specifico del contenitore. Ad esempio, VLC rifiuta di riprodurre il file MTS, mostra un frame e mostra il successivo solo in un secondo e mezzo. I video di GNOME hanno giocato bene. Ma quando è stato modificato in MKV, entrambi i giocatori hanno giocato abbastanza bene. Questa forse è una domanda di qualcosa di simile. Un giocatore può forse leggere un particolare contenitore (in questo caso MP4) in un modo che richiede solo il tempo sufficiente della CPU, che inizia a soffocarsi. L'effetto jerkiness può quindi essere attribuito a qualunque sottoprocesso occupi la finitura della CPU e il giocatore scarica tutti i frame che erano in ritardo molto rapidamente, dopodiché il cattivo sottoprocesso inizia di nuovo e il ciclo continua.

In questa possibilità, l'opzione migliore è ancora provare ad aggiornare il software. Con gli attuali processori multicore sarebbe difficile testare la necessità di aggiornare l'hardware senza ottenerlo, ma forse è possibile esaminare il carico della CPU durante l'utilizzo di QuickTime Player e confrontarlo con VLC. Se vedi il 100% per ogni core con QTP, questo potrebbe essere indicativo.


È piuttosto improbabile che avconv faccia un lavoro diverso per lui. avconv è un fork di ffmpeg e ffmpeg sta unendo molti commit dal progetto avconv a ffmpeg, correzioni di bug importanti come questo sarebbero probabilmente presenti in ffmpeg.
PTS

@ProfessorSparkles Penso che il fatto che abbia funzionato qui sia un terreno sufficiente per credere diversamente. Aspetterò di vedere cosa dice kaorukobo.
v010dya,

@Volodya Grazie per le tue informazioni. Ho aggiunto il rapporto provando avconv alla mia domanda.
Kaorukobo,

@kaorukobo Che cosa intendi esattamente per "avere la cornice inquietante ripetutamente ripetutamente"? L'output si scuote o in qualche modo salta avanti e indietro?
v010dya,

@Volodya Penso che la tua espressione sia giusta. Vedere per credere. Ho caricato la Canon-00006.MTS.mp4 risultante su filedropper.com/canon-00006mts Se non ti dispiace, prova a riprodurre quel file con QuickTime Player (se hai Mac ...) non VLC.
Kaorukobo,

5

Secondo questo bug di ffmpeg

I pacchetti H.264 interlacciati vengono divisi causando MP4 STTS

durante il remuxing di un mpeg-ts contenente H.264 interlacciato in mp4, entrambi i campi di ciascun fotogramma video vengono suddivisi in pacchetti separati. Software come Mediainfo utilizza STTS per determinare la frequenza dei fotogrammi. Mostrerà come 50 fps anziché 25 fps

La mancata corrispondenza della frequenza dei fotogrammi qui riportata sembra essere il risultato di ffmpeg che combina flussi MP4 interlacciati secondo le specifiche, in base al quale ciascun campo è separato in un pacchetto. E quindi

"Il software che utilizza il conteggio dei campioni nel file MP4 per determinare la frequenza dei fotogrammi è semplicemente sbagliato." Commento 7

Ciò non verrà corretto poiché l'unione di coppie di campi in un'unità di accesso viola le specifiche MPEG-4 e quindi anche gli encoder che fanno lo stesso.

Nota che l'output combinato, come quello qui sotto, suona bene per me in Potplayer e VLC.

    ffmpeg version N-76741-g8eadabf Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 5.2.0 (GCC)

Input #0, mpegts, from '00007.MTS':
  Duration: 00:00:07.01, start: 1.033367, bitrate: 15935 kb/s
  Program 1 
    Stream #0:0[0x1011]: Video: h264 (High) (HDMV / 0x564D4448), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0:1[0x1100]: Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, 5.1(side), fltp, 448 kb/s
    Stream #0:2[0x1200]: Subtitle: hdmv_pgs_subtitle ([144][0][0][0] / 0x0090), 1920x1080
[mp4 @ 054cf020] Codec for stream 0 does not use global headers but container format requires global headers
Output #0, mp4, to '00007.MTS.mp4':
  Metadata:
    encoder         : Lavf57.16.100
    Stream #0:0: Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 29.97 fps, 29.97 tbr, 90k tbn, 90k tbc
    Stream #0:1: Audio: aac ([64][0][0][0] / 0x0040), 48000 Hz, 5.1(side), fltp, 128 kb/s
    Metadata:
      encoder         : Lavc57.15.100 aac
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (ac3 (native) -> aac (native))
Press [q] to stop, [?] for help
[mp4 @ 054cf020] Timestamps are unset in a packet for stream 0. This is deprecated and will stop working in the future. Fix your code to set the timestamps properly
[mp4 @ 054cf020] pts has no value
    Last message repeated 209 times
frame=  420 fps=0.0 q=-1.0 Lsize=   12478kB time=00:00:07.01 bitrate=14564.2kbits/s    
video:12458kB audio:6kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.111239%
[aac @ 052fd480] Qavg: 64863.176

4

È possibile provare a imporre la frequenza dei fotogrammi originale utilizzando -r 29.97. FFmpeg sta probabilmente provando a regolare il framerate per qualche motivo. La tua sintassi è altrimenti corretta e non dovrebbe produrre questo errore.

Per quanto riguarda la tua terza domanda. Semplicemente impossibile. È possibile omettere i frame quando si utilizzano codec che codificano i frame singolarmente, ma non è così con h264 ma anche con un codec tale si modifica comunque il flusso video in qualche modo. Lo stesso vale per aumentare la frequenza dei fotogrammi, devi aggiungere fotogrammi calcolati o duplicare alcuni fotogrammi.

Modifica: per quanto riguarda le informazioni aggiuntive dal commento qui sotto. Se devi modificare i dati scritti nell'intestazione del formato senza scrivere un file completamente nuovo, probabilmente vorrai farlo in un editor esadecimale. FFmpeg ha solo la possibilità di modificare i metadati che non includono i dati del flusso. Come e dove apportare le modifiche al file dipende dal formato del contenitore.

Un'altra opzione sarebbe quella di demuxare il contenitore e rimodellare il flusso video e audio in un nuovo contenitore con le opzioni specificate. Quanto puoi specificare di nuovo dipende dal formato del contenitore. Lo strumento MP4Box potrebbe essere di aiuto in questo caso, in questo caso è possibile specificare un framerate durante il muxing di flussi video non elaborati in un nuovo mp4 utilizzando la sintassi seguente:

MP4Box -add input.h264:fps=29.97 -new output.mp4

Grazie. Per quanto riguarda -t 60switch, è un'opzione per specificare non un framerate ma una durata di elaborazione ( $ ffmpeg -h|grep -- -t-> -t duration record or transcode "duration" seconds of audio/video)
kaorukobo

Oh giusto, quello era un codificatore diverso, scusami per quell'errore.
PTS

Vedi la mia modifica alla risposta.
PTS

Grazie ancora. Ho modificato la mia domanda per aggiungere il risultato provando il tuo consiglio. Sfortunatamente, il problema era ancora lì ...
Kaorukobo,

Per quanto riguarda la tua risposta alla mia terza domanda, va bene per il caso in cui mi piacerebbe cambiare il framerate del flusso video, non solo "valore". Tuttavia, nel mio caso, "set framerate/timebase values"significa semplicemente riscrivere i valori inseriti nell'intestazione del contenitore / codec-stream. Perché? Ci sono alcuni casi da affrontare: il caso in cui un codificatore (ad esempio il transcoder h264 di Apple Compressor) inietta un valore di timebase errato (tbc) nel flusso video e il caso come questa domanda che ffmpeg immette valori di framerate / timebase errati, che sono diverso da quelli dei file video originali.
Kaorukobo,

2

So che questa è una vecchia domanda, ma è appena spuntata di nuovo nel feed, quindi è nuova per me. (-:

Una cosa che non vedo menzionata è l'ordine dei campi. Questo è un file interlacciato, quindi è una considerazione. L'OP menziona i frame "fremiti avanti e indietro" che è sempre una bandiera per un ordine di campo errato. Se il video è altrimenti OK, tranne per il "fremito", prova ad aggiungere qualunque ffmpeg abbia bisogno di forzare "il primo campo in primo luogo", quindi il contrario se è ancora sbagliato. Non ho abbastanza familiarità con i dettagli di ffmpeg per dare le bandiere esatte per questo.


Voglio provare ad eseguire alcuni comandi ffmepg sulla tua risposta. Tuttavia, la mia versione 2.2.1 di ffmpeg non sembra avere opzioni che gestiscano l'ordine dei campi. Ho provato ffmpeg -h|egrep 'field|first'ma non mostra nulla. La versione precedente (0.8.6) di ffmpeg aveva -topun'opzione che poteva gestirla.
Kaorukobo,

@kaorukobo Internet offre questo: -vf "fieldorder = bff" o = tff dove t e b si riferiscono rispettivamente all'inizio e alla fine. L' opzione top = 1/0 è apparentemente utilizzata per cambiare l'ordine in cui i campi vengono letti, non scritti. Ancora una volta, utilizzo ffmpeg / avconv solo casualmente, quindi nessuna garanzia.
Jim Mack,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.