自己实现

from moviepy.editor import *


# 输入 1.mp4 和 2.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()
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐