CCF BDCI 文心大模型创意项目】中秋款文心带你轻松搞定MV制作

本文涉及的产品
交互式建模 PAI-DSW,5000CU*H 3个月
简介: CCF BDCI 文心大模型创意项目】中秋款文心带你轻松搞定MV制作

项目背景

这个项目的启发,当然是来自我们无敌的磊哥


ninetailskim


看到磊哥用剪辑软件做出来的MV,我想着,我们可以用python来实现一款相对自动化的全流程MV生成工具。


在这里项目,我们只需要放入歌曲and歌曲的lrc文件以及一张首页图即可得到最终的MV

话不多说,肝着!


导入一些必备的包

# 用来剪切音频和转换mp3为wav
!pip install pydub
!pip install moviepy
!pip install auditok


文本处理

我们要拿到音频的时间点,以及文本,才能去进行一个文生图


我本来写了一个自动智能化根据静默时间切分音频的代码,结果,因为歌曲有背景曲效果很差,那就算了吧


有兴趣尝试自动切分音频并提取文本的可以参考我之前的项目:

[PaddleSpeech]助力视频字幕生成演讲稿提取


这里直接使用Lrc文件看效果,后续找到解决方案再去实现这个坑

目标:

  1. 时间节点
  2. 时间节点对应的文本


时间节点、歌词 获取

# 暂时没有找到比较合适的文本提取并且找到对应时间戳的工具
# 已有的 import auditok auditok.split这样的效果都不好
# 我暂且我找的歌曲的Lrc歌词文件
def readLrc(path = '水调歌头.lrc'):
    lines = []
    texts = []
    f = open(path,'r')
    while True:
        line = f.readline()  #包括换行符
        line = line[:-1]   #去掉换行符
        if line:
            if ('.' in line):
                timeMin = line.strip().split(']')[0][1:3]
                timeSec = line.strip().split(']')[0][4:6]
                text = line.strip().split(']')[1]
                lines.append([timeMin,timeSec])
                texts.append(text)
        else:
            break
    f.close()
    return lines,texts
info,text = readLrc('水调歌头.lrc')
print(info[0])
['00', '01']
text
['水调歌头',
 '作詞∶苏轼',
 '作曲∶梁弘志',
 '演唱∶王菲',
 '明月几时有  把酒问青天',
 '不知天上宫阙 今夕是何年',
 '我欲乘风归去 唯恐琼楼玉宇',
 '高处不胜寒 起舞弄清影 何似在人间',
 '转朱阁 低绮户 照无眠',
 '不应有恨 何事长向别时圆',
 '人有悲欢离合 月有阴晴圆缺',
 '此事古难全 但愿人长久 千里共婵娟',
 '^_^  ~~~MUSIC~~~  ^_^',
 '我欲乘风归去 唯恐琼楼玉宇',
 '高处不胜寒 起舞弄清影 何似在人间',
 '转朱阁 低绮户 照无眠',
 '不应有恨 何事长向别时圆(别时圆)',
 '人有悲欢离合 月有阴晴圆缺',
 '此事古难全 但愿人长久 千里共婵娟',
 '~END']


文心大模型

AK和SK的获取:

https://wenxin.baidu.com/moduleApi/key

当然因为这里要生成很多的图片,要等待很久!


生成图片

!pip install wenxin-api
from tqdm import tqdm
import wenxin_api
from wenxin_api.tasks.text_to_image import TextToImage
# 下面我们安装并导入ernie_vilg模块
# 因为需要发送请求,并等待数据返回,所以,会很慢,这取决于歌词条目的数量
pro= [] # 记录单片段歌词
def get_img(texts):
    # 你的prompt 我这里发现用逗号连接词语效果更佳
    # text_prompt = "程序员,写代码"
    imgs = []
    img_num = [] # 统计这一行歌词生成了几张图片的列表
    for i in tqdm(range(len(texts))):
        t = texts[i].replace(' ',',').split(',')
        img_num.append(len(t))
        for j in t:
            pro.append(j)
            text_prompt = j + ',圆月亮,夜晚,古风'
            wenxin_api.ak = "RgCyG5U1o9CsRr2T9exS4F47TZCgswnV"
            wenxin_api.sk = "PobN54TGDMwuFY0iens5bqsQWQxq8F44"
            input_dict = {
                "text": text_prompt,
                "style": "油画"
            }
            rst = TextToImage.create(**input_dict)
            imgs.append(rst['imgUrls'][0])
    return imgs,img_num
img_list,img_num = get_img(text)


下载图片

import requests
import os
from PIL import Image
import matplotlib.pyplot as plt
%matplotlib inline
# 生成存图的目录
def init_mkdir(data_path):
    if not os.path.exists(data_path): # 判断文件夹是否存在
        os.makedirs(data_path) # 不存在则新建文件夹
init_mkdir('output-img')
# 展示生成的图片并保存
for i in range(len(img_list)):
    #使用requests直接get 下载图片使用
    r = requests.get(img_list[i])
    ii = '%02d'%i +'.png'
    out_ii = 'output-img/' + ii
    with open(out_ii, 'wb') as f:
        f.write(r.content)
    f.close()
    img_ = Image.open(out_ii)
    plt.show()
    plt.imshow(img_) 


import os
import cv2
file_dir = 'output-img'
# 返回path下所有文件构成的一个list列表
filelist = os.listdir(file_dir)
# 保证读取按照文件的顺序
filelist.sort()
if ('.ipynb_checkpoints' in filelist):
    del filelist[0]
print(filelist)
['00.png', '01.png', '02.png', '03.png', '04.png', '05.png', '06.png', '07.png', '08.png', '09.png', '10.png', '11.png', '12.png', '13.png', '14.png', '15.png', '16.png', '17.png', '18.png', '19.png', '20.png', '21.png', '22.png', '23.png', '24.png', '25.png', '26.png', '27.png', '28.png', '29.png', '30.png', '31.png', '32.png', '33.png', '34.png', '35.png', '36.png', '37.png', '38.png', '39.png', '40.png', '41.png', '42.png', '43.png', '44.png']


图片加歌词

给图片加歌词

每一张图片的歌词如下:

前面以及存储过了

pro变量中

from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw
font = ImageFont.truetype("simhei.ttf",58)#设置字体和字体大小
font1 = ImageFont.truetype("STHUPO.TTF",36)#设置字体和字体大小
font2 = ImageFont.truetype("STXINGKA.TTF",55)#设置字体和字体大小
changed = 'output-text-img'
init_mkdir(changed)
def addTexttoImg():
    for i in range(len(pro)):
        imageFile = file_dir + '/' + filelist[i]
        tp=Image.open(imageFile)
        # 在图片上添加文字
        draw = ImageDraw.Draw(tp)
        draw.text((50, 50),'本歌曲由文心大模型生成图片',(255, 153, 0),font=font1) #分别设置文字的xy坐标,文字内容,文字颜色,字体
        draw.text((100, 850),pro[i],(0, 153, 255),font=font2) #分别设置文字的xy坐标,文字内容,文字颜色,字体
        draw.text((102, 852),pro[i],(255,255,255),font=font2) #分别设置文字的xy坐标,文字内容,文字颜色,字体
        draw = ImageDraw.Draw(tp)
        # 保存
        tp.save(changed + '/' + filelist[i]) #图片保存路径
addTexttoImg()


视频生成

这里是真的花了我好多的时间去设计如何让时间节点把所有的歌词对应的比较完美一些

处理时间节点

这个时间决定了我们需要插入多少张图片

PS 先知: 这里我们可以设置视频的帧数为5,后续视频生成也会用的到

因为我们图片不多

其次,要计算好时间需要多少张图片

如下:

# 总共262秒左右
4*60+22
262
# 我们最终需要1310张的图片才行
5*262
1310


生成策略

合成视频

我这里采取的策略是一秒的五帧都是相同的图片

然后我们上面有提取的时间节点,卡点加入后面的图片

# 时间序列
info
[['00', '01'],
 ['00', '04'],
 ['00', '06'],
 ['00', '08'],
 ['00', '11'],
 ['00', '22'],
 ['00', '32'],
 ['00', '44'],
 ['01', '03'],
 ['01', '14'],
 ['01', '27'],
 ['01', '38'],
 ['01', '56'],
 ['02', '27'],
 ['02', '38'],
 ['02', '57'],
 ['03', '08'],
 ['03', '30'],
 ['03', '41'],
 ['04', '15']]
# 求出每个时间段需要多少张图片
time_img = []
start = 0
for i in info:
    # 时间差
    end = int(i[0])*60 +int(i[1])
    time_img.append((end-start)*5)
    start = end
time_img.append(7*5) # 最后一段不要忘记了
sum(time_img)
1310
# 第一段时间留给首页 一秒 删除第一段,我们自行加首页,我已经放在了左侧的目录中
del time_img[0]


综上

我们的处理逻辑如下:

375e0b5a74094b7fbc57f544085b155e.png

此外:我采取时间段内的图片均分填充


视频所需要的图片列表

import os
import cv2
#造新的图片列表 1310 + 5(首页面) 张的
new_list = []
for i in range(5):
    new_list.append("home.png")
num = 0
#  0-20          
for j in range(len(time_img)): # 总共有多少个时间段 len(time_img) = 21 同时,前面还记录了每个时间段有多少张图片,就是 img_num
    #  0-5             5
    #  0-15           15
    for n in range(time_img[j]): # 每个时间段需要多少张图片
        if (img_num[j] == 1):
            new_list.append(changed + '/' + filelist[sum(img_num[:j])])
        if (img_num[j] == 2):
            if (n < (time_img[j]//2)):
                new_list.append(changed + '/' + filelist[sum(img_num[:j])])
            else:
                new_list.append(changed + '/' + filelist[sum(img_num[:j])+1])
        if (img_num[j] == 3):
            if (n < (time_img[j]//3)):
                new_list.append(changed + '/' + filelist[sum(img_num[:j])])
            elif (n < (time_img[j]//3)*2):
                new_list.append(changed + '/' + filelist[sum(img_num[:j])+1])
            else:
                new_list.append(changed + '/' + filelist[sum(img_num[:j])+2])
        if (img_num[j] == 5):
            if (n < (time_img[j]//5)):
                new_list.append(changed + '/' + filelist[sum(img_num[:j])])
            elif (n < (time_img[j]//5)*2):
                new_list.append(changed + '/' + filelist[sum(img_num[:j])+1])
            elif (n < (time_img[j]//5)*3):
                new_list.append(changed + '/' + filelist[sum(img_num[:j])+2])
            elif (n < (time_img[j]//5)*4):
                new_list.append(changed + '/' + filelist[sum(img_num[:j])+3])
            else:
                new_list.append(changed + '/' + filelist[sum(img_num[:j])+4])
new_list


len(new_list)
1310


图片列表转视频

import cv2
# VideoWriter是cv2库提供的视频保存方法,将合成的视频保存到该路径中
# 'MJPG'意思是支持jpg格式图片
# fps = 5代表视频的帧频为5,如果图片不多,帧频最好设置的小一点
# (1280,720)是生成的视频像素1280*720,一般要与所使用的图片像素大小一致,否则生成的视频无法播放
# 定义保存视频目录名称和压缩格式,像素为1280*720
video = cv2.VideoWriter('test.mp4',cv2.VideoWriter_fourcc(*'mp4v'),5,(1080,980))
for i in range(len(new_list)):
    #读取图片
    img = cv2.imread(new_list[i]) 
    # resize方法是cv2库提供的更改像素大小的方法
    # 将图片转换为1024*720像素大小
    img = cv2.resize(img,(1080,980))
    # 写入视频
    video.write(img)
# 释放资源
video.release()


音视频合并

from moviepy import *
from moviepy.editor import *
# pip install moviepy
def merge():
    video_path = 'test.mp4'
    audio_path = 'sdgt_wf.mp3'
    # 提取音轨
    audio = AudioFileClip(audio_path)
    # 读入视频
    video = VideoFileClip(video_path)
    # 将音轨合并到视频中
    video = video.set_audio(audio)
    # 输出
    video.write_videofile(f"output.mp4")
if __name__ == '__main__':
deo = video.set_audio(audio)
    # 输出
    video.write_videofile(f"output.mp4")
if __name__ == '__main__':
    merge()


项目总结

整个 项目的流程完成还是非常的费事

  1. 文本的提取
  2. 图片的生成
  3. 文本合并
  4. 图片列表生成
  5. 视频合成
  6. 音频合成

目前的视频生成还没有做到全自动,并且细节是不够完善的

相关文章
|
3月前
|
机器学习/深度学习 人工智能 搜索推荐
小红书开源「InstantID」,2024第一个爆火的Al写真项目,惊艳了!
小红书开源「InstantID」,2024第一个爆火的Al写真项目,惊艳了!
128 0
|
3月前
|
安全
Baidu千帆大模型赋能——儿童读物——科普故事42
Baidu千帆大模型赋能——儿童读物——科普故事42
19 0
|
3月前
|
安全
Baidu千帆大模型赋能——儿童读物——科普故事47
Baidu千帆大模型赋能——儿童读物——科普故事47
32 0
|
3月前
|
安全
Baidu千帆大模型赋能——儿童读物——科普故事48
Baidu千帆大模型赋能——儿童读物——科普故事48
20 0
|
6月前
|
人工智能 数据可视化
用了这8款AI制作PPT软件,年终总结再也不是问题!
8款好用的AI生成PPT软件推荐,轻松解决你的年终总结!
|
5月前
|
人工智能 IDE 开发工具
生成古风少女图片【InsCode Stable Diffusion美图活动一期】
生成古风少女图片【InsCode Stable Diffusion美图活动一期】
54 0
|
10月前
|
人工智能 算法 Ubuntu
【朱颜不曾改,芳菲万户香。AIGC人物图片创作---InsCode Stable Diffusion 美图活动一期】
【朱颜不曾改,芳菲万户香。AIGC人物图片创作---InsCode Stable Diffusion 美图活动一期】
573 2
|
12月前
|
人工智能 自然语言处理 大数据
GPT-4充当评测老师,效果惊艳,港中文(深圳)开源凤凰、Chimera等大模型
GPT-4充当评测老师,效果惊艳,港中文(深圳)开源凤凰、Chimera等大模型
148 0
|
12月前
|
人工智能 区块链
聊聊学习制作游戏的方法,以及最近大火的ChatGPT
先跟着入门课程把基础知识掌握好,把工具使用熟练,学习做游戏最重要的是动手做,尽可能完成每节课程后面的实践练习,只有做的多了,知识才能掌握的扎实,才能更快的入门。
126 0
|
12月前
|
机器学习/深度学习 人工智能 数据可视化
CVPR 2022 | 北大、腾讯提出文字logo生成模型,脑洞大开堪比设计师
CVPR 2022 | 北大、腾讯提出文字logo生成模型,脑洞大开堪比设计师
157 0