Como posso converter o arquivo .MTS (AVCHD) para .mp4 pelo ffmpeg sem recodificar o fluxo de vídeo H264?


20

Nota: Postei a mesma pergunta no stackoverflow pouco tempo antes, quando ainda não encontrei essa comunidade. Reposto isso, já que a pergunta é mais adequada para esta comunidade.

1. O que eu tentei

Tenho alguns arquivos .MTS (formato AVCHD) gravados com minha câmera AVCHD . Sua especificação é como mostrado abaixo:

$ 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

Preste atenção à parte da taxa de quadros / base de tempo: 29,97 fps, 29,97 tbr, 90k tbn, 59,94 tbc

Agora, eu gostaria de converter esse arquivo em arquivo .mp4, sem recodificar o fluxo de vídeo H264 , por outro lado, com a transcodificação do fluxo de áudio em AAC . Então, eu tentei o seguinte comando:

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

2. Resultado

e a especificação do arquivo de saída é mostrada abaixo:

$ 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

Veja a parte da taxa de quadros / base de tempo: 59,94 fps, 59,94 tbr, 90k tbn, 59,94 tbc . Embora o ffmpeg tenha copiado o fluxo de vídeo, a taxa de quadros e a base de tempo foram alteradas para o valor duas vezes .

Portanto, quando abro e reproduzo o arquivo de saída com o QuickTime Player ou VLC Player, o áudio não tem problema; no entanto, o fluxo de vídeo não é reproduzido corretamente. O vídeo é reproduzido com o quadro para frente e para trás tremendo repetidamente.

3. Pergunta

  1. Como posso converter o arquivo .MTS (AVCHD) para .mp4 pelo ffmpeg sem recodificar o fluxo de vídeo H264 corretamente ?
  2. Como posso manter os valores originais da taxa de quadros / base de tempo (fps / tbr / tbn / tbc) ao converter o contêiner com ffmpege seu -vcodec copycomutador.
  3. Como definir valores de framerate / timebase (fps / tbr / tbn / tbc) pelas opções de linha de comando do ffmpeg sem recodificar um fluxo de vídeo.

Alguma ideia?


4. Adicionando -r 29.97opção

O professor Sparkles me deu um conselho a acrescentar -r 29.97. Eu tentei isso:

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

No entanto, o arquivo de saída ainda possui taxa de quadros / timebase incorretas:

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

Eu tentei desmembrar e remux usando o MP4Box, de acordo com o conselho do 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 a saída foi:

$ 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)

Parece um pequeno passo à frente. Veja a parte da taxa de quadros / base de tempo: 29,97 fps, 29,97 tbr, 30k tbn, 59,94 tbc . Esses são correspondentes ao fluxo original, exceto portbn (valor da base de tempo do contêiner).

No entanto, quando reproduzo o arquivo de saída com o Quicktime Player ou VLC, o vídeo é reproduzido na metade da velocidade .

Embora o arquivo original tenha 90k tbn(90000 ticks por segundo) e o novo arquivo de saída da MP4Box possua 30k tbnapenas um terço do valor do original, o arquivo de saída é reproduzido na metade da velocidade.

Não sei o motivo. Mas acho que o resto é como posso ajustar o tbnvalor.


5-b. Relatório do MediaInfo no arquivo de saída

Eu também tentei a ferramenta MediaInfo no arquivo de saída gerado pelo 5. Remux usando o MP4Box . A saída está aqui: https://gist.github.com/kaorukobo/c5ab9eaa413dff6cd26a


6. Tentando avconv

Volodya relatou que avconvfuncionou bem. Também preparei um pequeno arquivo de filme de amostra (Canon-00006.MTS) gravado com a mesma câmera. Ok, vamos tentar:

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

As informações ffprobe do arquivo de saída estão aqui: https://gist.github.com/kaorukobo/5b53244ade2632ff1211 e suas informações de taxa de quadros / base de tempo são as seguintes: 59,94 fps, 59,94 tbr, 90k tbn, 59,94 tbc

O arquivo de saída foi reproduzido bem com o VLC Player, como Volodya relatou. No entanto, ao abri-lo com o Quicktime Player X, o vídeo foi reproduzido na velocidade normal, mas com o quadro para trás tremendo repetidamente.


7. Por que o aplicativo "Free AVCHD to MOV" funciona?

Como mencionei no meu comentário anterior , o recurso "rewrap to MOV" do aplicativo Free AVCHD to MOV funcionou bem, mesmo que não faça MP4, mas MOV.

O software chama seu próprio programa ffmpeg (ou avconv) internamente, e vi quais opções são passadas para ele. É como mostrado abaixo:

/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

Eu tentei passar as mesmas opções (Exatamente o mesmo. Defino o tipo de contêiner de saída como MOV e removi o -t 60interruptor uniforme .) Para o programa ffmpeg e a conversão. Mas o resultado foi o mesmo relatado até agora .

De qualquer forma, esse ótimo aplicativo resolveu meu problema em "Como posso converter o arquivo .MTS (AVCHD) para .mp4 sem recodificar o fluxo de vídeo H264?", Exceto em "para .mp4" e "por ffmpeg". Mas ainda estou interessado em saber por que esse aplicativo funciona bem, mas o ffmpeg não.


O que você quer dizer com "corretamente"? Talvez remova isso do título. Gostaria de ajudar, mas nunca usei o ffmpeg. Eu apenas uso o codificador de mídia do adobe tools.
eLouai

@eLouai Tudo bem, eu fixei o título.
kaorukobo

Respostas:


8

Vendo que no texto da sua pergunta você começou a discutir outros utilitários, assumirei que você não está interessado em continuar com o ffmpeg, mas em realizar o trabalho.

Na minha experiência com libav e MTS, não tive problemas com o framerate, os arquivos são remuxados perfeitamente.

Acabei de tentar o seguinte com um dos meus arquivos:

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

O arquivo MP4 resultante foi reproduzido corretamente com o VLC.

Meu arquivo é MTS progressivo, não tenho nenhum entrelaçado, mas, se necessário, posso fazer mais verificações com isso.

Relatório sobre o teste do arquivo

O iniciador de tópicos conseguiu fornecer um arquivo que foi remuxado do MTS para MP4 e não foi reproduzido na máquina dessa pessoa com o QuickTime Player (versão desconhecida). No entanto, jogou com o player VLC desse indivíduo.

Não tenho um computador com Mac OS, mas tentei com o Ubuntu. Eu o joguei no Ubuntu no VLC (2.0.8) e no GNOME Videos (costumava ser chamado de Totem) (3.8.2); ambos jogam perfeitamente.

Pedi a um amigo meu, que está em um Mac, para reproduzi-lo. Ele está no Mavericks (10.9.4) e jogou bem com o QuickTime Player 10.3 (727.4).

Neste momento, parece haver um problema com o reprodutor específico ou um problema com as definições de configuração no computador. E provavelmente é melhor tentar atualizar para a versão mais recente do QTP, possivelmente removendo a versão atual e limpando completamente a configuração antiga.

Outra possibilidade

Quando tenho uma máquina antiga, alguns arquivos com alta taxa de bits são reproduzidos incorretamente em alguns players, e era específico do contêiner. Por exemplo, o VLC se recusaria a reproduzir o arquivo MTS, mostraria um quadro e mostraria o próximo apenas em um segundo e meio. Os vídeos do GNOME foram excelentes. Mas ao remuxá-lo para o MKV, os dois jogadores jogaram razoavelmente bem. Talvez isso seja uma questão de algo semelhante. Um jogador talvez esteja lendo um contêiner em particular (MP4 neste caso) de uma maneira que exija apenas o tempo de CPU suficiente para começar a se sufocar. O efeito de jerkiness pode ser atribuído a qualquer subprocesso que ocorra na conclusão da CPU, e o jogador despeja todos os quadros atrasados ​​muito rapidamente, depois que o subprocesso ruim entra em ação novamente e o ciclo continua.

Nesta possibilidade, a melhor opção ainda é tentar atualizar o software. Com os processadores multicore atuais, seria difícil testar a necessidade de atualizar o hardware sem realmente obtê-lo, mas talvez seja possível observar a carga da CPU durante o uso do QuickTime Player e compará-la com o VLC. Se você vir 100% para qualquer núcleo com QTP, isso talvez seja indicativo.


É bastante improvável que o avconv faça um trabalho diferente para ele. avconv é um fork do ffmpeg e o ffmpeg está mesclando muitos commits do projeto avconv no ffmpeg, grandes correções de bugs como essa provavelmente estariam presentes no ffmpeg.
PTS

@ProfessorSparkles Acho que o fato de ter funcionado aqui é motivo suficiente para acreditar no contrário. Vou esperar para ver o que Kaorukobo diz.
v010dya

@Volodya Obrigado pela sua informação. Eu adicionei o relatório tentando avconv à minha pergunta.
kaorukobo

@kaorukobo O que exatamente você quer dizer com "ter sua estrutura para trás tremendo repetidamente"? A saída treme ou de alguma forma salta para frente e para trás?
v010dya

@ Volodya Acho que sua expressão está certa. Ver é crer. Carreguei o Canon-00006.MTS.mp4 resultante para filedropper.com/canon-00006mts Se você não se importa, tente reproduzir esse arquivo com o QuickTime Player (se você tiver Mac ...) e não o VLC.
precisa saber é o seguinte

5

De acordo com este bug ffmpeg

Pacotes entrelaçados H.264 são divididos causando MP4 STTS

ao remuxar um mpeg-ts contendo H.264 entrelaçado em mp4, os dois campos de cada quadro de vídeo são divididos em pacotes separados. Softwares como o Mediainfo usam o STTS para determinar a taxa de quadros. Ele será exibido como 50fps em vez de 25fps

A incompatibilidade da taxa de quadros relatada aqui parece ser o resultado de fluxos MP4 entrelaçados de ffmpeg muxing de acordo com a especificação, conforme a qual, cada campo é separado em um pacote. E assim

"o software que usa a contagem de amostras no arquivo MP4 para determinar a taxa de quadros está simplesmente errado." Comentário 7

Isso não será corrigido porque a fusão de pares de campos em uma unidade de acesso viola a especificação MPEG-4 e, portanto, o mesmo ocorre com os codificadores que fazem o mesmo.

Observe que a saída muxed, como a abaixo, funciona bem para mim no Potplayer e no 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

Você pode tentar aplicar a taxa de quadros original usando -r 29.97. O FFmpeg provavelmente está tentando ajustar a taxa de quadros por algum motivo. Caso contrário, sua sintaxe está correta e não deve produzir esse erro.

Em relação à sua terceira pergunta. Simplesmente não é possível. Você pode omitir quadros ao usar codecs que codificam quadros individualmente, mas esse não é o caso do h264, mas mesmo com esse codec, você ainda modifica o fluxo de vídeo de alguma maneira. O mesmo vale para o aumento da taxa de quadros, você precisa adicionar quadros calculados ou duplicar alguns quadros.

Editar: em relação às informações adicionais do comentário abaixo. Se você precisar alterar os dados gravados no cabeçalho do formato sem gravar um arquivo completamente novo, provavelmente desejará fazer isso em um editor hexadecimal. O FFmpeg só tem opção para alterar os metadados que não incluem os dados do fluxo. Como e onde fazer suas alterações no arquivo depende do formato do contêiner.

Outra opção seria desmontar o contêiner e remuxar o fluxo de vídeo e áudio em um novo contêiner com as opções especificadas. Quanto você pode especificar novamente depende do formato do contêiner. A ferramenta MP4Box pode ajudar, neste caso, você pode especificar uma taxa de quadros ao colocar os fluxos de vídeo bruto em um novo mp4 usando a seguinte sintaxe:

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

Obrigado. Em relação à -t 60mudança, é uma opção para especificar não um framerate mas a duração de processamento ( $ ffmpeg -h|grep -- -t-> -t duration record or transcode "duration" seconds of audio/video)
kaorukobo

Ah, certo, esse era um codificador diferente, desculpe por esse erro.
PTS

Veja minha edição para a resposta.
PTS

Obrigado novamente. Editei minha pergunta para adicionar o resultado, tentando o seu conselho. Infelizmente, o problema ainda estava lá ..
kaorukobo

Em relação à sua resposta à minha terceira pergunta, tudo bem no caso em que eu gostaria de alterar a taxa de quadros do fluxo de vídeo, não apenas "valor". No entanto, no meu caso, "set framerate/timebase values"significa apenas reescrever valores colocados no cabeçalho do container / codec-stream. Por quê? Há alguns casos a serem resolvidos: o caso em que algum codificador (por exemplo, o transcodificador h264 da Apple Compressor) injeta um valor incorreto da base de tempo (tbc) no fluxo de vídeo, e o caso como esta pergunta que ffmpeg injeta valores de framerate / base de tempo incorretos, que são diferente dos arquivos de vídeo originais.
kaorukobo

2

Sei que essa é uma pergunta antiga, mas ela apareceu novamente no feed, por isso é nova para mim. (-:

Uma coisa que não vejo mencionada é a ordem dos campos. Este é um arquivo entrelaçado, então é uma consideração. O OP menciona os quadros "tremendo para frente e para trás", que é sempre um sinalizador para a ordem incorreta do campo. Se o vídeo estiver bom, exceto pelo 'tremor', tente adicionar o que o ffmpeg precisar para forçar o "primeiro campo primeiro" e, em seguida, o contrário, se ainda estiver errado. Não estou familiarizado o suficiente com os detalhes do ffmpeg para fornecer as sinalizações exatas para isso.


Quero tentar executar alguns comandos ffmepg na sua resposta. No entanto, minha versão 2.2.1 do ffmpeg parece não ter opções que lidam com a ordem dos campos. Eu tentei, ffmpeg -h|egrep 'field|first'mas não mostra nada. A versão anterior (0.8.6) do ffmpeg tinha uma -topopção que pode lidar com isso.
precisa saber é o seguinte

@kaorukobo a Internet oferece este: -VF "fieldorder = bff" ou = TFF onde a t e b referem-se a parte superior e inferior, respectivamente. A opção top = 1/0 é aparentemente usada para alterar a ordem na qual os campos são lidos, não gravados. Novamente, eu uso o ffmpeg / avconv apenas casualmente, portanto não há garantias.
Jim Mack
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.