Use o codec de cópia ffmpeg para combinar arquivos * .ts em um único mp4


45

Eu tenho um monte de segmentos ts descritos por um único arquivo index.m3u8:

index.m3u8        
segment1_0_av.ts  
segment2_0_av.ts  
segment3_0_av.ts  
segment4_0_av.ts  
segment5_0_av.ts

Eu sei que todos eles são codificados da mesma maneira. O ffprobe me fornece o seguinte:

Input #0, mpegts, from 'segment1_0_av.ts':
  Duration: 00:00:10.00, start: 0.100511, bitrate: 1251 kb/s
  Program 1 
    Stream #0:0[0x100]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p, 960x540 [SAR 1:1 DAR 16:9], 12.50 fps, 25 tbr, 90k tbn, 25 tbc
    Stream #0:1[0x101]: Audio: aac ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp, 105 kb/s
    Stream #0:2[0x102]: Unknown: none ([21][0][0][0] / 0x0015)

Eu gostaria de combiná-los em um único recipiente mp4. Mas quando tento comandos como:

ffmpeg -f concat -i filelist.txt -c copy output.mp4

onde gera o arquivo filelist.txt a partir do arquivo index.m3u8, ele reclama de não conseguir ler vários arquivos. Mas converter os arquivos ts parece funcionar bem. Acho que não estou usando o ffmpeg corretamente.

Como uso o ffmpeg para combinar os arquivos ts descritos pelo index.m3u8 em um único contêiner mp4 usando o codec de cópia?

Respostas:


57

Não sei por que o ffmpeg está causando um erro. No entanto, ts é um dos poucos formatos que podem ser simplesmente concatenados. Então, quando você tiver um único ts, transmux para mp4.

Sob janelas:

copy /b segment1_0_av.ts+segment2_0_av.ts+segment3_0_av.ts all.ts
ffmpeg -i all.ts -acodec copy -vcodec copy all.mp4

No GNU / Linux, usando o bash:

cat segment1_0_av.ts segment2_0_av.ts segment3_0_av.ts > all.ts
ffmpeg -i all.ts -acodec copy -vcodec copy all.mp4

12
Você também pode precisar -bsf:a aac_adtstoasc.
Camilo Martin

1
interessante notar que o comando não é ffmpeg copy ..., é copy ...(no Windows)
Ron Royston

22

O uso de copy ou cat para combinar os arquivos, como a principal resposta atual do szatmary, pode deixar você com um arquivo que é muito além do limite e não pode procurar junto com problemas de reprodução.

Em vez disso, para combinar esses arquivos corretamente, use ffmpeg conforme as instruções em https://trac.ffmpeg.org/wiki/Concatenate . (Instale o ffmpeg aqui se você ainda não o possui https://github.com/adaptlearning/adapt_authoring/wiki/Installing-FFmpeg .)

Se você está com preguiça de ler meu primeiro link, basicamente precisa criar um arquivo .txt listando todos os arquivos que deseja combinar (o meu primeiro link fornece instruções sobre como fazê-lo facilmente) na pasta em que você ' está fazendo a concatenação:

file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

Aqui está uma cópia colada do meu primeiro link, de uma maneira, para criar um arquivo de texto, se você tiver o Windows na linha de comando, por exemplo, mas obviamente você pode criar o arquivo manualmente ou da forma que desejar:

(for %i in (*.ts) do @echo file '%i') > mylist.txt

Verifique se o seu arquivo .txt está bom e está formatado corretamente!

Depois disso, na linha de comando, execute:

ffmpeg -f concat -i mylist.txt -c copy all.ts

onde 'mylist.txt' é o arquivo .txt que você acabou de criar.

Verifique se o arquivo resultante reproduz o vídeo corretamente. A partir daqui, você pode transmitir para mp4 como de costume, se quiser:

ffmpeg -i all.ts -acodec copy -vcodec copy all.mp4

Isso for %i in (*.ts) donão classifica corretamente para i> = 10. Além disso, tudo funciona, obrigado. De fato, houve problemas com o arquivo concatenado, sem mencionar que o arquivo criado com o método acabou por ser 16% menor (eu tinha 1400 partes por 400kb).
usuário

8

2017 resposta

Mas quando tento comandos como ...esse, reclama de não conseguir ler vários arquivos.

Quando executo ffmpeg -i some.ts -c copy some.mp4um determinado vídeo, recebo esta mensagem de erro:

Malformed AAC bitstream detected: use the audio bitstream filter 
'aac_adtstoasc' to fix it ('-bsf:a aac_adtstoasc' option with ffmpeg)

av_interleaved_write_frame(): Operation not permitted

Não é de surpreender que a execução o ffmpeg -i some.ts -c copy -bsf:a aac_adtstoasc some.mp4conserte.


3
Obtenha um novo o suficiente ffmpege agora fará isso automaticamente.
Llogan 11/11

7

Juntando tudo

Usando a resposta de Juan Aquino (e corrigindo o primeiro comando para ser compatível com o Bash e usando a ordem natural dos arquivos), mais a resposta do 7vujy0f0hy, um script de trabalho simples para um shell do Linux Bash é:

#!/bin/bash
for i in `ls *.ts | sort -V`; do echo "file $i"; done >> mylist.txt
ffmpeg -f concat -i mylist.txt -c copy -bsf:a aac_adtstoasc video.mp4

4

A maneira correta de concaturar vários arquivos de vídeo da lista de reprodução m3u8 é

ffmpeg -i "index.m3u8" -codec copy output.mp4


  • a lista de reprodução m3u8 pode estar na web ou localmente no diretório
    • ele contém uma lista de caminhos de arquivo relativos à lista de reprodução
  • -codec copy para evitar codificação
  • o tipo de contêiner é importante:
    • *.mp4 é bom, mas parece um pouco lento para mux quando a lista de reprodução é obtida na web
    • *.mkvou *.tsfuncionou melhor para mim

2

Você pode fazer a concatenação simples assim (com bash):

for f in ./{0..<number>}.ts; do cat $f >> out.ts; done

Substitua <number>pelo número mais alto (obviamente). As variantes com ffmpeg não funcionaram corretamente. O arquivo de vídeo de saída gaguejava estranhamente.

Eu uso o loop for para garantir a ordem correta dos arquivos. Talvez você não precise disso. Talvez seja até possível canalizar a saída para ffmpeg e convertê-la para mp4 em tempo real.


0

Todas as respostas populares a esta pergunta que induzem os leitores a concatenar os arquivos TS antes de executar o ffmpeg estão incorretas. Para garantir que o áudio e o vídeo não fiquem fora de sincronia durante a montagem do fluxo mp4, o recurso "-f concat" mal documentado, mas importante, do ffmpeg deve ser usado.

    delimiterBeforeFileNumber="-"
    ls |egrep '[.]ts$' \
        |sort "-t$delimiterBeforeFileNumber" -k2,2n \
        |sed -r "s/(.*)/file '\1'/" >ts.files.txt

    ffmpeg -f concat -i ts.files.txt -c copy tsw.014.ts.mp4

As duas linhas de código preparatórias apenas criam um arquivo que contém uma lista de arquivos TS neste formato de linha:

    file 'seg-37-a.ts'

Na verdade, quando tentei isso, houve uma leve "gagueira" entre os segmentos no vídeo final. Portanto, pelo menos nesse caso, ajudou a concatenar os arquivos TS primeiro.
Sphinxxx 31/07

0

Você pode usar esses arquivos ts para ffmpeg e enviar o arquivo mp4.

cat *.ts | ffmpeg -i pipe: -c:a copy -c:v copy output.mp4

ou Se seu nome de arquivo não tiver ordem,

grep .*.ts index.m3u8 | xargs cat | ffmpeg -i pipe: -c:a copy -c:v copy output.mp4

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.