python - FFMPEG 从 list.txt 一次连接 X 视频
问题描述
我正在尝试从 list.txt 一次连接 3 个视频,我可以将列表中的所有视频连接成一个长视频,但我希望将列表中的 x 个视频连接到一个输出中,然后连接下一个x 来自同一列表的视频在另一个输出中,依此类推。
我正在开发的脚本是用 python 编写的,它从服务器获取一些视频并将它们保存在本地文件夹中并写入我的 concat.txt,然后 ffmpeg 读取 concat.txt 并创建单个 output.mp4
#this merge all video in concat file in a single output
os.system("ffmpeg -f concat -i downloaded/concat.txt -safe 1 -r 30 -fflags +genpts -c:a copy downloaded/output.mp4")
我正在寻找一种方法让 ffmpeg 从 concat.txt 读取第一个 x 行,将它们连接到 output1.mp4 中,然后从 cancat.txt 读取下一个 x 行,将它们连接到 output2.mp4 等等。
感谢您花时间帮助我,我真的很感激!
---编辑感谢@Tejas的回复,我解决了如何拆分concat.txt文件,现在我正在尝试对每个剪辑应用过滤器
import os
x = 3 #Number of files you want to concatenate
#Making directories so that the working directory stays organized
txtFileName = "./splits/output{}.txt"
outputFile = "./clip/output{}.mp4"
postFile = "./media/post{}.mp4"
os.makedirs(os.path.dirname(txtFileName), exist_ok=True)
os.makedirs(os.path.dirname(outputFile), exist_ok=True)
os.makedirs(os.path.dirname(postFile), exist_ok=True)
#While splitting the files store their path to a list
listofSplitFiles = []
with open('./downloaded/concat.txt','r') as concat:
lines = concat.readlines()
for i in range(0,lines.__len__()//x):
with open(txtFileName.format(i+1),'w') as split:
listofSplitFiles.append(txtFileName.format(i+1))
for j in range(0,x):
if( (i*x)+j < lines.__len__() ):
split.write(lines[(i*x)+j])
#Call ffmpeg on the list
for i in listofSplitFiles:
outputBaseName = os.path.basename(i)
outputFileName = os.path.splitext(outputBaseName)[0]
postFileName = os.path.splitext(outputBaseName)[0]
os.system("ffmpeg -f concat -i {} -safe 1 -r 30 -fflags +genpts -c:a copy ./clip/{}.mp4".format(i,outputFileName))
os.system('''ffmpeg -loglevel error -r 30 -i sfondo/bkg.png -i ./clip/output{}.mp4 -b:v 1M -filter_complex ''' + '''"[1:v]scale=''' + "750" + ''':''' + "1080" + ''' [ovrl], [0:v][ovrl]overlay=(main_w-overlay_w)/2:((main_h-overlay_h)/2)"''' + ''' ./media/{}.mp4''' .format(outputFileName,postFileName))
不幸的是我有这个错误./clip/{}.mp4: No such file or directory
解决方案
从 ffmpeg concat 的文档看来,它会读取 txt 文件中的整个文件列表并将它们连接成一个文件。所以你可以做的是使用 python 读取你的 concat.txt,将三行放入不同的文本文件,然后你可以在这些文件上运行 ffmpeg。像这样:
import os
x = 3 #Number of files you want to concatenate
#Making directories so that the working directory stays organized
txtFileName = "./splits/output{}.txt"
outputFile = "./output/output{}.mp4"
os.makedirs(os.path.dirname(txtFileName), exist_ok=True)
os.makedirs(os.path.dirname(outputFile), exist_ok=True)
#While splitting the files store their path to a list
listofSplitFiles = []
with open('./concat.txt','r') as concat:
lines = concat.readlines()
for i in range(0,lines.__len__()//x):
with open(txtFileName.format(i+1),'w') as split:
listofSplitFiles.append(txtFileName.format(i+1))
for j in range(0,x):
if( (i*x)+j < lines.__len__() ):
split.write(lines[(i*x)+j])
#Call ffmpeg on the list
for i in listofSplitFiles:
outputBaseName = os.path.basename(i)
outputFileName = os.path.splitext(outputBaseName)[0]
os.system("ffmpeg -f concat -i {} -safe 1 -r 30 -fflags +genpts -c:a copy ./output/{}.mp4".format(i,outputFileName))
不过需要注意的是,有更好的方法来读取文件,但据我所知,我认为您需要一个快速脚本来将多个文件连接在一起。所以 f.readlines() 应该不是问题
推荐阅读
- python-3.x - fastai.text NameError:未定义名称“BaseTokenizer”
- laravel - 如何在 laravel 雄辩的 selectRaw 方法中使用子查询?
- javascript - YT.Player 不适用于多个视频、javascript
- batch-file - Windows 10. 文件批处理中的错误 if 和 else
- php - 双引号和单引号 PHP
- django - 使用viewets.ModelViewSet视图更新Django rest框架模型中的外键
- flutter - 错误状态:使用 IOWebSocketChannel 时已监听 Stream
- c# - FontFamily 导入不适用于 Visual Studio 中的 C# Xamarin
- javascript - 你能在 JavaScript 中将一个变量声明为另一个变量的内容吗?
- r - cor() 热图也考虑了滞后?