Присоединяйтесь к mp4 файлам в Linux

37425
Jose Armando

Я хочу объединить два файла mp4, чтобы создать один. Видеопотоки кодируются в h264, а аудио - в aac. Я не могу перекодировать видео в другой формат по вычислительным причинам. Кроме того, я не могу использовать какие-либо программы с графическим интерфейсом, вся обработка должна выполняться с помощью утилит командной строки Linux. FFmpeg не может сделать это для файлов mpeg4, поэтому вместо этого я использовал MP4Box:

MP4Box -add video1.mp4 -cat video2.mp4 newvideo.mp4 

К сожалению, звук все перепутал. Я думал, что проблема была в том, что звук был в aac, поэтому я перекодировал его в mp3 и снова использовал MP4Box. В этом случае звук подходит для первой половины newvideo.mp4(соответствует video1.mp4), но затем звук отсутствует, и я не могу перемещаться по видео также.

Моей следующей мыслью было то, что аудио и видео потоки имели небольшие несоответствия в их длине, которые я должен исправить. Поэтому для каждого входного видео я разделял видео и аудио потоки, а затем соединял их с опцией -shortest в FFmpeg.

Таким образом, для первого видео я запустил:

 avconv -y -i video1.mp4 -c copy -map 0:0 videostream1.mp4 avconv -y -i video1.mp4 -c copy -map 0:1 audiostream1.m4a avconv -y -i videostream1.mp4 -i audiostream1.m4a -c copy -shortest video1_aligned.mp4 

Аналогично для второго видео затем использовали MP4Box, как и ранее. К сожалению, это тоже не сработало. Единственный успех, который у меня был, - это когда я отдельно соединял видеопотоки (т.е. videostream1.mp4 и videostream2.mp4) и аудиопотоки (то есть audiostream1.m4a и audiostream2.m4a), а затем соединял видео и аудио в конечном файле. Однако синхронизация теряется для второй половины видео. Конкретно, есть задержка аудио и видео на 1 секунду. Любые предложения действительно приветствуются.

26
«FFmpeg не может сделать это для файлов mpeg4, поэтому вместо этого я использовал MP4Box» Вы имеете в виду файл MP4? оба аудио-видео потока используют одинаковые параметры кодирования (ширина, высота, SPS, PPS, частота кадров, частота дискретизации, количество каналов? 11 лет назад 0
используя ffprobe я вижу, что аудиопотоки имеют идентичные атрибуты. Видеопотоки имеют одинаковые размеры, но разные скорости. Для 1-го видео Видео: h264, 720x592, 277 кбит / с, PAR 18944: 12915 DAR 512: 287, 24,97 кадров в секунду, 45 КБ, 90 КБ, 90 Кбит / с, а для второго видео: h264, 720 × 592, 226 КБ / с, PAR 481: 330 DAR 39:22, 24,91 кадр / с, 45 тыс. Тбр, 90 тыс. Тбн, 90 тыс. Тбит / с. Вы верите, что это источник моих проблем? 11 лет назад 0
попробуйте это http://stackoverflow.com/questions/5415006/ffmpeg-combine-merge-multiple-mp4-videos-not-working daya 11 лет назад 0
На ваш вопрос уже есть ответы в ffmpeg FAQ: http://www.ffmpeg.org/faq.html#How-can-I-join-video-files_003f Palec 10 лет назад 0
MP4 поддерживает объединение видео / аудио с разными характеристиками, используя разные дорожки для разных видео, но плеер не настолько умен. rajneesh 11 лет назад 0
просто любите те перенесенные вопросы, которые позже получили не перенесенные дубликаты: http://stackoverflow.com/questions/18552901/how-to-merge-videos-by-avconv Ciro Santilli 新疆改造中心 六四事件 法轮功 8 лет назад 0

6 ответов на вопрос

24
evilsoup

Лучший способ сделать это в настоящее время - использовать демоверсию concat . Сначала создайте файл с именем inputs.txtотформатированный так:

file '/path/to/input1.mp4' file '/path/to/input2.mp4' file '/path/to/input3.mp4' 

Затем просто запустите эту команду ffmpeg:

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

Смотрите также объединение в ffmpegFAQ .


Я оставляю здесь следующее для пользы тех, кто использует более старые версии ffmpeg.

Последние версии ffmpeg могут сделать это: сначала вам нужно будет смешать файлы в транспортные потоки mpeg (достаточно легкие для процессора, так как это только меняет формат контейнера):

ffmpeg -i input.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb middle.ts 

Если это выдает ошибку о h264, вам может потребоваться использовать:

ffmpeg -i input.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb middle.ts 

Вам придется делать это отдельно с каждым входным файлом. Чтобы объединить файлы вместе, используйте:

ffmpeg -i "concat:middle1.ts|middle2.ts|middle3.ts" -c copy output.mp4 

Если это выдает ошибку о AAC, возможно, вам придется использовать

ffmpeg -i "concat:middle1.ts|middle2.ts|middle3.ts" -c copy -absf aac_adtstoasc output.mp4 

Если ваша система поддерживает именованные каналы, вы можете сделать это без создания промежуточных файлов.

mkfifo temp0 temp1 

Вам нужно будет сделать следующее в трех отдельных виртуальных терминалах:

ffmpeg -i input0.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb -y temp0 ffmpeg -i input1.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb -y temp1 ffmpeg -f mpegts -i "concat:temp0|temp1" -c copy -absf aac_adtstoasc output.mp4 

Если output.mp4 уже существует, третий ffmpeg спросит вас, хотите ли вы перезаписать его, но он сделает это после того, как получит доступ к FIFO, и это приведет к первому закрытию ffmpegs. Поэтому убедитесь, что вы выбрали неиспользуемое имя для выходного файла.

Это может не сработать, если ваши входные файлы отличаются - я считаю, что различия в битрейте в порядке, но размер кадра, частота кадров и т. Д. Должны совпадать.

много спасибо друг, работал как шарм Jose Armando 11 лет назад 0
@DaveJarvis Не так; Это сообщение было преднамеренно и злонамеренно распространено командой libav, которая является группой разработчиков, которые отделились от проекта ffmpeg для разработки avconv (и изменили имя, потому что не смогли защитить авторские права на имя ffmpeg). См. [Кто может подсказать мне разницу между ffmpeg, libav и avconv?] (Http://stackoverflow.com/questions/9477115/who-can-tell-me-the-difference-and-relation-between- ffmpeg-libav-and-avconv) для получения дополнительной информации. evilsoup 10 лет назад 2
`*** ЭТА ПРОГРАММА УСТАРЕЛА *** Эта программа предназначена только для совместимости и будет удалена в будущем выпуске. Пожалуйста, используйте вместо этого avconv. Это сообщение, которое я вижу сейчас при запуске `ffmpeg` Lord Loh. 10 лет назад 2
@LordLoh. Смотрите ссылку в моем предыдущем комментарии. evilsoup 10 лет назад 0
Этот ответ не отвечает - как объединить mp4 с `avconv` Lord Loh. 10 лет назад 1
Скомпилированный ffmpeg 2.2, как в этом видео: http://youtu.be/MRrGNIuLJ40, а затем все работает отлично, используя параметры "-f concat -i inputfiles". +1 qed 10 лет назад 0
Это также работает для файлов MKV. colton7909 8 лет назад 0
7
Philippe Gachoud

Для mp4 единственное рабочее решение, которое я нашел, было с MP4Box из пакета gpac

#!/bin/bash filesList="" for file in $(ls *.mp4|sort -n);do filesList="$filesList -cat $file" done MP4Box $filesList -new merged_files_$(date +%Y%m%d_%H%M%S).mp4 

или команда

MP4Box -cat file1.mp4 -cat file2.mp4 -new mergedFile.mp4 

с mencoder и avconv я не могу заставить его работать :-(

2
Mark

Thanks for the script dvo. It was a great starting point for me. I had no problem with using named pipes so I adapted the script to use them instead. Plus I fixed it to work with filenames with spaces in them. Output to named pipes does not "go" until you begin reading from them, hence the need to background the initial remux tasks with an & before the final call to avconv. Plus, don't forget to use -c copy, or you end up re-encoding the whole lot.

#!/bin/bash for FILE in "$@"; do TAG=$(echo "$FILE" | sed -e s/[^A-Za-z0-9.]/_/g) mkfifo $TAG.mp4concatpipe avconv -loglevel "quiet" -i "$FILE" -f mpegts -c copy -bsf h264_mp4toannexb -y $TAG.mp4concatpipe & IN=$IN\|$TAG.fifo done IN=$ avconv -i concat:$IN -c copy out.mp4 rm *.mp4concatpipe 
По какой-то причине это выдает мне сообщение «concat: first.m4v.fifo | second.m4v.fifo: нет такого файла или каталога» ошибка .. даже с кавычками (-i concat: "$ IN" или -i "concat: $ IN "). MP4Box, предложенный в другом ответе ниже, прекрасно работает! vorburger 10 лет назад 0
2
Robert Cole

На Mac (macOS 10.13 High Sierra) я успешно использовал следующее:

for f in *.m4a; do echo "file '$f'" >> mylist.txt; done 

При необходимости измените порядок так же, как указано выше (обратите внимание, что ./ был удален - путь заставлял ffmpeg выдавать ошибку небезопасного имени файла).

Затем мне пришлось удалить кодек и битрейт, указанные для fPmpeg MacPorts по умолчанию, чтобы он мне понравился:

ffmpeg -f concat -i mylist.txt output.m4a 
Добро пожаловать в Super User! Пожалуйста, внимательно прочитайте вопрос. Ваш ответ не отвечает на первоначальный вопрос о Linux. Если вы считаете, что он будет работать на Linux, добавьте, чтобы у будущих читателей было четкое понимание, кроме этого, снова добро пожаловать в superuser и спасибо за ваш вклад. Пожалуйста, уделите пару минут прочтению: - http://superuser.com/help. Ответ: http://superuser.com/help/how-to-answer. mic84 6 лет назад 0
1
dvo

Спасибо зла Вот небольшой скрипт для автоматизации процесса, использующий более свежие avconv.
Кстати, именованные каналы у меня не сработали (вывод на них застрял).

 #!/bin/bash  for FILE in $@; do avconv -i $FILE -map 0 -f mpegts -bsf h264_mp4toannexb -c:v copy -y $FILE.tmp IN=$IN\|$FILE.tmp done  IN=$ avconv -i concat:"$IN" out.mp4  for FILE in $@; do rm $FILE.tmp done 
0
Benjamin

Пользовались большим успехом с

for f in ./*.m4a; do echo "file '$f'" >> mylist.txt; done 

вам может понадобиться немного изменить порядок mylist.txt

ffmpeg -f concat -i mylist.txt -c:a libfdk_aac -b:a 128k output.m4a 

ffmpeg версия 2.2.3

Похожие вопросы