moviepy 简介

MoviePy是一个用于视频修改的Python模块,它可被用于一些根本操作(如剪切、拼接、刺进标题)、视频合成(即非线性修改)、视频处理和创立高档特效。它可对大多数常见视频格式进行读写(来源于官方文档)【底层是使用 ffmpeg进行操作视频和音频,使用ImageMagick进行操作图片】

由此可知,咱们能够通过一些图片,视频等资料,能够自动化的批量生成一大批无脑视频

脚本传送门

目录结构

利用moviepy批量生成营销号视频

将案牍转成语音

将准备好的脚本文件写入 content.txt 中,将脚本转成音频

文字转语音有现成的大量方案,本文使用Google的gtts进行将文字转语音,先将脚本文件中按照标点符号离隔进行转成每一个语音,然后使用 ffmpeg 将语速调快至本来的1.2倍(本来转出来的太慢了),并核算每一句话的播映时长,用来均匀核算每一张图片应该播映多少秒,文件名包括每一句话的案牍【用来做字幕,播映时长】

一件件令人惊叹的作品在他的手中诞生_duration_5.000000.mp3

代码所示

def text_to_voice():
    try:
        shutil.rmtree('./tts')
        os.mkdir('./tts')
    except:
        pass
    voice = []
    content = open('content.txt').read()
    contents = re.split(r'[。!??,,]', content)
    for content in contents:
        content = content.strip()
        if not len(content):
            continue
        filename = './tts/%s.mp3' % content
        # 转语音
        g_tts = gTTS(content, lang='zh-CN')
        g_tts.save(filename)
        # 调整语速 为 1.2 倍速
        sound = AudioSegment.from_mp3(filename)
        duration = int(sound.duration_seconds)
        update_speed_filename = './tts/%s_duration_%f.mp3' % (content, math.ceil(duration * 0.85))
        cmd = "ffmpeg -y -i %s -filter_complex \"atempo=tempo=%s\" %s" % (filename, '1.2', update_speed_filename)
        res = subprocess.call(cmd, shell=True)
        if res == 0:
            os.remove(filename)
        voice.append(update_speed_filename)
        print(update_speed_filename)
    return voice

获取一切图片

def get_all_files(path):
    files = []
    for root, dirs, filenames in os.walk(path):
        for filename in filenames:
            files.append(os.path.join(root, filename))
    return files

将图片格式化为固定大小

def resize_images(image_path):
    # 打开图片
    image = Image.open(image_path)
    width = 1400  # 固定宽度
    height = 787  # 固定高度
    # 核算缩放份额
    original_width, original_height = image.size
    scale = min(width / original_width, height / original_height)
    # 核算缩放后的大小
    new_width = int(original_width * scale)
    new_height = int(original_height * scale)
    # 缩放图片
    image = image.resize((new_width, new_height))
    # 创立新的画布
    canvas = Image.new('RGB', (width, height), (0, 0, 0))
    # 核算居中方位
    x = (width - new_width) // 2
    y = (height - new_height) // 2
    # 将缩放后的图片粘贴到画布上
    canvas.paste(image, (x, y))
    # 保存图片
    canvas.save(image_path)

将图片转成视频,并加上背景音乐,解说和字幕

def handle_movie(voice = []):
    # 核算一切语音的长度,得出需要视频的长度
    duration_clips, text_clips = [], []
    for item in voice:
        filename = str(item.split('/')[-1])
        tmp = filename.split('_')
        text_clips.append(tmp[0])
        duration_clips.append(float(tmp[-1].replace('.mp3', '')))
    duration = sum(duration_clips)
    # 背景音乐
    bg_music = AudioFileClip("./bgm/1.MP3").set_duration(duration).volumex(0.3)
    # 解说 + 字幕
    voice_clips, txt_clips = [], []
    for idx, item in enumerate(text_clips):
        start = sum(duration_clips[:idx])
        end = start + duration_clips[idx]
        voice_clips.append(
            AudioFileClip(voice[idx]).set_start(start).volumex(0.8))
        txt_clip = TextClip(text_clips[idx], fontsize=10, color='black', font='兰亭黑-中黑')
        txt_clip = txt_clip.set_pos('bottom').set_duration(duration_clips[idx]).crossfadein(1).crossfadeout(1)
        txt_clip = txt_clip.set_start(start).set_end(end)
        txt_clips.append(txt_clip)
    picture_path = './pictures'
    # 定义每张图片的编排,并增加淡入淡出作用
    images = get_all_files(picture_path)
    # 将图片格式化
    for image in images:
        # 将图片变成 16:9  高度787.5 ,宽度1400
        resize_images(image)
    image_num = len(images)
    image_duration = duration / image_num
    image_clips = []
    # 镜头焦点作用
    def resize_func(t):
        return 1 + 0.005 * t
    # screensize = (640, 360)
    for image_path in get_all_files('./pictures'):
        image_clip = ImageClip(image_path).set_duration(image_duration).resize(resize_func).set_position(('center', 'center')).set_fps(25)
        image_clip = image_clip.crossfadein(1).crossfadeout(1)
        image_clips.append(image_clip)
    # 将一切图片编排合并为一个编排
    image_clip = concatenate_videoclips(image_clips)
    # 将图画、字幕和音频编排合并为一个编排,并增加淡入淡出作用
    video_clip = CompositeVideoClip([image_clip] + txt_clips)
    audio_clip = CompositeAudioClip([bg_music] + voice_clips)
    video_clip = video_clip.set_audio(audio_clip)
    video_clip = video_clip.crossfadein(1).crossfadeout(1)
    # 导出视频编排
    video_clip.write_videofile("video.mp4", fps=24)

遇到的坑

  1. 背景音乐时长要大于视频时长,否则会报错(能够优化处理,使用ffmpeg进行将背景音乐循环)
  2. 设置的时分字体要电脑有的字体,否则或许中文或许无法打印

结语

详细代码已上传github传送门,具体目录结构和代码运行看readm.md

有问题或改善的能够联系 1105504520@qq.com