作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一系列名为“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
删除了音频因为我稍后会添加音轨。我在这里看到的问题是,我正在使用添加到编辑中的每个单独的视频文件一遍又一遍地压缩视频,因为我一次只添加一个视频,然后重新编码。
最佳答案
您可以通过首先使用一对 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/2
和
d
是每个文件的持续时间。三个输出选项(
pix_fmt
、
r
和
enc_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/
我是一名优秀的程序员,十分优秀!