Как конкатенировать два файла MP4 с помощью FFmpeg?

Я пытаюсь объединить два файла mp4 с помощью ffmpeg. Мне нужно, чтобы это был автоматический процесс, поэтому я выбрал ffmpeg. Я конвертирую два файла в файлы .ts, затем объединяю их и пытаюсь закодировать объединенный файл .ts. Файлы закодированы в h264 и aac, и я надеюсь сохранить качество таким же или максимально близким к исходному.

ffmpeg -i part1.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part1.ts
ffmpeg -i part2.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part2.ts
cat part1.ts part2.ts > parts.ts
ffmpeg -y -i parts.ts -acodec copy -ar 44100 -ab 96k -coder ac -vbsf h264_mp4toannexb parts.mp4

К сожалению, во время кодирования я получаю следующее сообщение об ошибке от ffmpeg:

[h264 @ 0x1012600]sps_id out of range
[h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period
[h264 @ 0x1012600]sps_id out of range
[h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period
[NULL @ 0x101d600]error, non monotone timestamps 13779431 >= 13779431kbits/s    
av_interleaved_write_frame(): Error while opening file

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

В FFmpeg есть три метода конкатенации:

1. concat video filter

ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv \
  -filter_complex "[0:v] [0:a] [1:v] [1:a] [2:v] [2:a] concat=n=3:v=1:a=1 [v] [a]" \
  -map "[v]" -map "[a]" output.mkv

Обратите внимание, что этот метод выполняет повторное кодирование.

2. concat demuxer

$ cat mylist.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

$ ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4

Для Windows:

(echo file 'first file.mp4' & echo file 'second file.mp4' )>list.txt
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4

3. concat protocol

ffmpeg -i "concat:input1|input2" -codec copy output.mkv

Этот метод не работает для многих форматов, включая MP4, из-за природы этих форматов и упрощенной конкатенации, выполняемой этим методом.

Какой метод использовать

  • concat filter: Используйте, если ваши входные данные не имеют одинаковых параметров (ширина, высота и т.д.), или не являются одинаковыми форматами/кодеками, или если вы хотите выполнить какую-либо фильтрацию. (Вы можете перекодировать только те входы, которые не совпадают, чтобы они имели одинаковые кодеки и другие параметры, а затем использовать concat demuxer, чтобы избежать повторного кодирования других входов).

  • concat demuxer: Используется, когда вы хотите избежать повторного кодирования и ваш формат не поддерживает конкатенацию на уровне файлов (большинство файлов, используемых обычными пользователями, не поддерживают конкатенацию на уровне файлов).

  • concat protocol: Используется с форматами, поддерживающими конкатенацию на уровне файлов (MPEG-1, MPEG-2 PS, DV). Не используйте с MP4.

Если вы сомневаетесь, попробуйте использовать concat demuxer.

Также см.

Комментарии (26)

ДЛЯ ФАЙЛОВ MP4

Для .МР4 файлы (которые я получил от DailyMotion.com: в 50-минутный эпизод ТВ, загружаемые только в три части, как три .MP4 видео файлы) следующее решение было эффективным для для Windows 7, а не **** не предусматривают повторного кодирования файлов.

Я переименовал файлы (как файл file1.МР4, файл2.МР4, файл file3.МР4) таким образом, чтобы части были в правильном порядке для просмотра полный эпизод ТВ.

Затем я создал простой батник (функция concat.летучая мышь), со следующим содержанием:

:: Create File List
echo file file1.mp4 >  mylist.txt 
echo file file2.mp4 >> mylist.txt
echo file file3.mp4 >> mylist.txt

:: Concatenate Files
ffmpeg -f concat -i mylist.txt -c copy output.mp4

В батник и ffmpeg.exe должен быть помещен в ту же папку как .mp4 файлы должны быть соединены. Затем запустите пакетный файл. Это обычно занимает менее десяти секунд, чтобы убежать. .

Дополнение (2018/10/21) -

Если то, что вы ищете-это способ для указания всех mp4 файлов в текущей папке без перепечатывания, попробуйте это в Windows батник вместо (должны включить параметр -безопасная 0):

:: Create File List
for %%i in (*.mp4) do echo file '%%i'>> mylist.txt

:: Concatenate Files
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4

Это работает на Windows 7, в пакетном файле. Дон'т попробуйте использовать его в командной строке, потому что она работает только в пакетном файле!

Комментарии (8)

Здесь'ы быстро (занимает меньше 1 минуты) и без потерь способ сделать это без использования промежуточных файлов:

ls Movie_Part_1.mp4 Movie_Part_2.mp4 | perl -ne 'print "file $_"' | ffmpeg -f concat -i - -c copy Movie_Joined.mp4

В "ЛС" и содержит файлы, чтобы присоединиться к В "перл", которая создает файл конкатенации на лету в трубу В " Я" и говорит ffmpeg для чтения из трубы

(Примечание - мои файлы были без пробелов и странностей в них - вы'll необходимо соответствующее оболочки-побег, если вы хотите сделать эту мысль с "жесткий" и файлы).

Комментарии (9)

для файлов mp4:

Если они не точно такие же (100% один и тот же кодек, то же разрешение, тот же тип) mp4 файлов, то вам придется транс-код их в промежуточные потоки сначала:

ffmpeg -i myfile1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts temp1.ts
ffmpeg -i myfile2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts temp2.ts
// now join
ffmpeg -i "concat:temp1.ts|temp2.ts" -c copy -bsf:a aac_adtstoasc output.mp4

Внимание!: Выход будет как первый файл ( а не второй)

Комментарии (9)

Я пытался объединить три `.аудио файлы MP3 в один.файл M4A и этот ffmpeg команду работает.

Ввод команды:

ffmpeg -i input1.mp3 -i input2.mp3 -i input3.mp3 -filter_complex concat=n=3:v=0:a=1 -f MOV -vn -y input.m4a

Значения : " по-filter_complex функция concat=П=3:V с=0:а=1 с" : <БР>

функция concat означает использование СМИ конкатенации (присоединения) функция.<БР> Н значит, подтвердить общее количество входных файлов.<БР> в означает, однако других video? использовать 0 = Нет видео, 1 = содержит видео.<БР> а означает audio однако других? используйте значение 0 = Без звука, 1 = содержать аудио.<БР> означает силу установить формат файла (для просмотра всех поддерживаемых форматов, использовать видео -форматов)<БР> -ВН средства отключения видео (а также и ... бы отключить звук, если не хотел)<БР> означает перезапись выходных файлов (если выходной файл уже существует).

Для получения дополнительной информации: использовать ffmpeg на ч Полная` распечатать все параметры (включая формат и кодек конкретные варианты, очень долго)

Комментарии (2)
Решение

В итоге я использовал mpg в качестве промежуточного формата, и все заработало (ВНИМАНИЕ, это опасный пример, -qscale 0 перекодирует видео...).

ffmpeg -i 1.mp4 -qscale 0 1.mpg
ffmpeg -i 2.mp4 -qscale 0 2.mpg
cat 1.mpg 2.mpg | ffmpeg -f mpeg -i - -qscale 0 -vcodec mpeg4 output.mp4
Комментарии (13)

Подробной документации на различные способы объединения в ffmpeg может быть найден здесь]1.

Вы можете использовать 'фильтр функция concat' для быстрого сцепления.

Он выполняет повторное кодирование. Этот вариант лучше, когда входы имеют различные видео/аудио форматы.

Для объединения 2-х файлов:

ffmpeg -i input1.mp4 -i input2.webm \
-filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mp4

Для объединения 3 файла:

ffmpeg -i input1.mp4 -i input2.webm -i input3.mp4 \
-filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] [2:v:0] [2:a:0] concat=n=3:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mp4

Это работает для одной а также нескольких типов входных файлов.

Комментарии (12)

это работало для меня (на Windows)

ffmpeg -i "concat:input1|input2" -codec copy output

пример...

ffmpeg -i "concat:01.mp4|02.mp4" -codec copy output.mp4

<Н2>питон</Н2>

Используя некоторые Python код, чтобы сделать это с, как многие МР4 есть в папке (установить Python от python.org скопируйте и сохраните этот код в файл под названием mp4.py и запустить его из cmd в открывшемся в папку с Python mp4.py и все MP4 в папке будут объединены)

в

import glob
import os

stringa = ""
for f in glob.glob("*.mp4"):
    stringa += f + "|"
os.system("ffmpeg -i \"concat:" + stringa + "\" -codec copy output.mp4")

<Н3>Версия 2 С Python</Н3>

Взято из моего поста на моем блоге]1, это, как я делаю это в Python:

в

import os
import glob

def concatenate():
    stringa = "ffmpeg -i \"concat:"
    elenco_video = glob.glob("*.mp4")
    elenco_file_temp = []
    for f in elenco_video:
        file = "temp" + str(elenco_video.index(f) + 1) + ".ts"
        os.system("ffmpeg -i " + f + " -c copy -bsf:v h264_mp4toannexb -f mpegts " + file)
        elenco_file_temp.append(file)
    print(elenco_file_temp)
    for f in elenco_file_temp:
        stringa += f
        if elenco_file_temp.index(f) != len(elenco_file_temp)-1:
            stringa += "|"
        else:
            stringa += "\" -c copy  -bsf:a aac_adtstoasc output.mp4"
    print(stringa)
    os.system(stringa)

concatenate()
Комментарии (4)

Я нашел оператора труба не работает для меня, когда, используя опцию 3, чтобы функция concat несколько файлов mp4 на Mac в принятой ответ.

Следующие один-лайнер работает на Mac (высокая Сьерра) для объединения файлов mp4, без посредников требуется создание файла.

пакет ffmpeg -F в функции concat просмотра 0 -Я &л;(для F в ./*.МР4; делать Эхо "файл &#39;$ФРД/$Ф&#39; и"; сделал) -C копировать выхода.МР4

Комментарии (1)

на основе rogerdpack's и Ed999'ответы, Я'вэ создал свой .ш версия

#!/bin/bash

[ -e list.txt ] && rm list.txt
for f in *.mp4
do
   echo "file $f" >> list.txt
done

ffmpeg -f concat -i list.txt -c copy joined-out.mp4 && rm list.txt

он объединяет все *.МР4 файлы в текущей папке в которую вошли-вышли.МР4

протестировал на Mac.

в результате объем-точную сумму моего 60 проверенные файлы. Не должно быть каких-либо потерь. Просто то, что мне нужно

Комментарии (0)

Из документации здесь: https://trac.ffmpeg.org/wiki/Concatenate

если у вас есть mp4-файлов, они могут быть изображение сцепленное с первым перекодирования их в MPEG-2 транспортных потоков. С H. 264 видео и AAC аудио, следующее может использоваться:

ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts
ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate2.ts
ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" -c copy -bsf:a aac_adtstoasc output.mp4

Этот подход работает на всех платформах.

Мне нужна возможность, чтобы инкапсулировать это в скрипт платформы, так как я использовал свободно-ffmpeg С и придумал следующее решение:

const unlink = path =>
  new Promise((resolve, reject) =>
    fs.unlink(path, err => (err ? reject(err) : resolve()))
  )

const createIntermediate = file =>
  new Promise((resolve, reject) => {
    const out = `${Math.random()
      .toString(13)
      .slice(2)}.ts`

    ffmpeg(file)
      .outputOptions('-c', 'copy', '-bsf:v', 'h264_mp4toannexb', '-f', 'mpegts')
      .output(out)
      .on('end', () => resolve(out))
      .on('error', reject)
      .run()
  })

const concat = async (files, output) => {
  const names = await Promise.all(files.map(createIntermediate))
  const namesString = names.join('|')

  await new Promise((resolve, reject) =>
    ffmpeg(`concat:${namesString}`)
      .outputOptions('-c', 'copy', '-bsf:a', 'aac_adtstoasc')
      .output(output)
      .on('end', resolve)
      .on('error', reject)
      .run()
  )

  names.map(unlink)
}

concat(['file1.mp4', 'file2.mp4', 'file3.mp4'], 'output.mp4').then(() =>
  console.log('done!')
)
Комментарии (0)

Вот скрипт, который я сделал, чтобы объединить несколько GoPro mp4'ов в 720p mp4. Надеюсь, это поможет.

#!/bin/sh
cmd="( "
for i; do
    cmd="${cmd}ffmpeg -i $i -ab 256000 -vb 10000000 -mbd rd -trellis 2 -cmp 2 -subcmp 2 -g 100 -f mpeg -; "
done
cmd="${cmd} ) | ffmpeg -i - -vb 10000000 -ab 256000 -s 1280x720 -y out-`date +%F-%H%M.%S`.mp4"
echo "${cmd}"
eval ${cmd}
Комментарии (2)

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

mp4box.exe -add video1.mp4 -cat video2.mp4 destvideo.mp4

Скачать здесь для большинства платформ: https://gpac.wp.imt.fr/mp4box/

Комментарии (2)
ffmpeg \
  -i input_1.mp4 \
  -i input_2.mp4 \
  -filter_complex '[0:v]pad=iw*2:ih[int];[int][1:v]overlay=W/2:0[vid]' \
  -map [vid] \
  -c:v libx264 \
  -crf 23 \
  -preset veryfast \
  output.mp4
Комментарии (3)

Слияние всех mp4 файлов из текущего каталога

Я лично, как не создавая внешнего файла, который мне надо потом удалить, так что мое решение было следующим, который включает файлы нумерации списка (как file_1_name, file_2_name, file_10_name, file_20_name, file_100_name`, ...)

#!/bin/bash
filesList=""
for file in $(ls -1v *.mp4);do #lists even numbered file
    filesList="${filesList}${file}|"
done
filesList=${filesList%?} # removes trailing pipe
ffmpeg -i "concat:$filesList" -c copy $(date +%Y%m%d_%H%M%S)_merged.mp4
Комментарии (2)

После различных попыток ниже скрипт работал для меня на Windows 10 с помощью PowerShell.

    $files=Get-ChildItem -path e:\ -Filter *.mp4

    $files| ForEach-Object  {"file '$($_.FullName)'"}| Out-File -FilePath e:\temp.txt -Encoding ASCII

    if (-not (test-path "e:\ffmpeg\bin\ffmpeg.exe")) {throw "e:\ffmpeg\bin\ffmpeg.exe needed"}

    E:\ffmpeg\bin\ffmpeg.exe -safe 0 -f concat -i "e:\temp.txt" -c copy -bsf:v hevc_mp4toannexb -an e:\joined.mp4

    # Conversion Cleanup
    Remove-Item e:\temp.txt

Здесь первые две строки создают текст temp.txt файл, который имеет следующее содержание

file 'e:\first.mp4'
file 'e:\second.mp4'

3-й, 4-й линии проверяет, если ffmpeg не опубликованным на пути и создать "и присоединился.МР4"и

Основные отличия от других ответов как ниже

usage  of -bsf:v hevc_mp4toannexb -an

для мой файл mp4 выше работал, Вам может понадобиться использовать другой альтернативы, как показано ниже, в зависимости от вашего кодирования.

h264_mp4toannexb

Все возможные фильтры битовый поток может быть найден в https://ffmpeg.org/ffmpeg-bitstream-filters.html

Комментарии (1)

Здесь's мой способ соединения каталоги с mp4 файлы, используя команду подстановки и метода concat видео фильтр (это будет перекодировать) - подумал, что кто-то будет пользоваться этой фразой, особенно если у вас много файлов (я просто зарегистрирован 17 файлов одним махом):

попробуйте $(для F в *.МР4 ; делать Эхо -Н " С-я $е " и сделали) -filter_complex \ на "$(Я=0 ; для F в *.МР4 ; делать Эхо -Н " и[$я:в] [$я:] и" ; Я=$((Я+1)) ; сделано \ &ампер;&ампер; Эхо "функция concat=н=$я:в=1:а=1 [В] [а] то") на" карта " и[в] на" карта " и[А] на" выход.МР4

Б. Н. эта команда объединяет свои файлы в том порядке, в котором они'повторный им (т. е. в том порядке, как они'вновь представил если выполнить команды ls *.МР4) - в моем случае, каждый из них имел номер трека, так он работал отлично.

Комментарии (0)

Протокол конкатенацию описано здесь; https://trac.ffmpeg.org/wiki/Concatenate#protocol

При реализации через именованные каналы, чтобы избежать промежуточных файлов

Очень быстро (читай мгновенного), нет кадров сократилась, и работает хорошо.

Не забудьте удалить именованный канал файлы и не забудьте проверить, если видео H264 и AAC, которых можно сделать только через FFmpeg -I имя_файла.МР4 (проверьте для H264 и AAC упоминаний)

Комментарии (0)