2025年2月24日 星期一 甲辰(龙)年 腊月廿四 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

python --moviepy合成视频加转场效果(淡入淡出),FFmepg,取首帧

时间:08-15来源:作者:点击数:69

文章介绍了如何使用Python的Moviepy库来实现视频的拼接,特别是创建叠化转场效果,以及如何通过VideoFileClip、fx、fadein、fadeout等函数进行视频的淡入淡出处理。同时,文章还提到了FFmpeg命令行工具在视频拼接和添加淡入淡出效果方面的应用,提供了多个示例代码。

摘要由CSDN通过智能技术生成

自己实现

  • from moviepy.editor import *
  • # 输入 1.mp42.mp4,返回他们拼接的成品(带叠化效果)
  • def diehua(file_1, file_2):
  • clip_1 = VideoFileClip(file_1)
  • clip_2 = VideoFileClip(file_2)
  • # 将这两个视频分成3部分,第一部分为纯 1.mp4 的部分,第二部分为 1.mp4 和 2.mp4 叠加的部分,第三部分为纯 2.mp4 的部分
  • magic_time = 0.5 # 设置叠化转场时长
  • duration_video1 = clip_1.duration # 片段1时长
  • duration_video2 = clip_2.duration # 片段2时长
  • part1 = clip_1.subclip(0, duration_video1 - magic_time) # 片段1截取
  • part3 = clip_2.subclip(magic_time, duration_video2) # 片段2截取
  • part2_1 = clip_1.subclip(duration_video1 - magic_time, duration_video1) # 片段1的最后0.5
  • part2_2 = clip_2.subclip(0, magic_time) # 片段2的开始0.5
  • # 将第二部分(1.mp4和2.mp4叠加的部分)分成10份,每份时长尽量保持一致,超过10份会明显卡顿一下,未探究原因
  • part2_1_1 = part2_1.subclip(0, 0.05)
  • part2_1_2 = part2_1.subclip(0.05, 0.1)
  • part2_1_3 = part2_1.subclip(0.10, 0.15)
  • part2_1_4 = part2_1.subclip(0.15, 0.2)
  • part2_1_5 = part2_1.subclip(0.2, 0.25)
  • part2_1_6 = part2_1.subclip(0.25, 0.3)
  • part2_1_7 = part2_1.subclip(0.3, 0.35)
  • part2_1_8 = part2_1.subclip(0.35, 0.4)
  • part2_1_9 = part2_1.subclip(0.4, 0.45)
  • part2_1_10 = part2_1.subclip(0.45, 0.5)
  • part2_2_1 = part2_2.subclip(0, 0.05)
  • part2_2_2 = part2_2.subclip(0.05, 0.1)
  • part2_2_3 = part2_2.subclip(0.1, 0.15)
  • part2_2_4 = part2_2.subclip(0.15, 0.2)
  • part2_2_5 = part2_2.subclip(0.2, 0.25)
  • part2_2_6 = part2_2.subclip(0.25, 0.3)
  • part2_2_7 = part2_2.subclip(0.3, 0.35)
  • part2_2_8 = part2_2.subclip(0.35, 0.4)
  • part2_2_9 = part2_2.subclip(0.4, 0.45)
  • part2_2_10 = part2_2.subclip(0.45, 0.5)
  • # 将 part2_1 和 part2_2 叠加视频合成 part2,2个部分通过控制不同时间不同透明度完成叠化效果
  • # 其中第二个参数处于上面一层,通过把前面的片段放在上面一层,再逐渐降低他的不透明度(就是让前面的片段慢慢变透明),来让下面一层的后面的片段慢慢浮现出来,产生片段叠加效果
  • F_part2_1 = CompositeVideoClip([part2_2_1, part2_1_1.set_opacity(0.95)])
  • F_part2_2 = CompositeVideoClip([part2_2_2, part2_1_2.set_opacity(0.85)])
  • F_part2_3 = CompositeVideoClip([part2_2_3, part2_1_3.set_opacity(0.75)])
  • F_part2_4 = CompositeVideoClip([part2_2_4, part2_1_4.set_opacity(0.65)])
  • F_part2_5 = CompositeVideoClip([part2_2_5, part2_1_5.set_opacity(0.55)])
  • F_part2_6 = CompositeVideoClip([part2_2_6, part2_1_6.set_opacity(0.45)])
  • F_part2_7 = CompositeVideoClip([part2_2_7, part2_1_7.set_opacity(0.35)])
  • F_part2_8 = CompositeVideoClip([part2_2_8, part2_1_8.set_opacity(0.25)])
  • F_part2_9 = CompositeVideoClip([part2_2_9, part2_1_9.set_opacity(0.15)])
  • F_part2_10 = CompositeVideoClip([part2_2_10, part2_1_10.set_opacity(0.05)])
  • # 拼接视频片段
  • video1 = concatenate_videoclips(
  • [F_part2_1, F_part2_2, F_part2_3, F_part2_4, F_part2_5, F_part2_6, F_part2_7, F_part2_8, F_part2_9, F_part2_10])
  • # 拼接视频片段
  • video2 = concatenate_videoclips([part1, video1, part3])
  • video2.write_videofile('8.mp4')
  • diehua(r'12.mp4', '13.mp4')

moviepy实现

示例一:

  • from moviepy.editor import *
  • clip = VideoFileClip(r"F:\video\fansNote1M_crop.mp4")
  • clipColorx = clip.fx(vfx.fadein,15)
  • clipColorx.write_videofile (r"F:\video\fansNote1M_fadein.mp4")

上述四行代码实现Moviepy模块的加载、然后读入视频文件、对视频前15秒进行淡入处理、输出调整后视频到结果视频文件。以上四行代码也可以精简为如下两行:

  • from moviepy.editor import *
  • VideoFileClip(r"F:\video\fansNote1M_crop.mp4").fx(vfx.fadein,15).write_videofile (r"F:\video\fansNote1M_fadein.mp4")

淡出处理类似,只要把函数fadein改成fadeout,并调整时间参数即可。

MoviePy是一个用于视频编辑的Python模块,可用于进行视频的基本操作(如剪切、连接、标题插入)、视频合成(也称非线性编辑)、视频处理或创建高级效果。它可以读写最常见的视频格式,包括GIF。MoviePy能处理的视频是ffmpeg格式的,理解支持的文件类型至少包括:*.mp4 *.wmv *.rm *.avi *.flv *.webm *.wav *rmvb。

MoviePy使用ffmpeg读取、导出视频和音频文件,使用ImageMagick生成文本和输出GIF文件。Python的快速数字库Numpy保证了不同媒体的处理。高级效果和增强使用了Python的许多图像处理库(PIL、Scikit-image、scipy等)。

moviepy的核心对象是剪辑(clips),包括AudioClips 和VideoClips。它们可以修改(剪切、减速、变暗…)或与剪辑混合以形成新剪辑,可以使用PyGame或IPython Notebook预览,并可以输出到对应类型的文件(如MP4、GIF、 MP3等)。例如,VideoClips可以从视频文件、图像、文本或自定义动画创建。VideoClips可以有一个音频轨道(这是一个AudioClip)和一个mask(一个特殊的VideoClip,指示当剪辑与其他剪辑混合时要隐藏哪些部分)。

上述代码涉及到的相关函数包括VideoFileClip、fx、fadein、write_videofile,其中:

VideoFileClip实际上是一个类,用于从视频文件装载视频到内存

fx函数是Moviepy剪辑基类Clip的方法,fx方法是用于执行参数指定的函数,并返回该参数对应函数的执行结果

fadein用于调整剪辑的淡入,对应的要进行淡出处理使用fadeout,注意时间参数t的含义是淡入处理是从开头到t时刻的视频进行淡入处理,淡出是从t时刻开始到结尾进行淡出处理

write_videofile用于将剪辑内容输出到视频文件

示例二:

  • import moviepy.editor as mp
  • # 定义视频淡入淡出效果的时长
  • fade_duration = 1
  • # 加载需要合并的视频片段
  • clip1 = mp.VideoFileClip("video1.mp4").fadein(fade_duration).crossfadein(fade_duration)
  • clip2 = mp.VideoFileClip("video2.mp4").fadein(fade_duration).crossfadein(fade_duration)
  • clip3 = mp.VideoFileClip("video3.mp4").fadein(fade_duration).crossfadein(fade_duration)
  • # 合并视频片段
  • final_clip = mp.concatenate_videoclips([clip1, clip2, clip3])
  • # 保存合并后的视频
  • final_clip.write_videofile("final_video.mp4")
  • ```

以上代码使用了moviepy库,先定义了淡入淡出效果的时长,然后通过VideoFileClip加载需要合并的视频片段。对于每个视频片段,使用fadein方法和crossfadein方法增加淡入淡出效果。通过concatenate_videoclips方法将所有视频片段合并起来,最后使用write_videofile方法保存合并后的视频。

FFmpeg

以下是使用 Python 和 FFmpeg 合并视频并添加淡入淡出效果的代码示例:

示例一:

  • import subprocess
  • # 定义视频文件路径
  • input_files = ["video1.mp4", "video2.mp4", "video3.mp4", "video4.mp4"]
  • # 定义输出文件名
  • output_file = "merged_video.mp4"
  • # 定义淡入淡出时长(秒)
  • fade_duration = 1
  • # 使用 subprocess 调用 FFmpeg 命令进行合并和转换
  • command = (
  • f"ffmpeg -y " # 覆盖同名输出文件
  • f"-i concat:{'|'.join(input_files)} " # 拼接输入文件
  • f"-filter_complex " # 加入过渡效果
  • # 第一个输入视频不加淡入效果
  • f"[0:v]fade=out:st={int(fade_duration)}:d={int(fade_duration)},fade=in:st=0:d={int(fade_duration)}[v0]; "
  • # 中间输入视频添加淡入淡出效果
  • f"{';'.join([f"[{i}:v]fade=out:st={int(fade_duration)}:d={int(fade_duration)},"
  • f"fade=in:st=0:d={int(fade_duration)}[v{i}]" for i in range(1, len(input_files) - 1)])}; "
  • # 最后一个输入视频不加淡出效果
  • f"[{len(input_files) - 1}:v]fade=out:st={int(fade_duration)}:d={int(fade_duration)}[v{len(input_files) - 1}]; "
  • # 串联各视频的效果处理结果
  • f"[v0]"
  • f"{';'.join([f"[v{i}]concat=n=1:v=0:a=1[v{i + 1}]" for i in range(len(input_files) - 1)])} "
  • f"-map [v{len(input_files)}] -map 0:a " # 仅输出视频流和第一个输入文件的音频流
  • f"-c:v libx264 -preset veryfast -crf 18 " # 视频编码参数
  • f"-c:a copy {output_file}" # 音频不用转换,直接拷贝
  • )
  • subprocess.call(command, shell=True)

这个代码使用 FFmpeg 对多个视频进行拼接,并且在视频之间添加淡入淡出效果,最后生成一个新的视频文件。你可以根据实际需求修改上述代码中的视频文件路径、输出文件名和淡入淡出时长等参数。

示例二:

  • ffmpeg \
  • -i video1.mp4 \
  • -i video2.mp4 \
  • -i video3.mp4 \
  • -filter_complex \
  • "[0:v]fade=in:st=0:d=1:alpha=1,fade=out:st=8:d=1:alpha=1[fade1]; \
  • [1:v]fade=in:st=0:d=1:alpha=1,fade=out:st=8:d=1:alpha=1[fade2]; \
  • [2:v]fade=in:st=0:d=1:alpha=1,fade=out:st=8:d=1:alpha=1[fade3]; \
  • [fade1][1:v]overlay=shortest=1[over1]; \
  • [over1][fade2][2:v]overlay=shortest=1[over2]" \
  • -c:v libx264 -crf 18 -preset veryfast -y final_video.mp4

以上代码使用了FFmpeg,先指定需要合并的视频文件,然后通过filter_complex参数定义每个视频片段的淡入淡出效果。每个视频片段使用fade滤镜增加淡入淡出效果,overlay滤镜实现视频片段的切换。在overlay滤镜中指定shortest=1参数,可以确保所有视频片段的长度相等。

最后,通过-c:v libx264 -crf 18 -preset veryfast -y参数指定输出视频的编码格式、画质、压缩速度和覆盖文件等信息。执行以上命令后,输出合并后的视频文件final_video.mp4

示例三

  • ffmpeg \
  • -i video1.mp4 \
  • -i video2.mp4 \
  • -i video3.mp4 \
  • -filter_complex \
  • "[0:v]fade=t=in:st=0:d=1:alpha=1,fade=t=out:st=8:d=1:alpha=1[v1]; \
  • [1:v]fade=t=in:st=0:d=1:alpha=1,fade=t=out:st=8:d=1:alpha=1[v2]; \
  • [2:v]fade=t=in:st=0:d=1:alpha=1,fade=t=out:st=8:d=1:alpha=1[v3]; \
  • [v1][v2][v3]concat=n=3:v=1:a=0,fade=t=out:st=28:d=1:alpha=1[v]" \
  • -map "[v]" -c:v libx264 -crf 18 -preset veryfast -y final_video.mp4

以上代码同样使用了FFmpeg,使用filter_complex参数定义每个视频片段的淡入淡出效果。每个视频片段同样使用fade滤镜增加淡入淡出效果,使用concat滤镜将多个视频片段合并为一个,并在最后一个片段处增加一个淡出效果。

最后,通过-map参数指定合并后的视频流,并通过-c:v libx264 -crf 18 -preset veryfast -y参数指定输出视频的编码格式、画质、压缩速度和覆盖文件等信息。执行以上命令后,输出合并后的视频文件final_video.mp4

取视频首帧

  • from moviepy.editor import VideoFileClip
  • # 读取视频文件
  • video_path = "path_to_your_video_file.mp4"
  • video = VideoFileClip(video_path)
  • # 提取视频的第一帧
  • first_frame = video.get_frame(0)
  • # 保存第一帧图像
  • first_frame_path = "path_to_save_first_frame.png"
  • first_frame.save_frame(first_frame_path)
  • # 关闭视频对象
  • video.close()
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐