Python实现vlog生成器的示例代码
虚坏叔叔 人气:0Python实现vlog生成器
vlog,全称为Video blog,意为影音博客,也有翻译为微录。
本文将尝试用Python基于Moviepy从一个文本文件中自动生成一个视频格式的vlog,实现的功能如下:
- 将文件的第一行标题生成视频的片头
- 将文件中图片和文字转成视频并生成音频和字幕
- 将文件中视频片段或gif拼接到视频中
- 自动添加一个片尾
效果如下:
1. 文本格式
平时习惯用markdown进行写作,所以这里也选择markdown作为文本格式。定义格式如下:
- 第一行为视频的标题
- 从第二行开始是视频的内容
- 视频内容分两种格式,一种图片加文字,一种视频或gif。第一种是一张图片后面加一行文字说明,视频或gif没有文字说明
接下来按上面的格式实现代码。
2. 内容解析
第一步是将markdown解析成Python的一个字典对象。字典对象包括*标题(title)和内容(content)*两部分。标题是一个文本值,内容是一个列表,包括一些图片加文字或视频片段。
解析过程如下:
2.1 读取文件,将第一行去除不需要的字符作为标题;
2.2 遍历文件,提取文件后缀,根据文件后缀判断是否是视频还是图片,如果是图片就将下一行作为解说文字;
2.3 不断解析直至文件结束。
代码如下:
def parse(filename): result = { "title": "", "content": [] } with open(filename) as f: lines = f.readlines() title = lines[0].strip('#').strip() result['title'] = title content = list(filter(lambda x: x.strip() != '', lines[1:])) print(content) i = 0 while i < len(content): s = content[i] link = s[s.find("(")+1:s.find(")")] text = s[s.find("[") + 1:s.find("]")] i += 1 if link.endswith(".mp4") or link.endswith(".gif"): result['content'].append({ 'link': link, 'text': text, 'type': 'video' }) else: subtitle = content[i].strip() i += 1 result['content'].append({ 'link': link, 'text': text, 'subtitle': subtitle, 'type': 'image' }) return result
3. 生成片头
解析完成后开始根据内容生成视频,先用标题生成片头并添加动态效果,代码如下:
def generate_title(title): print(f"title: {title}") def cascade(screenpos, i): v = np.array([0, -1]) d = lambda t: 1 if t < 0 else abs(np.sinc(t) / (1 + t ** 4)) return lambda t: screenpos + v * 400 * d(t - 0.15 * i) def move_letters(letters, funcpos): return [letter.set_pos(funcpos(letter.screenpos, i)) for i, letter in enumerate(letters)] size = (1280, 720) title_clip = TextClip(title, color=config.TITLE['color'], font=config.TITLE['font'], kerning=5, fontsize=config.TITLE['font-size']) cvc = CompositeVideoClip([title_clip.set_pos('center')], size=size) letters = findObjects(cvc) clip = CompositeVideoClip(move_letters(letters, cascade), size=size).subclip(0, 5) return clip
4.视频片段生成
片头之后是内容片段的生成,内容片段如果是视频直接读取即可,如果是图片需要将图片配上语音并添加字幕,代码如下:
def generate_clip_with_subtitle(image_path, text): print(f"clip text: {text}") clip = ImageClip(image_path) audio = AudioFileClip(text2wav(text)) txt_clip = TextClip(text.replace(" ", ""), font=config.SUBTITLE['font'], color=config.SUBTITLE['color'], fontsize=config.SUBTITLE['font-size']) vtuber_clip = get_vtuber(audio.duration) video = CompositeVideoClip([clip, txt_clip.set_pos(('center', 'bottom')), vtuber_clip.set_pos(('right', 'bottom'))]) video.audio = audio video.duration = audio.duration return video
5.生成片尾
内容片段生成完成后,再添加一个简单的片尾,这里添一个加文字片尾,代码如下:
def generate_ending(text="听说点赞带来好运"): print(f"ending: {text}") size = (1280, 720) title_clip = TextClip(text, color=config.ENDING['color'], font=config.ENDING['font'], kerning=5, fontsize=config.ENDING['font-size']) clip = CompositeVideoClip([title_clip.set_pos('center')], size=size) clip.duration = 1 return clip
6.完整视频合成
最后就是整合上面的代码,并将上面生成视频片段合并成一个完整的视频,代码如下:
def generate_vlog(filename, output_path): clips = [] result = parser.parse(filename) title_clip = generate_title(result['title']) clips.append(title_clip) for item in result['content']: if item['text']: clips.append(generate_text_clip(item['text'])) if item['type'] == 'image': clips.append(generate_clip_with_subtitle(item['link'], item['subtitle'])) elif item['type'] == 'video': clips.append(load_video(item['link'])) clips.append(generate_ending()) video = concatenate_videoclips(clips, method="compose") video.write_videofile(output_path, fps=24, audio_codec="aac")
加载全部内容