web-dev-qa-db-fra.com

Utilisez le codec de copie ffmpeg pour combiner des fichiers * .ts en un seul fichier mp4

J'ai un tas de segments ts décrits par un seul fichier index.m3u8:

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

Je sais qu'ils sont tous codés de la même manière. ffprobe me donne ce qui suit:

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)

Je voudrais les combiner dans un seul conteneur MP4. Mais quand j'essaye des commandes comme:

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

là où il génère le fichier filelist.txt à partir du fichier index.m3u8, il se plaint de ne pas pouvoir lire différents fichiers. Mais convertir les fichiers ts eux-mêmes semble bien fonctionner. Je pense que je n'utilise pas ffmpeg correctement.

Comment utiliser ffmpeg pour combiner les fichiers ts décrits par index.m3u8 dans un seul conteneur mp4 à l'aide du codec de copie?

39
Ana

Je ne suis pas sûr de savoir pourquoi ffmpeg vous donne une erreur. Cependant, ts est l’un des rares formats pouvant être simplement concaténés. Ensuite, une fois que vous avez un seul ts, transmux en MP4.

Sous les fenêtres:

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

Sous GNU/Linux, en utilisant 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
53
szatmary

Utiliser copy ou cat pour combiner les fichiers comme la réponse principale actuelle de szatmary peut vous laisser avec un fichier lu bien au-delà de la limite et ne pouvant pas chercher avec des problèmes de lecture.

Au lieu de cela, pour combiner correctement ces fichiers, utilisez ffmpeg comme indiqué dans https://trac.ffmpeg.org/wiki/Concatenate . (Installez ffmpeg ici si vous ne l'avez pas déjà https://github.com/adaptlearning/adapt_authoring/wiki/Installing-FFmpeg .)

Si vous êtes trop paresseux pour lire mon premier lien, vous devez créer un fichier .txt répertoriant tous les fichiers que vous souhaitez combiner de la sorte (dans lequel mon premier lien explique comment le faire facilement) dans le dossier où vous ' faire la concaténation:

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

Voici un copier/coller de mon premier lien pour créer un fichier texte si vous avez Windows en ligne de commande, par exemple, mais vous pouvez évidemment créer le fichier manuellement ou comme vous le souhaitez:

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

Vérifiez que votre fichier .txt est correct et qu'il est correctement formaté!

Après cela, en ligne de commande, lancez:

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

où 'mylist.txt' est le fichier .txt que vous venez de créer.

Vérifiez si le fichier résultant lit correctement la vidéo. De là, vous pouvez transmux en mp4 comme d'habitude si vous aimez:

ffmpeg -i all.ts -acodec copy -vcodec copy all.mp4
21
Juan Aquino

Réponse 2017

Mais lorsque j'essaie des commandes comme ..., il se plaint de ne pas pouvoir lire divers fichiers.

Lorsque j'exécute ffmpeg -i some.ts -c copy some.mp4 sur une certaine vidéo, le message d'erreur suivant s'affiche:

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

Sans surprise, l'exécution de ffmpeg -i some.ts -c copy -bsf:a aac_adtstoasc some.mp4 le corrige.

6
7vujy0f0hy

Assembler tous les éléments

En utilisant la réponse de Juan Aquino (et en corrigeant la première commande pour qu'elle soit compatible avec Bash et en utilisant l'ordre naturel des fichiers), ainsi que la réponse de 7vujy0f0hy, un script simple pour un shell Bash Linux est:

#!/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
Francesco Galgani

La bonne façon de concaténer plusieurs fichiers vidéo de la playlist m3u8 est la suivante:

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


  • la playlist m3u8 peut être sur le Web ou localement dans le répertoire
    • il contient la liste des chemins de fichiers relatifs à la playlist
  • -codec copy pour éviter l'encodage
  • le type de conteneur est important:
    • *.mp4 est correct mais cela semble un peu lent à multiplexer lorsque la liste de lecture est extraite du Web
    • *.mkv ou *.ts a fonctionné mieux pour moi
3

Vous pouvez faire la concaténation simple comme ceci (avec bash):

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

Remplacez <number> par le nombre le plus élevé (évidemment). Les variantes avec ffmpeg ne fonctionnaient pas correctement. Le fichier vidéo en sortie bégaitait étrangement.

J'utilise la boucle for pour assurer le bon ordre des fichiers. Peut-être n'en avez-vous pas besoin. Peut-être qu’il est même possible de diriger la sortie vers ffmpeg et de la convertir en mp4 à la volée.

2
ragnarsson

Toutes les réponses populaires à cette question qui induisent les lecteurs en erreur pour concaténer les fichiers TS avant d'exécuter ffmpeg sont incorrectes. Pour vous assurer que l'audio et la vidéo ne sont pas désynchronisés pendant l'assemblage du flux mp4, vous devez utiliser la fonctionnalité "-f concat" mal documentée mais importante de ffmpeg.

    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

Les deux lignes de code préparatoires créent simplement un fichier contenant une liste de fichiers TS dans ce format de ligne:

    file 'seg-37-a.ts'
0
Douglas Daseeco