如何使用FFmpeg连接两个MP4文件?


441

我正在尝试使用ffmpeg连接两个mp4文件。我需要这是一个自动过程,因此为什么选择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文件连接在一起并使它正常工作。

Answers:


783

FFmpeg具有三种串联方法:

1. concat视频过滤器

如果输入的参数不同(宽度,高度等)或格式/编解码器不同,或者要执行任何过滤,请使用此方法。(您可以仅对不匹配的输入进行重新编码,以便它们共享相同的编解码器和其他参数,然后使用concat多路分配器避免对其他输入进行重新编码)。

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分离器

如果要避免重新编码并且格式不支持文件级串联(一般用户使用的大多数文件不支持文件级串联),请使用此方法。

$ 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协议

将此方法用于支持文件级串联的格式(MPEG-1,MPEG-2 PS,DV)。千万不能用MP4使用。

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

由于这些格式的性质以及此方法执行的简单级联,因此该方法不适用于许多格式,包括MP4。


如果不确定使用哪种方法,请尝试使用concat多路分配器。

另见


3
Windows命令提示符转义字符是^;。我也遇到了引号的问题,结果变成了:ffmpeg -i concat:input1 ^ | input2 -codec复制输出
user423430

1
有用的答案。当我阅读此变体时,这对我来说更有意义:superuser.com/a/607384/74576
Ryan

3
CONCAT分流器适用于视频,但我失去了音频
卢瓦克

23
对于单行使用:ffmpeg -safe 0 -f concat -i <(find . -type f -name '*' -printf "file '$PWD/%p'\n" | sort) -c copy output.mkv(mkv比mp4接受更多的编解码器,但您也可以在mp4上尝试使用)。的-safe 0是最近的ffmpeg版本抱怨不安全的文件名,并且-type f仅适用于上市文件。我添加| sort了按字母顺序对文件进行排序;因为find按顺序读取它们是保存在文件系统中。也适用于带有空格的文件。
erik

1
对我来说,在Windows中,双引号工作(而不是单在你的例子)ffmpeg -i "concat:input1|input2" -codec copy output。无需转义管道字符。
Shovalt '16

82

对于MP4文件

对于.MP4文件(这是我从DailyMotion.com获得:50分钟的电视节目,可下载的仅在三个部分,三个.mp4格式的视频文件)以下是为有效的解决方案的Windows 7,和不NOT涉及重新编码文件。

我重命名了文件(如file1.mp4file2.mp4file3.mp4),以使各部分的顺序正确,可以观看完整的电视节目。

然后,我创建了一个简单的批处理文件(concat.bat),其内容如下:

:: 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 批处理文件中尝试此操作必须包含选项-safe 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上的批处理文件中有效。不要尝试在命令行上使用它,因为它只能在批处理文件中使用!


5
迄今为止最简单的解决方案。
1934286年

这应该是最好和最简单的答案。辛苦了 你救了我的日子。
DysaniazzZ

这是一个很好的解决方案,但是谈论批处理文件会使这个声音变得很原始(就像它是批处理一样),并且比原来要复杂得多(因为完全不需要批处理文件)。如果只显示C:\blah>type mylist.txt<ENTER>(这样,他们就可以看到该文件的内容),那就更清楚了。然后, ffmpeg -f concat -i mylist.txt -c copy output.mp4<ENTER> 您还应该包括参考文件 trac.ffmpeg.org/wiki/Concatenate (该参考文件甚至使用相同的文件名mylist.txt)
barlop

这是一个非常好的解决方案,因为它可以避免输入冗长的-i参数文件列表。在Linux上,我这样做:ls -1 P1041*.mp4 | sed s/"P"/" file P"/g > mylist.txt这比编写批处理脚本还要酷。无论如何,-c copy执行速度非常快(我没有意识到),这是此答案的真正魔力。
Würgspaß

1
对于我的mp4文件,使用ffmpeg v3.2.2在Mac上运行concat代码后,输出文件中根本没有音频。
kakyo

59

这是一种无需中间文件即可快速(耗时不到1分钟)且无损的方法:

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

“ ls”包含要加入的文件。“ perl”动态创建连接文件到管道中。“-i-”部分告诉ffmpeg从管道中读取

(请注意-我的文件中没有空格或奇怪的东西-如果您要对“硬”文件执行此操作,则需要适当的外壳转义)。


2
在OSX上做过,效果很好!很棒,快速,无损的解决方案,几乎没有要求。
2014年

1
对于包含空格的文件进行适当的转义:ls Movie_Part_1.mp4 Movie_Part_2.mp4 | perl -ne '$_ =~ s/\n$//; print "file '"'"'$_'"'"'\n"' | ffmpeg -f concat -i - -c copy Movie_Joined.mp4
Thomas Bachem 2015年

4
ls * | perl -ne 'print "file $_"' | ffmpeg -f concat -i - -c copy Movie_Joined.mp4如果文件命名正确且顺序合理,也可以这样做。正是我想要的,因此在OS X上对我来说很棒。
natebeaty

3
在Linux上,我使用了oneliner :(ffmpeg -safe 0 -f concat -i <(find . -type f -name '*' -printf "file '$PWD/%p'\n" | sort) -c copy output.mkvmkv比mp4接受更多的编解码器,但您也可以在mp4上尝试使用它)。的-safe 0是最近的ffmpeg版本抱怨不安全的文件名,并且-type f仅适用于上市文件。我添加| sort了按字母顺序对文件进行排序;因为find按顺序读取它们是保存在文件系统中。也适用于带有空格的文件。
erik

12
我必须添加此参数才能ffmpeg使其起作用:-protocol_whitelist file,tcp,http,pipe
Bensge

44

对于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

注意!:输出将类似于第一个文件(而不是第二个文件)


2
如下面我的答案所示,无需对文件进行代码转换。FFmpeg可以将多个mp4文件连接成一个mp4文件-无需任何中间步骤,也无需任何重新编码。唯一需要重新编码的情况是,原始文件不是mp4文件,但目的是创建一个mp4文件作为输出文件。
Ed999

@T。Todua:我很想了解您的两个mp4源文件之间的区别到底是什么。他们是否使用不同的采样率(例如44,100 Hz和48,000 Hz)?还是他们使用不同的比特率(例如128 kbps和64 kbps)?在这两种情况下,我都不太了解命令-c copy(流复制指令)如何修改源文件以使其兼容。
Ed999

4
@ T.Todua嗨,当视频没有音轨时,此命令可以正常使用。但是,当myfile1.mp4没有音频并且myfile2.mp4有音频时,结果output.mp4没有音频。预期的output.mp4应该包含音频。我该如何解决?
AnswerZhao

2
@ T.Todua er ....太糟糕了。file1 | file2生成与file2 | file1不同的视频。顺序很重要。
AnswerZhao

1
我在concat 2 mp4文件上尝试了您的命令。有用。但是,第二个文件的音频变得杂乱无章,就像在产生的新串联中的Ah-oh-Ee声音一样。你有解决办法吗?
superlinux

35

我试图将三个.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 = n = 3:v = 0:a = 1”

concat表示使用媒体连接(合并)功能。
n表示确认输入文件的总数。
v意味着有视频?使用0 =无视频,1 =包含视频。有声音
手段吗?使用0 =无音频,1 =包含音频。-F
表示强制设置文件格式(要查看所有受支持的格式,请使用ffmpeg -formats
-vn表示禁用视频(-an如果不需要,也将禁用音频)
-y表示覆盖输出文件(如果输出文件已经存在)。

有关更多信息:使用ffmpeg -h full 打印所有选项(包括所有格式和编解码器特定的选项,很长)


1
Fi使用此功能-f concat -safe 0 -i "file.txt" -c copy -y "OutPut.mp4"会很方便,但是当某些视频带有音频而有些没有音频时,则无法正常工作。谢谢–
Ahmad

1
这可行。感谢您的回答中的详细说明。这非常有帮助。
乔T.博卡

31

我最终使用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

8
截至本评论,-sameq已被删除。使用-qscale 0代替。
Xavier Ho

6
-sameq并不意味着“质量相同”,并已如@XavierHo所述从ffmpeg中删除。
llogan

3
仅通过连接两个文件就必须通过中间格式对视频进行转码,这似乎很可耻。您会损失一代人。最好不要深入了解容器格式,并concat像上面@rogerdpack一样在ffmpeg中使用命令。
兰德尔·库克

8
为什么这是一个公认的答案?这是非常糟糕的方法。
显示名称

4
@SargeBorsch因为它有效。我已经尝试了页面上的所有其他内容-它们都无法正常工作。

14

可以在此处找到有关 ffmpeg中各种串联方式的详细文档。

您可以使用“ 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

这适用于相同以及多种输入文件类型。


您可以在此示例中为选项指定更多详细信息吗?
开发人员

@Developer:有关选项的说明-> Concat过滤器Wiki
SJ00

4
串联3个文件时,应使用concat = n = 3:v = 1:a = 1而非n = 2
Cynapsis

1
我没有得到无损连接,我的ouput.mp4视频比特率明显低于输入视频的视频比特率
jasan

感谢Cynapsis指出来,感谢georgiecasey更新命令
SJ00

10

我发现使用选项3在公认的答案中在Mac上连接多个MP4时,管道运算符对我不起作用。

以下一线可在Mac(High Sierra)上连接mp4,而无需创建中间文件。

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


2
这个简单的答案是唯一对我有用的答案。这里和其他地方的文档一页一页,而只需要这种简单的一列式即可—并且实际上是有效的。谢谢。
blujay

9

根据rogerdpack和Ed999的回复,我创建了.sh版本

#!/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

它将*.mp4当前文件夹中的所有文件加入joined-out.mp4

在Mac上测试。

结果文件大小是我的60个测试文件的精确总和。不应有任何损失。我所需要的


9

这对我有用(在Windows上)

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

一个例子...

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

蟒蛇

使用一些python代码在一个文件夹中处理尽可能多的mp4(从python.org安装python,将其复制并粘贴并保存到名为mp4.py的文件中,然后使用python从文件夹中打开的cmd中运行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")

Python版本2

从我博客上的帖子中摘录,这就是我在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()

1
concat协议不应与MP4一起使用,并且不能按已接受的答案中所述使用
llogan

@LordNeckbeard我想知道您是否对有关指定2个MP4视频同时指定输出比特率的ffmpeg问题的答案?video.stackexchange.com/q/24569/5657谢谢。
瑞安

@LordNeckbeard我的猜测是,如果您愿意,您的答案仍然是最好的答案!我对自己的东西并不特别满意。
瑞安

不仅(如Neckbeard勋爵所指出的那样),为了使连接成功,有必要将.mp4文件转换为中间.TS格式,而且,甚至更糟的是,此答​​案甚至无法解决输入的需要。视频文件具有匹配的比特率,帧速率,采样率,时基和持续时间。如果没有这5个因素的共同点,则无法串联文件(即,使用流复制将文件联接),而必须重新编码。
Ed999 '18

9

这里有2个纯bash解决方案,仅使用ffmpeg和不使用

  • 中间文件
  • perl,python或javascript

一线解决方案使用 ls

ls video1.mp4 video2.mp4 | while read line; do echo file \'$line\'; done | ffmpeg -protocol_whitelist file,pipe -f concat -i - -c copy output.mp4

带0或2+个参数的函数

#######################################
# Merge mp4 files into one output mp4 file
# usage:
#   mergemp4 #merges all mp4 in current directory
#   mergemp4 video1.mp4 video2.mp4
#   mergemp4 video1.mp4 video2.mp4 [ video3.mp4 ...] output.mp4 
#######################################
function mergemp4() {
  if [ $# = 1 ]; then return; fi

  outputfile="output.mp4"

  #if no arguments we take all mp4 in current directory as array
  if [ $# = 0 ]; then inputfiles=($(ls -1v *.mp4)); fi
  if [ $# = 2 ]; then inputfiles=($1 $2); fi  
  if [ $# -ge 3 ]; then
    outputfile=${@: -1} # Get the last argument
    inputfiles=(${@:1:$# - 1}) # Get all arguments besides last one as array
  fi

  # -y: automatically overwrite output file if exists
  # -loglevel quiet: disable ffmpeg logs
  ffmpeg -y \
  -loglevel quiet \
  -f concat \
  -safe 0 \
  -i <(for f in $inputfiles; do echo "file '$PWD/$f'"; done) \
  -c copy $outputfile

  if test -f "$outputfile"; then echo "$outputfile created"; fi
}

注意:在此线程中尝试了一些解决方案,但没有一个让我满意


7

对于.mp4文件,我发现使用开源命令行工具可以更好,更快地工作mp4box。然后,您可以通过以下方式使用它:

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

对于大多数平台,请在此处下载:https : //gpac.wp.imt.fr/mp4box/


2
尽管这对某人可能有用,但要求是:“ 我正在尝试使用ffmpeg连接两个mp4文件。我需要这是一个自动过程 ”。请阅读完整的问题,然后尝试提供正确的答案。
thvs86 '19

5
这个答案是完全正确的。这是一个FOSS工具,可以完成相同的工作。可以像FFmpeg一样在脚本中使用它。它比任何FFmpeg答案都更简单地完成工作。看看它们有多复杂!其中之一使用Node.js调用FFmpeg!疯狂。请停止胡言乱语,然后尝试再次使StackOverflow有用。由于像您这样的痴迷者,该网站成为了昔日自我的阴影。此外,该问题是“ XY问题”的一个示例,您应该很熟悉。
blujay

mp4box是一个FOSS工具并不重要。该问题使用ffmpeg而不是mp4box寻求答案。
jramos775

@ thvs86我就是一个例子。我使用ffmpeg,因为它是媒体的真正瑞士刀。我还会在我的特定用例中寻求帮助,因为争论的结构可能非常复杂(此处的各种答案都证明了这一点)。这是我第一次听说mp4box,如果不是这个答案的话,我不会找到它。因此,请我+1,请更多地考虑人们在寻找答案,而不是无意义的互联网观点和严格的规则。
帕维尔

4

这是我制作的脚本,用于将多个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}

这不是串联的。该代码不连接输入,而是对其重新编码。这将获取任意视频文件,并将它们更改为通用的音频和视频比特率(无论源文件的原始比特率或原始帧大小如何)。o / p希望使用流复制来合并两个文件,而不是对其进行重新编码,因此这不能解决所提出的问题。
Ed999 '18

4

从此处的文档中: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

这种方法适用于所有平台。

我需要将其封装在跨平台脚本中的能力,因此我使用fluent-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!')
)

1
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

1
不只是发布答案,您还可以添加一些解释,以便对OP和以后的读者更好地理解该解决方案。
Balagurunathan Marimuthu

1
这创建了一个新的无声视频,两个输入彼此同时播放。我希望串联会创建一个视频,先播放input_1.mp4,然后再播放input_2.mp4
Alexx Roche

3
这完全是错误的答案。这并没有吸引视频,只是像@AlexxRoche提到的那样静静地并排播放它们。
卡洛夫·陶里恩

1

合并当前目录中的所有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

我将此代码复制到记事本,什么也没有发生。
7vujy0f0hy

1
@ 7vujy0f0hy这可以在带有bash shell的Linux上使用,也许可以与cygwin一起使用
Pipo 18'July

1

经过下面的各种尝试,脚本在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'

第三,四行检查ffmpeg在路径中是否可用,并创建“ joined.mp4”

与其他答案的主要区别如下

usage  of -bsf:v hevc_mp4toannexb -an

对于上面的mp4文件,您可能需要根据视频编码使用如下所示的其他替代方法。

h264_mp4toannexb

所有此类可能的比特流过滤器都可以在https://ffmpeg.org/ffmpeg-bitstream-filters.html上找到


我的MP4来自CCTV摄像机。没有该命令,对话将无法生成输出文件。我正在使用其网站上的最新ffmpeg。
rahul maindargi

0

这是我的方法,该方法使用命令替换和concat视频过滤器(包含完整的MP4文件)加入一个充满MP4文件的目录-认为其他人会从这种单一代码中受益,尤其是如果您有很多文件(我只是一口气加入了17个文件):

ffmpeg $(for f in *.mp4 ; do echo -n "-i $f "; done) -filter_complex \
"$(i=0 ; for f in *.mp4 ; do echo -n "[$i:v] [$i:a] " ; i=$((i+1)) ; done \
&& echo "concat=n=$i:v=1:a=1 [v] [a]")" -map "[v]" -map "[a]" output.mp4

注意,此命令按照文件的命名顺序(即,如果您运行它们,则显示的顺序)将文件连接在一起ls *.mp4-在我的情况下,它们每个都有一个轨道号,因此效果很好。


0

这里描述的concat协议; https://trac.ffmpeg.org/wiki/Concatenate#protocol

使用命名管道实现以避免中间文件时

速度非常快(读取:即时),没有丢帧,并且运行良好。

切记删除命名的管道文件,并切记检查视频是否为H264和AAC ffmpeg -i filename.mp4(只需使用即可)(检查h264和aac是否提及)


-1

以可重用的PowerShell脚本的形式接受的答案

Param(
[string]$WildcardFilePath,
[string]$OutFilePath
)
try
{
    $tempFile = [System.IO.Path]::GetTempFileName()
    Get-ChildItem -path $wildcardFilePath | foreach  { "file '$_'" } | Out-File -FilePath $tempFile -Encoding ascii
    ffmpeg.exe -safe 0 -f concat -i $tempFile -c copy $outFilePath
}
finally
{
    Remove-Item $tempFile
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.