moviepy自动化制作美食视频

根据公司需要,最近需要制作大量的食谱和美食视频,代码如下:

from moviepy.editor import *
import pandas as pd
from TTS import TTS
import time,random,requests,os,re

#遍历文件夹,找出所有mp4,flv视频或者jpg,png图片或者acc,mp3音频文件

def func(filepath,form_lst,clip_path = []):
    files = os.listdir(filepath)#查看当前目录中的文件
    #print(files)
    for file in files:#拿到每一个文件名

        file_p = os.path.join(filepath,file)#形成文件的地址
        # print(file_p)
        file_name = file_p.split('.')

        if os.path.isdir(file_p):#如果文件是文件夹
            clip_path = func(file_p,form_lst,clip_path = clip_path)
        elif file_name[-1] in form_lst:
            file_p = os.path.normpath(file_p)
            clip_path.append(file_p)
            # print(clip_path)
        else:
            continue
    return clip_path

def get_img(url,f_path, count = 0, max_count = 3):

    ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36'
    headers = {'User-Agent':f'{ua}'}
    try:
        time.sleep(random.random() * 3)
        r = requests.get(url=url, headers=headers, timeout=30)
        # r.raise_for_status()
        # r.encoding = 'utf-8'
        # print(r.text)
        with open(f_path, 'wb') as f:
            f.write(r.content)
        return f_path
    except:
        count += 1
        print(f'第{count}次爬取{url}失败')
        time.sleep(30)
        if count < max_count:
            return get_img(url=url, count=count)

def add_logo(clip):
    #给视频加水印

    logo = (TextClip("制作:轩轩和格格",font='SIMYOU.TTF',fontsize=30,color='white',bg_color='white',stroke_color='pink',stroke_width=2,method='label')
            .set_duration(clip.duration)  # 水印持续时间
            .resize(height=50)  # 水印的高度,会等比缩放
            .margin(left=40, bottom=40, opacity=0) # 水印边距和透明度
            .set_pos(("right", "bottom")))  # 水印的位置

    clip_add_logo = CompositeVideoClip([clip, logo])
    return clip_add_logo

def make_mp4(caipu_title_img,caipu_name,caipu_material,caipu_step_img,caipu_step_txt):
    # 定义画面尺寸和帧率
    h, w ,fps= 720, 1280,30
    #语音带#读不了报错,需要先去掉
    caipu_material = re.sub('[#]','',caipu_material)
    caipu_step_txt = re.sub('[#]','',caipu_step_txt)
    # windows路径名不能含有特殊字符,因此我们在菜谱名字里面去掉,方便后面使用作为保存文件名
    caipu_name = re.sub('[#\/:*?"<>|]', '', caipu_name)
    if len(caipu_name) > 12:
        caipu_name0 = caipu_name[:12]
    else:
        caipu_name0 = caipu_name
    # print(caipu_name0)
    f_path = os.path.normpath(f'./babyfood/{caipu_name}')
    if not os.path.exists(f_path):
        os.makedirs(f_path)
    # 1镜头:片头.封面背景
    #片头语音
    voice_begin = random.choice(func(filepath='./片头', form_lst=['mp3']))
    voice_begin = AudioFileClip(voice_begin)
    #食谱名字语音
    TTS(caipu_name, f_path + '\\name.mp3')
    voice_name = AudioFileClip(f_path + '\\name.mp3')
    #组合成开场语音
    voice0 = concatenate_audioclips([voice_begin,voice_name])
    #语音时长决定视频时长
    t0 = voice0.duration
    #片头背景图
    bg_img = random.choice(func(filepath='./封面', form_lst=['png', 'jpg', 'jpeg']))
    # 片头背景图实例化
    bg_img_cover = ImageClip(bg_img, duration=t0).resize(width=w)
    # 片头主图
    # 保存链接上的标题图到本地电脑,获取本地地址
    title_img = get_img(url=caipu_title_img, f_path=f_path + '\\title_img.jpg')
    print(title_img)
    #片头主图实例化
    Img_cover = ImageClip(title_img, duration=t0)
    # 片头标题
    text_cover = TextClip(caipu_name0, font='titlehupo.TTF', fontsize=100, color='white').set_position(
        'center').set_duration(t0)
    # 片头视频片段,无声音
    clip0 = CompositeVideoClip([bg_img_cover, Img_cover, text_cover]).set_audio(voice0).resize(width=w, height=h)
    # 给片头片段加logo
    clip0 = add_logo(clip=clip0)
    # 所有镜头都保存到列表里,方便后面连接起来组合最终视频
    clip_steps = [clip0]

    # 2镜头:第一段主体视频:菜谱名称,沿用封面的参数或者用主题参数,方便后续调整单独列出.

    # # 第1个主镜头的语音:名称
    # TTS(caipu_name, f_path + '\\name.mp3')
    # voice1 = AudioFileClip(f_path + '\\name.mp3')
    # t1 = voice1.duration
    # # 镜头由背景图\主图\字幕三个图层构成,视频时长都根据语音时长来定
    # bg_img1 = ImageClip(bg_img, duration=t1).resize(width=w)
    # Img1 = ImageClip(title_img, duration=t1)
    # Img1 = add_logo(Img1).set_position("center").resize(width=w)
    # text1 = TextClip(caipu_name0, font='titlehupo.TTF', fontsize=100, color='white').set_position(
    #     'center').set_duration(t1)
    #
    # clip1 = CompositeVideoClip([bg_img1, Img1, text1]).set_audio(voice1).resize(width=w, height=h)
    # clip_steps.append(clip1)

    # # 第2个主镜头的语音:所需食材(所需食材最好再分解成小片段)
    # n = 0
    # for caipu_mt in caipu_material.split(';'):
    #     if caipu_mt == None:
    #         continue
    #     n += 1
    #     TTS(caipu_mt, f_path + f'\\material{n}.mp3')
    #     voice2 = AudioFileClip(f_path + f'\\material{n}.mp3')
    #     # 语音时长决定视频时长
    #     t2 = voice2.duration
    #     # 镜头由背景图\主图\字幕三个图层构成,视频时长都根据语音时长来定
    #     bg_img2 = ImageClip(bg_img, duration=t2).resize(width=w)
    #     Img2 = ImageClip(title_img, duration=t2)
    #     Img2 = add_logo(Img2).set_position('center').resize(width=w * 0.6)
    #     text2 = TextClip(caipu_mt, font='SIMYOU.TTF', fontsize=20, color='white').margin(bottom=50,
    #                                                                                      opacity=0).set_position(
    #         'bottom').set_duration(t2)
    #     clip2 = CompositeVideoClip([bg_img2, Img2, text2]).set_audio(voice2).resize(width=w, height=h)
    #     clip_steps.append(clip2)

    i = 0
    # 每一个操作步骤做成一个片段
    for step_img_url, step_txts in zip(caipu_step_img.split(';'), caipu_step_txt.split(';')):
        # 如果末尾是符号,分割出来的就会是None,需要过掉
        if step_img_url == '' or step_txts == '':
            continue
        print(step_img_url)
        step_img = get_img(url=step_img_url, f_path=f_path + f'\\step{i}.jpg')
        #把所需食材加到第一个步骤里面
        if i == 0:
            step_txts = step_txts.split(',') + ['食材清单:'] + caipu_material.split(';')
        else:
            step_txts = step_txts.split(',')

        for step_txt in step_txts:
            # 如果末尾是符号,分割出来的就会是None,需要过掉
            if step_txt == '':
                continue
            i += 1
            # 步骤语音
            TTS(step_txt, f_path + f'\\step{i}.mp3')
            voice3 = AudioFileClip(f_path + f'\\step{i}.mp3')

            # 背景图
            bg_img3 = ImageClip(bg_img, duration=voice3.duration).resize(width=w)
            # 步骤图从网络连接保存到本地,获取本地地址

            # 步骤主图
            img3 = ImageClip(step_img, duration=voice3.duration)
            img3 = add_logo(img3).set_position('center').resize(width=w * 0.6)
            # 步骤文字
            text3 = TextClip(step_txt, font='SIMYOU.TTF', fontsize=20, color='white').margin(bottom=50,
                                                                                             opacity=0).set_position(
                'bottom').set_duration(voice3.duration)
            # 步骤视频片段
            clip_step = CompositeVideoClip([bg_img3, img3, text3]).set_audio(voice3).resize(width=w, height=h)

            # 步骤的片段都加到列表里面去
            clip_steps.append(clip_step)

    # 形成主体视频
    main_clip = concatenate_videoclips(clip_steps, method='compose').resize(width=w, height=h)

    # 获取视频的配音
    main_audio = main_clip.audio
    # 添加背景音乐和片尾
    bg_music = random.choice(func(filepath='背景音乐', form_lst=['mp3'], clip_path=[]))
    print(bg_music)
    background_music = AudioFileClip(bg_music)

    # 设置背景音乐循环,时间与视频时间一致

    bg_audio = afx.audio_loop(background_music, duration=main_clip.duration)

    # 视频声音和背景音乐,音频叠加

    audio_clip_add = CompositeAudioClip([main_audio.volumex(1.5), bg_audio.volumex(0.3)]).set_duration(
        main_clip.duration)

    # 视频写入背景音

    main_video = main_clip.set_audio(audio_clip_add)

    clip_tail = VideoFileClip(random.choice(func(filepath='./片尾', form_lst=['mp4'], clip_path=[]))).resize(width=w,
                                                                                                             height=h)

    final_clip = concatenate_videoclips([main_video, clip_tail], method='compose').resize(width=w, height=h)

    date = time.strftime('%Y%m%d', time.localtime())

    out_put_path = f'./out_put'
    if not os.path.exists(out_put_path):
        os.mkdir(out_put_path)
    final_clip.write_videofile(f'{out_put_path}/{date}{count}{caipu_name}.mp4', bitrate='1800k', fps=fps)

def main(count):

    #对原素材进行处理一下问题

    # caipu = pd.read_excel('caipu20221205.xlsx')
    #
    # caipu_names = caipu['宝宝辅食菜谱名称']
    # caipu_materials = caipu['所需食材']
    # caipu_step_txts = caipu['制作步骤文字说明']
    # caipu_step_imgs = caipu['制作步骤配图']
    # caipu_title_imgs = caipu['菜谱主图']
    # for i in range(101):
    #     caipu['菜谱主图'][i] = str(caipu_step_imgs[i]).split(';')[-1]
    #
    # for i in range(len(caipu_names)):
    #     caipu['制作步骤文字说明'][i] =  str(caipu['制作步骤文字说明'][i]).replace(' ','').replace('\t','')
    #     caipu['所需食材'][i] = str(caipu['所需食材'][i]).replace(' ','')
    #
    # caipu.to_excel('baby_caipu.xlsx', sheet_name="baby_caipu", index=False)

    #处理字幕和图片

    caipu = pd.read_excel('baby_caipu.xlsx')

    caipu_title_imgs = caipu['菜谱主图']
    caipu_names = caipu['宝宝辅食菜谱名称']
    caipu_materials = caipu['所需食材']

    caipu_step_imgs = caipu['制作步骤配图']
    caipu_step_txts = caipu['制作步骤文字说明']


    for caipu_title_img,caipu_name,caipu_material,caipu_step_img,caipu_step_txt in list(zip(caipu_title_imgs,caipu_names,caipu_materials,caipu_step_imgs,caipu_step_txts))[::-1][count:]:
        time.sleep(random.random() * 2)
        if all([caipu_title_img, caipu_name, caipu_material, caipu_step_img, caipu_step_txt]) == False:
            continue
        try:
            make_mp4(caipu_title_img=caipu_title_img,caipu_name=caipu_name,caipu_material=caipu_material,caipu_step_img=caipu_step_img,caipu_step_txt=caipu_step_txt)
        except:
            print(f'第{count}个视频出错,重新执行')
            main(count=count)
        print(f'今日已完成第{count}个视频')
        count += 1

if __name__ =='__main__':
    count = 26
    main(count=count)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值