【问题标题】:FFMPEG Concatenate X video at time from a list.txtFFMPEG 从 list.txt 一次连接 X 视频
【发布时间】:2020-02-20 15:56:30
【问题描述】:

我正在尝试从 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

【问题讨论】:

    标签: python ffmpeg


    【解决方案1】:

    从 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))
    

    需要注意的是,有 better ways 可以读取文件,但据我所知,我认为您需要一个快速脚本来将多个文件连接在一起。所以 f.readlines() 应该不是问题

    【讨论】:

    • 我整个下午都在研究你的代码,现在我正在尝试对连接文件使用过滤器:os.system('''ffmpeg -loglevel error -r 30 -i sfondo/bkg.png -i ./clip/{}.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 错误:s
    • p.s postFileName 是postFileName = os.path.splitext(outputBaseName)[0]
    • 在最后一次os.system() 调用中,您将字符串分成多个部分。因此,当您最后使用'''" ./media/{}.mp4 "'''.format(outputFileName,postFileName)) 时,它只会将./media/{}.mp4 替换为format() 中的第一个参数。要调试该行,您可以将 os.system() 替换为旧的 print() 以检查出了什么问题。如果您已经连接了文件,最好单独处理过滤器而不是重复使用相同的脚本,因为这将再次进行连接。
    猜你喜欢
    • 2012-03-09
    • 1970-01-01
    • 2020-07-28
    • 2012-10-02
    • 2013-08-29
    • 2016-09-06
    • 2016-05-25
    • 2023-04-06
    • 1970-01-01
    相关资源
    最近更新 更多