原文链接:cloud.tencent.com/developer/a…
布景
最近萌生了一个想法,便是短视频给人传递信息的速度要远远超越枯燥无味的文字,而众所周知,短视频也是媒体人花费许多经历所创造出来的。
我猜测大概的过程是这样的:
- 选取一个好的题材
- 更具题材写一篇稿子
- 经过稿子里边的一些关键字来搜索一些和主题相关的图片资料,或许电影的片段。
- 然后根据以上内容,经过一些视频剪辑东西,将资料和稿子兼并起来,然后在增加配音。
大概是上面这几个步骤就完成了一个短视频的输出,可能我上面描绘的过于清新,实际上,上面每一步都很浪费时刻,这也便是出一个精品不容易的原因。
那么,有没有想过,假如有现在有一封题材比较好的稿子,能否直接经过稿子生成短视频呢?
当你看到这篇文章的时分,那不好意思,这个想法已经完成了:这里是GitHub库房地址:github.com/bravekingzh…
原理
其完成原理能够大致的描绘一下:
- 将文本进行分段,现在没有想到好的方法,便是经过标点符号句号分段,分红一个个的语句
- 经过语句生成图片,生成声响,图片开源的有许多,本方案选用 stable-diffusion,言语转文字运用 edge-tts
- 在经过 opencv 将图片兼并为视频,现在输出 mp4 格局的视频,语句作为字母贴到视频内容的底部区域。
- 音频是一个有时刻概念的东西,刚好能够经过音频控制一张画面的播映时长
- 在经过 ffmpeg 将音频兼并到原始视频中。
最终,一个有画面,有字幕,有声响的视频就出现了,咱们完成了一个 文本转视频
。
作用
这个东西能够将一段文本转换为视频,并保存到指定的本地,初衷是想完成小说的可视化视频阅览。
if __name__ == '__main__':
text_test= '''
一个风和日丽的早上,我骑着自行车去校园,在路上遇到了彩虹,当时我的心情十分的愉快。
'''
convertTextToVideo(models[0], text_test)
仿制
文本转视频后的作用能够检查 demos/demo.mp4
细节
文字生成图片
文字生成图片,发现中文生成图片的作用不是很抱负,由于是运用开源社区的stable-diffusion 这些模型,我想假如接入百度的文心一言文字生成图片,也许作用会略微好点,毕竟某度仍是愈加懂中文的。
def generateImage(model, prompt):
body = {
"inputs": translate_to_english(prompt)
}
r = requests.post("https://api-inference.huggingface.co/models/" + model,
data=json.dumps(body), headers=headers)
# 将图片写入到 images 目录下,每个图片运用(时刻戳+model).png 来命名
timeStamp = str(int(time.time()))
imagePath = "images/" + timeStamp + \
"-" + model.split("/")[-1] + ".png"
with open(imagePath, "wb") as f:
f.write(r.content)
f.close()
voicePath = "voices/" + timeStamp + \
"-" + model.split("/")[-1] + ".mp3"
仿制
视频字幕
视频上字幕其实做了取巧,直接把文字贴在图片上,但是留意opencv 不太好处理中文字,对英文还算好,妥协之下仍是挑选了PIL库。留意字幕有长短,还有换行的处理,以及给字幕一些布景,由于,字幕色彩和图片相近,容易看不到字。以及怎样摆放。
for image_file in image_files:
if image_file.endswith(".png"):
text_color = (255, 255, 255) # 白色文字
background = (0, 0, 0,128) # 黑色布景半透明
image_path = "images/" + image_file
draw_text = sentences[image_files.index(image_file)]
add_text_to_image(draw_text, image_path,
text_color, background, padding=10)
image = cv2.imread(image_path)
resized_image = cv2.resize(image, (frame_width, frame_height))
output_video.write(resized_image)
# 增加停顿帧
duration = get_duration_from_vtt(
f"voices/{find_file_name_without_extension(image_file)}.mp3.vtt")
print(duration)
for _ in range(int(duration * 30)):
output_video.write(resized_image)
仿制
增加音频
音频直接是一语句转声响,这个有许多库能够用,但是免费的仍是edge-tts好用一些,作用会好一些,因而本项目选用edge-tts。
def convert_text_to_speech(text, output_file):
# 指定输出目录
output_directory = os.path.join(current_directory,"voices")
# 创建输出目录(假如不存在)
os.makedirs(output_directory, exist_ok=True)
# 执行命令,并将作业目录设置为输出目录
try:
command = ['edge-tts', '--voice', 'zh-CN-XiaoyiNeural', '--text', text, '--write-media', output_file, '--write-subtitles', f'{output_file}.vtt']
result = subprocess.run(command, cwd=current_directory, timeout=10)
print(result)
duration = get_duration_from_vtt(output_file + ".vtt")
# 删除 无效音频 or 从头生成?
if duration == 0.1:
os.remove(output_file + ".vtt")
os.remove(output_file)
except subprocess.CalledProcessError as e:
print("Command execution failed with return code:", e.returncode)
print("Command output:", e.output)
仿制
图片音频同步
图片怎么和播映的声响同步,这是一个有趣的问题,我们知道图片和声响都是经过语句生成的,而声响天然就有时长这个特点,因而,在融入视频的时分,根据这个时长来做停顿帧就能够了。
# 增加停顿帧
duration = get_duration_from_vtt(
f"voices/{find_file_name_without_extension(image_file)}.mp3.vtt")
print(duration)
for _ in range(int(duration * 30)):
output_video.write(resized_image)