gpt4 book ai didi

python - 有效地交叉淡入任意数量的视频ffmpeg

转载 作者:行者123 更新时间:2023-12-04 23:18:21 29 4
gpt4 key购买 nike

我有一系列名为“cut_xxx.mp4”的视频,其中 xxx 代表 000 到 999 之间的数字。我想对任意数量的视频进行交叉淡入淡出以创建汇编,每次淡入淡出应持续 4 秒。目前,我正在使用 Python 执行此操作,但我怀疑这不是最有效的方法:

import subprocess    
def get_length(filename):
result = subprocess.run(["ffprobe", "-v", "error", "-show_entries",
"format=duration", "-of",
"default=noprint_wrappers=1:nokey=1", filename],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
return float(result.stdout)

CROSS_FADE_DURATION = 4

basevideo = 'cut_000.mp4'
for ii in range(total_videos - 1):
fade_start = math.floor(get_length(basevideo) - CROSS_FADE_DURATION) # new one
outfile = f'cross_fade_{ii}.mp4'
append_video = f'cut_{str(ii+1).zfill(3)}.mp4'
cfcmd = f'ffmpeg -y -i {basevideo} -i {append_video} -filter_complex "xfade=offset={fade_start}:duration={CROSS_FADE_DURATION}" -an {outfile}'
basevideo = outfile
subprocess.call(cfcmd)
print(fade_start)
我专门用 -an 删除了音频因为我稍后会添加音轨。我在这里看到的问题是,我正在使用添加到编辑中的每个单独的视频文件一遍又一遍地压缩视频,因为我一次只添加一个视频,然后重新编码。
应该有一种方法可以将多个视频交叉淡入淡出到一个汇编中,但我不确定这会是什么样子,或者我如何让它适用于任意数量的不同持续时间的视频文件。关于那个整体 ffmppeg 命令的外观或者我如何在给定视频列表及其持续时间的情况下自动生成它的任何想法?

最佳答案

您可以通过首先使用一对 fade 重新编码每个文件来避免重复重新编码。过滤每个文件,后跟“concat-copy”。
第一步:

ffmpeg -in url_in -vf fade=in:d={t_fade},fade=out:st={d-t_fade}:d={t_fade} \
-pix_fmt yuv420p -r 25 -enc_time_base 0 -an url_out
在这里, t_fade = CROSS_FADE_DURATION/2d是每个文件的持续时间。三个输出选项( pix_fmtrenc_time_base )是下一步所有褪色文件的关键通用参数。使用适合您用例的 pix_fmt & r .
假设输出为 faded_cut_###.mp4那么你需要像这样编写一个 ffconcat 文本脚本文件:
ffconcat version 1.0
file faded_cut_000.mp4
file faded_cut_001.mp4
file faded_cut_002.mp4
file faded_cut_003.mp4
...
然后将它们全部结合起来,运行
ffmpeg -f concat -safe 0 -in {script} -c copy -y output.mp4
下面是我用我的 ffmpegio 测试它的方法包(如果有兴趣, pip install ffmpegio-core):
from os import path
from tempfile import TemporaryDirectory
import ffmpegio

srcfiles = [...] # list of source file paths

# get durations of the video (ffprobe calls)
# equivalent to: ffprobe -of default=nk=1:nw=1 -show_entries format=duration url
durs = [ffmpegio.probe.query(url, fields=("duration",))[0] for url in srcfiles]

print('video durations': durs)

# transcode with fading effects
def add_fades(url_in, url_out, d):
t_fade = 1 # duration of each half of cross fading
expr = f"fade=in:d={t_fade},fade=out:st={d-t_fade}:d={t_fade}"

ffmpegio.transcode(
url_in,
url_out,
vf=expr,
pix_fmt="yuv420p",
r=25,
enc_time_base=0,
an=None,
# show_log=True, # Omit/False to hide FFmpeg logs
)
# equivalent to
# ffmpeg -in url_in -vf expr -pix_fmt yuv420p -r 25 -enc_time_base 0 -an url_out

return url_out

# work in a temporary directory
with TemporaryDirectory() as tmpdir:
# tmpdir = "sandbox" # you may use a folder of your choice

# apply fading and get the urls of new video in tmpdir
faded_urls = [
add_fades(url, path.join(tmpdir, path.basename(url)), d)
for url, d in zip(srcfiles, durs)
]

# use concat muxer to copy-transcode
ffconcat = ffmpegio.FFConcat()
ffconcat.add_files(faded_urls)
with ffconcat: # creates the script file
print(ffconcat.script) # to see the script
ffmpegio.transcode(
ffconcat,
"output.mp4", # final output path here
f_in="concat",
c="copy",
safe_in=0,
overwrite=True, # adds -y
show_log=True, # False to hide FFmpeg logs
)
# equivalent to
# ffmpeg -f concat -safe 0 -in script -c copy -y output.mp4
[编辑:添加]
这双- fade解决方案与 xfade 不完全相同.如果你必须有真正的淡入淡出效果, add_fades需要修改为采用 2 个输入(主要和另一个在主视频结束时淡入)。这里的诀窍是确保正确拼接输入文件,以便在连接它们时获得平滑的过渡。

关于python - 有效地交叉淡入任意数量的视频ffmpeg,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71879841/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com