我有一个包含20多个视频文件的文件夹,我需要将它们合并成一个长视频文件。如何在Python中使用FFMPEG来实现这一点?我知道以下命令
ffmpeg -vcodec copy -isync -i \ "concat:file1.mp4|file2.mp4|...|fileN.mp4" \
outputfile.mp4但我宁愿不键入所有的20多个文件的名称。
k75qkfdt1#
这是我最后用的...
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你在互联网上找到的警告Emptor!
vohkndzv2#
可以是单行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
g6ll5ycj3#
下面是一个Windows批处理文件,用于连接目录中的所有.avi文件:
.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。
i2loujxw4#
使用此选项:
cat *.mp4 | ffmpeg -i pipe: -c:a copy -c:v copy all.mp4
其他解决方案:
创建如下文本文件:mylist.txt
file '/path/to/file1' file '/path/to/file2' file '/path/to/file3'
并使用FFMPEG连接:
ffmpeg -f concat -i mylist.txt -c copy all.mp4
更多信息
olmpazwi5#
如果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
c2e8gylq6#
我知道最初问题是关于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"); }
polkgigr7#
Windows操作系统解决方案:1.在目标文件夹中打开cmd.exe1.粘贴并运行此代码
chcp 65001 (for %i in (*.mp4) do @echo file '%i') > my_video_list.txt ffmpeg -safe 0 -f concat -i my_video_list.txt -c copy output.mp4
7条答案
按热度按时间k75qkfdt1#
这是我最后用的...
它的丑陋让我很痛苦,但它似乎工作得很好,它处理文件名中的空格。还有,不知道OP为什么要问python --当一些肮脏的旧bash/sed就能达到目的时,没有必要使用像python这样可爱的东西!)
ps:我知道这是一个老帖子,但如果谷歌“ffmpeg concat”把我带到这里,它可能会把其他可怜的灵魂也带到这里。注意,以上可能只会工作,如果你所有的文件都有相同的设置/编解码器。
pps:@Stackdave说他设法删除了他的视频文件夹与此早在一天!我真的不知道怎么会发生,我没有抱怨,因为,但一如既往,当复制和粘贴随机片段的bash你在互联网上找到的警告Emptor!
vohkndzv2#
可以是单行bash命令:
请确保所有视频文件的帧大小和音频-视频编解码器完全相同。
否则,您可以在连接时转换它们:
g6ll5ycj3#
下面是一个Windows批处理文件,用于连接目录中的所有
.avi
文件:请参阅ffmpeg文件中的Concatenate。
i2loujxw4#
使用此选项:
其他解决方案:
创建如下文本文件:
mylist.txt
并使用FFMPEG连接:
更多信息
olmpazwi5#
如果ffmpeg不喜欢 *.mp4,你可以用这个代替文件列表;
但我认为您的示例没有遵循specification,因此您可能需要这样做:
另请参见类似的question
c2e8gylq6#
我知道最初问题是关于Python的,但Google让我来到这里,当我问到..实际上我不记得确切的查询。
首先,文件应具有以下格式:
和/或其他信息。
接下来是Java(Mac)中的解决方案:
polkgigr7#
Windows操作系统解决方案:
1.在目标文件夹中打开cmd.exe
1.粘贴并运行此代码