Використовуйте ffmpeg копіювальний кодек, щоб об'єднати * .ts файли в один mp4


47

У мене є купа сегментів, описаних одним файлом index.m3u8:

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

Я знаю, що всі вони закодовані однаково. ffprobe дає мені таке:

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)

Я хотів би об'єднати їх в один контейнер mp4. Але коли я пробую такі команди, як:

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

де генерує файл filelist.txt з файлу index.m3u8, він скаржиться на неможливість читання різних файлів. Але перетворення файлів TS, здається, працює добре. Я думаю, що я не використовую ffmpeg належним чином.

Як я можу використовувати ffmpeg для об'єднання файлів TS, описаних index.m3u8, в один контейнер mp4 за допомогою кодека копіювання?

Відповіді:


58

Я не впевнений, чому ffmpeg видає вам помилку. Однак ts є одним з небагатьох форматів, який можна просто об'єднати. Потім, як тільки у вас є один ts, перетворіть на mp4.

Під вікнами:

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

Під GNU / Linux, використовуючи 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
Можливо, вам також знадобиться -bsf:a aac_adtstoasc.
Каміло Мартін

1
Цікаво зазначити, що команда НЕ ffmpeg copy ..., це copy ...(під Windows)
Рон Ройстон

25

Використання копії чи кота для комбінування файлів, таких як поточна відповідь szatmary, може залишити вас файлом, який відтворює далеко за ліміт і не може шукати разом із проблемами відтворення.

Натомість для комбінування цих файлів належним чином використовуйте ffmpeg згідно інструкцій на https://trac.ffmpeg.org/wiki/Concatenate . (Встановіть ffmpeg тут, якщо у вас його ще немає https://github.com/adaptlearning/adapt_authoring/wiki/Installing-FFmpeg .)

Якщо ви лінуєтеся прочитати моє перше посилання, вам, як правило, потрібно створити .txt файл із переліком усіх файлів, які ви хочете об'єднати так (який мій перший посилання дає вказівки, як це зробити легко) у папці, де ви ' робиш конкатенацію:

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

Ось папка для копіювання з мого першого посилання про один спосіб створення текстового файлу, якщо у вас є, наприклад, Windows в командному рядку, але очевидно, ви можете зробити файл вручну або як би ви хочете:

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

Переконайтесь, що ваш .txt файл добре виглядає та правильно відформатований!

Після цього в командному рядку запустіть:

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

де "mylist.txt" - файл .txt, який ви тільки що створили.

Перевірте, чи отриманий файл відтворює відео правильно. Звідси ви можете перетворити на mp4 як завжди, якщо вам подобається:

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

Це for %i in (*.ts) doне сортується правильно для i> = 10. Крім того, все працює, дякую. Дійсно, були проблеми з об'єднаним файлом, не кажучи вже про те, що файл, зроблений вашим методом, виявився на 16% меншим (у мене було 1400 частин на 400 кбіт).
користувач

@user для чисел, щоб ви могли перебирати цифри на зразокfor i in {1..10}; do echo file \'$i.ts\' >> list.txt ; done
qwr

8

Відповідь 2017 року

Але коли я намагаюся виконувати такі команди ..., він скаржиться на неможливість читання різних файлів.

Коли я виконую ffmpeg -i some.ts -c copy some.mp4певне відео, я отримую це повідомлення про помилку:

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

Не дивно, що виконання ffmpeg -i some.ts -c copy -bsf:a aac_adtstoasc some.mp4його виправляє.


3
Отримайте достатньо нового, ffmpegі тепер це буде зроблено автоматично.
логіан

7

Збираємо всіх разом

Використовуючи відповідь Хуана Аквіно (і виправляючи першу команду на сумісність з Bash та використовуючи природне впорядкування файлів), а також відповідь 7vujy0f0hy, простим робочим сценарієм для оболонки 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

Правильний спосіб сформувати декілька відеофайлів із списку відтворення m3u8

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


  • плейлист m3u8 може бути в Інтернеті або локально в каталозі
    • він містить список шляхів до файлів відносно списку відтворення
  • -codec copy щоб уникнути кодування
  • Тип контейнера має значення:
    • *.mp4 це добре, але, здається, мало повільно муксує, коли список відтворення вибирається з Інтернету
    • *.mkvабо *.tsпрацював найкраще для мене

2

Ви можете зробити поєднувальний простий так (з bash):

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

Замініть <number>на найбільшу кількість (очевидно). Варіанти з ffmpeg не працювали належним чином. Вихідний відеофайл дивно заїкається.

Я використовую цикл for, щоб забезпечити правильний порядок файлів. Можливо, вам це не потрібно. Можливо, можливо навіть передати вихід на ffmpeg і перетворити його на mp4 на льоту.


1

Ви можете скористатися цими файлами ts для ffmpeg та вивести файл mp4.

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

або Якщо у вас ім'я файлу не має порядку,

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


0

Усі популярні відповіді на це запитання, які вводять в оману читачів для об'єднання файлів TS перед запуском ffmpeg, є невірними. Щоб аудіо та відео не випадали з синхронізації під час збирання потоку mp4, слід використовувати неякісно задокументовану, але важливу особливість ffmpeg "-f concat".

    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

Два підготовчих рядки коду просто створюють файл, що містить перелік TS-файлів у такому форматі рядка:

    file 'seg-37-a.ts'

Насправді, коли я це спробував, між сегментами у фінальному відео було незначне «заїкання». Так, принаймні, в одному випадку це допомогло спочатку об'єднати файли TS.
Sphinxxx
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.