如何合并文件夹中的所有视频以使用 FFMPEG 制作单个视频文件

Posted

技术标签:

【中文标题】如何合并文件夹中的所有视频以使用 FFMPEG 制作单个视频文件【英文标题】:How can I merge all the videos in a folder to make a single video file using FFMPEG 【发布时间】:2015-05-09 10:46:43 【问题描述】:

我有一个包含 20 多个视频文件的文件夹,我需要将它们合并以制作一个长视频文件。如何在 Python 中使用 FFMPEG 实现这一点?

我知道以下命令

ffmpeg -vcodec copy -isync -i \ "concat:file1.mp4|file2.mp4|...|fileN.mp4" \

输出文件.mp4

但我宁愿不要输入 20 多个文件的所有名称。

【问题讨论】:

【参考方案1】:

这就是我最终使用的......

find *.mp4 | sed 's:\ :\\\ :g'| sed 's/^/file /' > fl.txt; ffmpeg -f concat -i fl.txt -c copy output.mp4; rm fl.txt

它的丑陋让我很痛苦,但它似乎工作正常,它可以处理文件名中的空格。此外,不知道为什么 OP 询问 python - 当一些肮脏的旧 bash/sed 可以解决问题时,不需要使用像 python 这样可爱的东西! ;)

ps:我知道这是一篇旧帖子,但如果谷歌搜索“ffmpeg concat”把我带到这里,它可能也会把其他可怜的灵魂也带到这里。请注意,仅当您的所有文件都具有相同的设置/编解码器时,上述方法才可能有效。

pps:@Stackdave 说他当年设法用这个删除了他的视频文件夹!我真的不知道这是怎么发生的,从那以后我就再也没有抱怨过,但是在复制和粘贴您在互联网上发现的随机 bash 的随机 sn-ps 时一如既往地告诫 Emptor!

【讨论】:

我已经用你的脚本删除了文件夹 video 上的所有文件!警告 很抱歉听到戴夫的消息! reddit.com/r/ProgrammerHumor/comments/7u92m8/…【参考方案2】:

可以是单行 bash 命令:

for f in *.mp4 ; do echo file \'$f\' >> list.txt; done && ffmpeg -f concat -safe 0 -i list.txt -c copy stitched-video.mp4 && rm list.txt

确保所有视频文件的帧大小和音频-视频编解码器完全相同。

否则,您可以在连接时转换它们:

for f in *.mp4 ; do echo file \'$f\' >> list.txt; done && ffmpeg -f concat -safe 0 -i list.txt -s 1280x720 -crf 24 stitched-video.mp4 && rm list.txt

【讨论】:

谢谢洛根。固定。 这对我有用。始终可以安全地使用第二个命令进行转换和连接。谢谢。 谢谢!我有一个视频列表,如video-1.mp4video-2.mp4video-10.mp4...,以及需要排序的文件。这里是用混合字符串和数字对文件进行排序的版本:rm list.txt; for f in *.mp4 ; do echo file \'$f\' >> list.txt; done && sort -V list.txt > list-sort.txt && ffmpeg -f concat -safe 0 -i list-sort.txt -c copy stitched-video.mp4 ; rm list.txt list-sort.txt【参考方案3】:

这是一个 Windows 批处理文件,用于连接目录中的所有 .avi 文件:

for %%f in (*.avi) do (
    echo file %%f >> list.txt
)
ffmpeg -f concat -safe 0 -i list.txt -c copy output.avi
del list.txt

请参阅 ffmpeg 文档中的 Concatenate。

【讨论】:

很遗憾,我正在处理的文件的文件名中有空格。 echo file "%%f" >> list.txt 还不够。 cmd 一旦遇到第一个空格字符就会停止。 NVM,以下帮助,superuser.com/questions/1574718/…。代替双引号,使用单引号,回显文件 '%%f' >> list.txt,然后在 for 功能块之后和语句“ffmpeg -f concat -safe...”之前,将以下语句放在其上自己的行,sed -i "s/\"/'/g" list.txt【参考方案4】:

使用这个:

cat *.mp4  | ffmpeg  -i pipe: -c:a copy -c:v copy all.mp4

【讨论】:

Windows 无法唤醒【参考方案5】:

如果 ffmpeg 不喜欢 *.mp4,你可以这样做来代替文件列表;

ls -1 *.mp4 | perl -0pe 's/\n/|/g;s/\|$//g'

但我认为您的示例未遵循 specification,因此您可能想要这个:

for F in *.mp4 ; do
    ffmpeg -i $F -c copy -bsf:v h264_mp4toannexb -f mpegts $(echo $F | perl -pe 's/mp4$/ts/g');
done
ffmpeg -i "concat:$(ls -1 *.ts | perl -0pe 's/\n/|/g;s/\|$//g')" -c copy -bsf:a aac_adtstoasc outputfile.mp4

也可以看到类似的question

【讨论】:

或者只是echo *.mp4 | tr ' ' '|',如果您的文件名称中没有空格。【参考方案6】:

我知道最初的问题是关于 Python 的,但是当我询问时,Google 把我带到了这里。实际上我不记得确切的查询。

首先,文件应具有以下格式:

file 'filename1.mp4'
file 'filename2.mp4' 
file 'filename3.mp4'

等等。

接下来,Java (Mac) 中的解决方案:

public static void joinVideos(String folderPath) throws Exception 
    File folderFile = new File(folderPath);
    //File[] files = folderFile.listFiles();
    //On Mac filter out .DS_Store
    File[] files = folderFile.listFiles(new FilenameFilter() 
        @Override
        public boolean accept(File dir, String name) 
            return !name.equals(".DS_Store");
        
    );
    StringBuilder fileListBuilder = new StringBuilder();
    for (File file : files) 
        fileListBuilder.append("file '").append(file.getName()).append("'\n");
    
    ReadWriteUtil.writeTxt(fileListBuilder.toString(), folderPath + File.separator + "list.txt");

    ProcessBuilder processBuilder = new ProcessBuilder("/usr/local/bin/ffmpeg", "-f", "concat", "-i", "list.txt", "-c", "copy", "output.mp4");
    File errorFile = new File(folderPath + File.separator + "error.txt");
    processBuilder.redirectError(errorFile);

    Process process = processBuilder.directory(new File(folderPath)).start();

    int exitCode = process.waitFor();
    String error = ReadWriteUtil.readFileAsString(errorFile);
    System.out.println("error: " + error);
    System.out.println("VideoJoiner Finished with exit code: " + exitCode);
    System.out.println("videos joined");


【讨论】:

以上是关于如何合并文件夹中的所有视频以使用 FFMPEG 制作单个视频文件的主要内容,如果未能解决你的问题,请参考以下文章

关于ffmpeg推流,如何推流一个文件夹里的所有视频或者多个视频?

ffmpeg合并视频命令报错总结

ffmpeg合并视频命令报错总结

FFmpeg 命令行工具ffmpeg

如何使用ffmpeg进行音视频裁剪命令和音视频合成命令

如何在Pytube中组合音频和视频?