Подтвердить что ты не робот

Ffmpeg: Объединение/объединение нескольких видеороликов mp4 не работает, вывод содержит только первое видео

Вот команда, которую я использую для объединения нескольких видео:

ffmpeg -i 75_540_38HQ2.mp4 -i 76_70_20.mp4 -i 76_173_80.mp4 -i 81_186_35.mp4 -vcodec copy -acodec copy Mux1.mp4

Результирующий Mux1.mp4 не содержит всех видеороликов. Только первое видео (75_540_38HQ2.mp4). Размер файла источника и результирующего видео ниже (как вы можете видеть, итоговое видео немного больше, чем первый вид):

$ ls -lh
-rw-r--r-- 1 dbaker dbaker  42M 2011-03-24 11:59 75_540_38HQ2.mp4
-rw-r--r-- 1 dbaker dbaker 236M 2011-03-24 12:09 76_173_80.mp4
-rw-r--r-- 1 dbaker dbaker  26M 2011-03-24 12:05 76_70_20.mp4
-rw-r--r-- 1 dbaker dbaker  54M 2011-03-24 12:15 81_186_35.mp4
-rw-r--r-- 1 dbaker dbaker  44M 2011-03-24 14:48 Mux1.mp4

Вот результат команды ffmpeg. Для меня это выглядит нормально, показывая несколько исходных входов и один вывод.

FFmpeg version SVN-r26402, Copyright (c) 2000-2011 the FFmpeg developers
  built on Mar 21 2011 18:05:32 with gcc 4.4.5
  configuration: --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable-libfaac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxvid --enable-x11grab
  libavutil     50.36. 0 / 50.36. 0
  libavcore      0.16. 1 /  0.16. 1
  libavcodec    52.108. 0 / 52.108. 0
  libavformat   52.93. 0 / 52.93. 0
  libavdevice   52. 2. 3 / 52. 2. 3
  libavfilter    1.74. 0 /  1.74. 0
  libswscale     0.12. 0 /  0.12. 0
  libpostproc   51. 2. 0 / 51. 2. 0
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '75_540_38HQ2.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 1970-01-01 00:00:00
    encoder         : Lavf52.93.0
  Duration: 00:00:29.99, start: 0.000000, bitrate: 11517 kb/s
    Stream #0.0(eng): Video: h264, yuv420p, 1280x960 [PAR 1:1 DAR 4:3], 11575 kb/s, 29.94 fps, 29.97 tbr, 30k tbn, 59.94 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
    Stream #0.1(eng): Audio: aac, 48000 Hz, stereo, s16, 127 kb/s
    Metadata:
      creation_time   : 1970-01-01 00:00:00
Input #1, mov,mp4,m4a,3gp,3g2,mj2, from '76_70_20.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 1970-01-01 00:00:00
    encoder         : Lavf52.93.0
  Duration: 00:00:19.98, start: 0.000000, bitrate: 10901 kb/s
    Stream #1.0(eng): Video: h264, yuv420p, 1280x960 [PAR 1:1 DAR 4:3], 10804 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
    Stream #1.1(eng): Audio: aac, 48000 Hz, stereo, s16, 128 kb/s
    Metadata:
      creation_time   : 1970-01-01 00:00:00
Input #2, mov,mp4,m4a,3gp,3g2,mj2, from '76_173_80.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 1970-01-01 00:00:00
    encoder         : Lavf52.93.0
  Duration: 00:03:09.99, start: 0.000000, bitrate: 10393 kb/s
    Stream #2.0(eng): Video: h264, yuv420p, 1280x960 [PAR 1:1 DAR 4:3], 10321 kb/s, 29.96 fps, 29.97 tbr, 30k tbn, 59.94 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
    Stream #2.1(eng): Audio: aac, 48000 Hz, stereo, s16, 128 kb/s
    Metadata:
      creation_time   : 1970-01-01 00:00:00

Seems stream 0 codec frame rate differs from container frame rate: 119.88 (120000/1001) -> 30000.00 (30000/1)
Input #3, mov,mp4,m4a,3gp,3g2,mj2, from '81_186_35.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 1970-01-01 00:00:00
    encoder         : Lavf52.93.0
  Duration: 00:00:35.00, start: 0.000000, bitrate: 12700 kb/s
    Stream #3.0(eng): Video: h264, yuv420p, 1280x720 [PAR 1:1 DAR 16:9], 12620 kb/s, 59.91 fps, 30k tbr, 60k tbn, 119.88 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
    Stream #3.1(eng): Audio: aac, 48000 Hz, stereo, s16, 128 kb/s
    Metadata:
      creation_time   : 1970-01-01 00:00:00
Output #0, mp4, to 'Mux1.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 1970-01-01 00:00:00
    encoder         : Lavf52.93.0
    Stream #0.0(eng): Video: libx264, yuv420p, 1280x960 [PAR 1:1 DAR 4:3], q=2-31, 11575 kb/s, 30k tbn, 29.97 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
    Stream #0.1(eng): Audio: libfaac, 48000 Hz, stereo, 128 kb/s
    Metadata:
      creation_time   : 1970-01-01 00:00:00
Stream mapping:
  Stream #0.0 -> #0.0
  Stream #2.1 -> #0.1
Press [q] to stop encoding
frame=  883 fps=632 q=-1.0 Lsize=   44730kB time=29.40 bitrate=12465.1kbits/s    
video:41678kB audio:2969kB global headers:0kB muxing overhead 0.184548%

Я делаю что-то ослепительно глупо здесь?

Исходные видеоролики поступали с видеокамеры и представляли собой небольшие фрагменты с ffmpeg -i bigfile.mp4 -ss 20 -t 10 -vcodec copy etc..

Спасибо, кучи!! Dave


Изменить: не удалось его решить, поэтому я просто использую инструмент GUI avidemux. Казалось, что MP4 просто отлично.

Должна быть проблема с MP4 или только с теми, которые выходят из камеры gopro.

4b9b3361

Ответ 1

Вы должны конвертировать их в формат MPEG, который можно легко объединить. Ниже приведен скрипт, который я использую и называю "ffcat" для моих видео GoPro. По сути, он запускает несколько команд "ffmpeg -i", которые генерируют MPEG с возможностью объединения, который передается команде ffmpeg, которая затем преобразует их в файл mp4 H.264.

Это также размер видео до 720p, но вы можете не захотеть этого.

"H264options" - это флаги, которые я недавно нашел в интернете по адресу h264.code-shop.com

Надеюсь, это поможет, Рейд


cmd="( "

h264options="-vcodec libx264 -b 512k -flags +loop+mv4 -cmp 256 \
 -partitions +parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 \
 -me_method hex -subq 7 -trellis 1 -refs 5 -bf 3 \
 -flags2 +bpyramid+wpred+mixed_refs+dct8x8 -coder 1 -me_range 16 \
   -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -qmin 10\
 -qmax 51 -qdiff 4"

outfile="out-'date +%F-%H%M.%S'.mp4"

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 -y -i - -threads 8 ${h264options} -vb 10000000 -acodec libfaac -ar 44100 -ab 128k -s 1280x720 ${outfile}"
echo "${cmd}"
eval ${cmd}

Ответ 2

Предполагая, что вы хотите конкатенировать фильм, вы можете использовать следующую команду:

ffmpeg -f concat -i inputs.txt -vcodec copy -acodec copy Mux1.mp4

Со следующим текстом в inputs.txt:

file 75_540_38HQ2.mp4 
file 76_70_20.mp4 
file 76_173_80.mp4
file 81_186_35.mp4

Примечание: некоторые дистрибутивы (например, Ubuntu) не имеют ffmpeg в своем репозитории и вместо этого определяют ffmpeg как псевдоним avconv. Это не будет работать с avconv, так что в таком случае вам придется скомпилировать ffmpeg самостоятельно. Вы можете проверить, есть ли у вас реальный ffmpeg, запустив ffmpeg и проверив, заканчивается ли первая выходная строка "разработчиками FFmpeg".

Ответ 3

Забудьте о FFmpeg, используйте вместо него MP4Box, это легко и быстро:

    mp4box -add video1.mp4 -cat video2.mp4 -cat video3.mp4 output.mp4

Он доступен для Windows, Linux и OS X: http://www.videohelp.com/tools/mp4box

Если вы работаете в Windows, вы можете использовать YAMB, который представляет собой графический интерфейс для MP4Box, который отлично работает: http://www.videohelp.com/tools/YAMB

ОБНОВЛЕНИЕ Июнь-2016: FFmpeg добавил фильтр конкатенации, более подробную информацию здесь: fooobar.com/questions/45711/...

Ответ 4

Из раздела ffmpeg man "Примеры":

Вы можете поместить в поток много потоков одного и того же типа:

ffmpeg -i test1.avi -i test2.avi -vcodec copy -acodec copy \ -vcodec copy -acodec copy test12.avi -newvideo -newaudio

В дополнение к первым видео- и аудиопотокам в результате  выходной файл test12.avi будет содержать второе видео и второе  аудио поток, найденный в списке входных потоков.

Параметры "-newvideo", "-newaudio" и "-newsubtitle" должны быть указаны сразу после имени выходного файла, к которому вы хотите добавить.

Если вы имели в виду, что хотите их соединить, FAQ содержит инструкции.

Я не уверен, принадлежит ли этот вопрос/ответ на SuperUser.

Ответ 5

Простой concat работает для файлов mp4 и mkv, если все входные видео имеют одинаковый кодек и вы хотите выводить видео также в одном кодеке. https://trac.ffmpeg.org/wiki/Concatenate
вам нужно создать текстовый файл как

# this is a comment
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

А затем используйте команду

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

Я использовал пример с той же справочной страницы, он работает довольно хорошо. Единственная проблема возникает, когда видео записывается неправильно. Это может вызвать проблемы с синхронизацией аудио и видео, поскольку оно просто копирует информацию PTS и DTS из исходного видео в видео назначения.
Чтобы получить полностью проверенное решение, вам нужно читать видео пакет за пакетом, а затем собирать все пакеты в одно видео с настраиваемой оптимизацией, такой как отбрасывание повторяющихся пакетов PTS и поддержание монотонных значений PTS.

Ответ 6

Я успешно использовал этот script. Результаты идеальны, потому что они используют необработанное видео.

http://trac.ffmpeg.org/wiki/How%20to%20concatenate%20%28join,%20merge%29%20media%20files

Убедитесь, что вы редактируете строку EXTRA OPTIONS.

#!/bin/bash

################################################################################
#
# Script name: MultiMedia Concat Script (mmcat)
# Author: burek ([email protected])
# License: GNU/GPL, see http://www.gnu.org/copyleft/gpl.html
# Date: 2012-07-14
#
# This script concatenates (joins, merges) several audio/video inputs into one
# final output (just like as if all the inputs were played in a playlist, one
# after another).
#
# All input files must have at least one audio and at least one video stream.
# If not, you can easily add audio silence, using FFmpeg. Just search the
# internet for "ffmpeg add silence".
#
# The script makes use of FFmpeg tool (www.ffmpeg.org) and is free for use under
# the GPL license. The inspiration for this script came from this FAQ item:
# http://ffmpeg.org/faq.html#How-can-I-join-video-files_003f
#
# If you find any bugs, please send me an e-mail so I can fix it.
#
################################################################################
#
# General syntax: mmcat <input1> <input2> <input3> ... <output>
#
# For example: mmcat file1.flv file2.flv output.flv
# would create "output.flv" out of "file1.flv" and "file2.flv".
#
################################################################################

# change this to what you need !!!
EXTRA_OPTIONS='-vcodec libx264 -crf 23 -preset medium -acodec aac -strict experimental -ac 2 -ar 44100 -ab 128k'

################################################################################
#
# NO NEED TO TOUCH ANYTHING AFTER THIS LINE!
#
################################################################################

# the version of the script
VERSION=1.3

# location of temp folder
TMP=/tmp

################################################################################

echo "MultiMedia Concat Script v$VERSION (mmcat) - A script to concatenate multiple multimedia files."
echo "Based on FFmpeg - www.ffmpeg.org"
echo "Don't forget to edit this script and change EXTRA_OPTIONS"
echo ""

################################################################################
# syntax check (has to have at least 3 params: infile1, infile2, outfile
################################################################################
if [ -z $3 ]; then
    echo "Syntax: $0 <input1> <input2> <input3> ... <output>"
    exit 1
fi

################################################################################
# get all the command line parameters, except for the last one, which is output
################################################################################
# $first  - first parameter
# $last   - last parameter (output file)
# $inputs - all the inputs, except the first input, because 1st input is
#           handled separately
################################################################################
first=${@:1:1}
last=${@:$#:1}
len=$(($#-2))
inputs=${@:2:$len}

# remove all previous tmp fifos (if exist)
rm -f $TMP/mcs_*

################################################################################
# decode first input differently, because the video header does not have to be
# kept for each video input, only the header from the first video is needed
################################################################################
mkfifo $TMP/mcs_a1 $TMP/mcs_v1

ffmpeg -y -i $first -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a1 2>/dev/null </dev/null &
ffmpeg -y -i $first -an -f yuv4mpegpipe -vcodec rawvideo $TMP/mcs_v1 2>/dev/null </dev/null &

# if you need to log the output of decoding processes (usually not necessary)
# then replace the "2>/dev/null" in 2 lines above with your log file names, like this:
#ffmpeg -y -i $first -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a1 2>$TMP/log.a.1 </dev/null &
#ffmpeg -y -i $first -an -f yuv4mpegpipe -vcodec rawvideo $TMP/mcs_v1 2>$TMP/log.v.1 </dev/null &

################################################################################
# decode all the other inputs, remove first line of video (header) with tail
# $all_a and $all_v are lists of all a/v fifos, to be used by "cat" later on
################################################################################
all_a=$TMP/mcs_a1
all_v=$TMP/mcs_v1
i=2
for f in $inputs
do
    mkfifo $TMP/mcs_a$i $TMP/mcs_v$i

    ffmpeg -y -i $f -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a$i 2>/dev/null </dev/null &
    { ffmpeg -y -i $f -an -f yuv4mpegpipe -vcodec rawvideo - 2>/dev/null </dev/null | tail -n +2 > $TMP/mcs_v$i ; } &

    # if you need to log the output of decoding processes (usually not necessary)
    # then replace the "2>/dev/null" in 2 lines above with your log file names, like this:
    #ffmpeg -y -i $f -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a$i 2>$TMP/log.a.$i </dev/null &
    #{ ffmpeg -y -i $f -an -f yuv4mpegpipe -vcodec rawvideo - 2>$TMP/log.v.$i </dev/null | tail -n +2 > $TMP/mcs_v$i ; } &

    all_a="$all_a $TMP/mcs_a$i"
    all_v="$all_v $TMP/mcs_v$i"
    let i++
done

################################################################################
# concatenate all raw audio/video inputs into one audio/video
################################################################################
mkfifo $TMP/mcs_a_all
mkfifo $TMP/mcs_v_all
cat $all_a > $TMP/mcs_a_all &
cat $all_v > $TMP/mcs_v_all &

################################################################################
# finally, encode the raw concatenated audio/video into something useful
################################################################################
ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i $TMP/mcs_a_all \
       -f yuv4mpegpipe -vcodec rawvideo -i $TMP/mcs_v_all \
    $EXTRA_OPTIONS \
    $last

################################################################################
# remove all fifos
################################################################################
rm -f $TMP/mcs_*

Ответ 7

Конкатентный демультиплер

В ffmpeg 1.1 добавлен concat demuxer. Если ваша версия ffmpeg устарела, получить здесь новый статический двоичный код: http://www.ffmpeg.org/download.html

Инструкции

Создайте файл mylist.txt со всеми файлами, которые вы хотите связать в следующем виде (строки, начинающиеся с тире, игнорируются):

# this is a comment
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

Обратите внимание, что это могут быть либо относительные, либо абсолютные пути. Затем вы можете закодировать свои файлы с помощью:

ffmpeg -f concat -i mylist.txt -c copy output

Можно создать этот файл списка с помощью цикла bash for или с помощью printf. Любой из следующих файлов будет генерировать файл списка, содержащий каждый *.wav в рабочем каталоге:

for f in ./*.wav; do echo "file '$f'" >> mylist.txt; done
printf "file '%s'\n" ./*.wav > mylist.txt

Источник: ffmpeg wiki

Ответ 8

MP4Box работает без нарушения звука. Для получения хороших результатов я сделал следующее:

Пример командной строки:

MP4Box -force-cat -add in1.mp4 -cat in2.mp4 -cat in3.mp4 ... out.mp4

Некоторые незначительные комментарии:

  • Вышеупомянутый способ важен, поскольку последняя версия MP4Box, распространяемая с Linux Mint 13, является ошибкой и приводит к поврежденному звуку.

  • -force-cat важно, так как тег видеоформата был изменен с AVC на avc3 без него.

Ответ 9

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

ffmpeg -f concat -safe 0 -i <(for f in ./*.mp4; do echo "file '$PWD/$f'"; done) -c copy output.mp4

Обратитесь к ffmpeg вики.