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

47

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?

Ana
la source

Réponses:

58

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
szatmary
la source
12
Vous pouvez aussi avoir besoin -bsf:a aac_adtstoasc.
Camilo Martin
1
intéressant de noter que la commande n'est PAS ffmpeg copy ..., elle est copy ...(sous Windows)
Ron Royston
26

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 rechercher avec des problèmes de lecture.

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 en principe créer un fichier .txt répertoriant tous les fichiers que vous souhaitez combiner de la sorte (dans lequel mon premier lien donne des instructions pour 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
Juan Aquino
la source
Cela for %i in (*.ts) done fonctionne pas correctement pour i> = 10. En dehors de cela, tout fonctionne, merci. En effet, il y avait des problèmes avec le fichier concaténé, sans parler du fait que le fichier créé avec votre méthode était 16% plus petit (j'avais 1400 parties par 400 ko).
utilisateur
@ utilisateur pour les nombres dans l'ordre, vous pouvez parcourir les nombres tels quefor i in {1..10}; do echo file \'$i.ts\' >> list.txt ; done
qwr
8

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.mp4une 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 le ffmpeg -i some.ts -c copy -bsf:a aac_adtstoasc some.mp4corrige.

7vujy0f0hy
la source
3
Obtenez un nouveau assez ffmpeget il va maintenant le faire automatiquement.
llogan
7

Mettre tous ensemble

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 de travail simple pour un shell Linux Bash 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
Francesco Galgani
la source
4

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 un répertoire
    • il contient la liste des chemins de fichiers relatifs à la playlist
  • -codec copy éviter l'encodage
  • le type de conteneur est important:
    • *.mp4 est bien, mais il semble peu lent à multiplexer lorsque la liste de lecture est extraite du Web
    • *.mkvou a *.tsfonctionné mieux pour moi
Vlastimil Ovčáčík
la source
2

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 que vous n'en avez 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.

Ragnarsson
la source
1

Vous pouvez utiliser ces fichiers ts vers ffmpeg et générer le fichier mp4.

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

ou Si votre nom de fichier n'est pas en ordre,

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

Kris Roofe
la source
0

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 lors de 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'
Douglas Daseeco
la source
En fait, lorsque j'ai essayé cela, il y avait un léger "bégaiement" entre les segments de la vidéo finale. Donc, au moins dans ce cas, cela a d'abord aidé à concaténer les fichiers TS.
Sphinxxx le