以下是我用来组合多个视频的命令:
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..
谢谢堆! 戴夫
编辑:无法解决,所以我只使用avidemux GUI工具。它似乎附加了MP4就好了。
一定是MP4的问题,或者只是gopro相机的问题。
答案 0 :(得分:18)
假设您要连接影片,可以使用以下命令:
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。
答案 1 :(得分:13)
忘了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的GUI,效果很好: http://www.videohelp.com/tools/YAMB
2016年6月更新: FFmpeg添加了一个串联过滤器,更多信息在这里: https://stackoverflow.com/a/11175851/218418
答案 2 :(得分:7)
从ffmpeg手册页“示例”部分:
您可以在输出中放置许多相同类型的流:
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。
答案 3 :(得分: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值。
答案 4 :(得分:4)
您必须将它们转换为易于连接的MPEG格式。下面是我使用的脚本,并为我的GoPro视频调用“ffcat”。它基本上运行了几个“ffmpeg -i”命令,这些命令产生可连接的MPEG,它通过管道输出到ffmpeg命令,然后将它们转换为H.264 mp4文件。
它还会将视频大小调整为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}
答案 5 :(得分:3)
我一直非常成功地使用这个脚本。结果很完美,因为它使用的是原始视频。
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 (burek021@gmail.com)
# 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_*
答案 6 :(得分:3)
concat demuxer被添加到ffmpeg 1.1中。如果你的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
答案 7 :(得分:1)
最初的问题更多是关于在一个输出文件中混合多个视频流,并让应用程序选择要解码的视频流。正如上面评论中提到的,您可以使用 FFmpeg 提供的 -map
选项来完成。
以下是从单独的输入文件中混合 3 个视频流的快速示例命令:
ffmpeg -i video_A.mp4 -i video_B.mp4 -i video_C.mp4 -c copy \
-map 0:0 -map 1:0 -map 2:0 -map 2:1 output_mux_video.mp4
-map
选项都以特定的值格式 <INPUT_INDEX>:<STREAM_INDEX>
开头<INPUT_INDEX>
上面是-i <INPUT_FILE_NAME>
<STREAM_INDEX>
是在每个 <INPUT_FILE_NAME>
中找到的流的顺序,它也可以是特殊字符,例如 a
(所有音频流)或 v
(所有视频流)流),有关更高级的用法,请查看 FFmpeg -map 。在此示例中,假设视频流位于索引 0
,音频流位于索引 1
-c copy
表示 stream copy,因此 FFmpeg 将复制每个输入视频流以进行复用/解复用,而不是对每个视频流重新编码。命令执行会输出这样的消息:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from "/path/to/video_A.mp4"
..... <OMITTED_NOT_IMPORTANT> .....
Duration: 00:04:54.08, start: 0.000000, bitrate: 146 kb/s
Stream #0.0(und): Video: h264 (Main), yuv420p, 256x140 [PAR 1:1 DAR 64:35], 10 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc
Stream #0.1(und): Audio: aac, 44100 Hz, stereo, fltp, 127 kb/s
Input #1, mov,mp4,m4a,3gp,3g2,mj2, from "/path/to/video_B.mp4"
..... <OMITTED_NOT_IMPORTANT> .....
Duration: 00:05:35.01, start: 0.000000, bitrate: 363 kb/s
Stream #1.0(und): Video: h264 (Main), yuv420p, 426x240 [PAR 1:1 DAR 71:40], 229 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc
Stream #1.1(eng): Audio: aac, 44100 Hz, stereo, fltp, 127 kb/s
Input #2, mov,mp4,m4a,3gp,3g2,mj2, from "/path/to/video_C.mp4"
..... <OMITTED_NOT_IMPORTANT> .....
Duration: 00:05:35.01, start: 0.000000, bitrate: 363 kb/s
Stream #2.0(und): Video: h264 (Main), yuv420p, 426x240 [PAR 1:1 DAR 71:40], 229 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc
Stream #2.1(eng): Audio: aac, 44100 Hz, stereo, fltp, 127 kb/s
Output #0, mp4, to '/path/to/output_mux_video.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
..... <OMITTED_NOT_IMPORTANT> .....
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #1:0 -> #0:1 (copy)
Stream #2:0 -> #0:2 (copy)
Stream #2:1 -> #0:3 (copy)
Press ctrl-c to stop encoding
frame= 8818 fps= 0 q=-1.0 Lq=-1.0 size= 15342kB time=293.87 bitrate= 427.7kbits/s
video:9783kB audio:5235kB global headers:0kB muxing overhead 2.160838%
通过检查上面的 Stream mapping
部分,您将知道映射是否符合您的预期。
对于那些遇到类似问题的人,这个答案可以节省您的时间。
答案 8 :(得分:0)
MP4Box可以在不破坏音频的情况下工作。我做了以下工作以获得良好的结果:
从gpac网站下载最新的Linux deb版本: http://gpac.wp.mines-telecom.fr/downloads/gpac-nightly-builds/
使用-force-cat
选项
示例命令行:
MP4Box -force-cat -add in1.mp4 -cat in2.mp4 -cat in3.mp4 ... out.mp4
一些小评论:
上述方法很重要,因为与Linux Mint 13一起发布的MP4Box的最新版本存在错误,并且导致音频损坏。
-force-cat
很重要,因为视频格式标签在没有它的情况下从AVC更改为avc3。
答案 9 :(得分:0)
您可以避免显式创建列表文件,而只需一行即可完成整个操作
ffmpeg -f concat -safe 0 -i <(for f in ./*.mp4; do echo "file '$PWD/$f'"; done) -c copy output.mp4
请参阅ffmpeg wiki。
答案 10 :(得分:0)
如here所示,您有几种选择:
ffmpeg -i "concat:input1.ts|input2.ts|input3.ts" -c copy output.ts
我不完全了解这一点,您可能需要查看所有图表和过滤器图表,但是它可以让您处理多种格式和不同的编解码器属性
ffmpeg -i input1.mp4 -i input2.webm -i input3.mov \
-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[outv][outa]" \
-map "[outv]" -map "[outa]" output.mkv
首先,您需要生成某种列表文件,例如。 “ mylist.txt”
# this is a comment
file '/path/to/file1.wav'
file '/path/to/file2.wav'
file '/path/to/file3.wav'
第二,您需要运行命令以使用列表
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.wav