《趣学音视频》这段“朋友圈模版视频”的扛鼎之作是如何诞生的
大家好,这里是《趣学音视频》频道,我是ucsheep
欢迎大家点赞、评论、关注、分享
以上是一个“朋友圈视频模版”的扛鼎之作,整个视频散发着浓厚的朋友圈气息。熟悉的界面内,字里行间,抖着视频创作者的激灵。而中间大海波涛汹涌的动态画面,和耳畔的海浪声将观看者从颓靡的遐想中拉回现实,让观看者意识到“自己已经不是从前的自己”的残酷现实。
“长大”意味着什么?上面的视频给出了一个内涵且搞笑的答案。你看懂视频,摇摇头,会心一笑之时,是不是也有一丝伤怀——你已经和纯真、稚嫩彻底Bye-Bye。既然已经看到这篇文章,不妨让我告诉你:一个长大的工程师,也是时候学点音视频知识了。
在抖音上经常会刷到类似上面的“朋友圈”模版视频,搞笑的文案、搞笑的视频,辅之以神评,往往播放量惊人。经我稍加思索,认为此类视频可以使用软件进行傻瓜式、批量化地生成,将其发扬光大。如你所见,上面的视频,并不是录屏,也不是剪辑软件剪辑,而是我用程序合成的。只需提供文案和视频素材,这个程序就会生产出类似上面的视频。
今天我将会帮你学会:如何用程序自动地合成出这样的视频。本文的结尾,我也会分享完整的源码及相关程序。
1.功能分析

观察上面的视频截图,我们对此次开发的软件功能进行提炼。即,用户输入自定义文案和视频素材;程序将用户输入的文案渲染到视频背景中对应的区域,并且为背景内角色随机抽取头像,渲染到视频背景中各个角色的头像对应位置,最终将背景和视频素材合成,生产出目标视频。
1.1 用户输入
1.2 程序流程及输出
2.技术选择
根据需求,我们的技术重心分为背景图片合成及背景图与视频素材合成两部分。
其中背景图片合成部分,涉及图片与图片和合成、图片与文字的合成两种。我们采用Python的
背景图与视频素材合并,我们采用FFmpeg的
3.实现步骤
3.1 基础底图制作
基础底图,我们直接从朋友圈找一条视频,然后截图,使用

这张图将我们截取的图片尺寸根据竖版视频

我们将需要动态合成的区域分为3类:
图片类区域(
图片中用阿拉伯数字标注的1-10黑色区域 )

文本类区域(
图片中使用红框框起并使字母A-G的区域 )

视频区域

3.2 背景图合成
上面我成功制作了基础底图,并获取了所有合成所需参数。接下来就进行背景图制作。
3.2.1 头像渲染

我准备了1695个方形的头像图片,用于合成时随机调取。存放在
def getAvatarRandom():
totalList = os.listdir("res/avatar")
if len(totalList) == 9:
return totalList
randIndex = random.randint(0,len(totalList)-9)
return totalList[randIndex:randIndex+9]
在获取头像资源后,就需要在基础底图上渲染头像图片了。使用Pillow进行图像的合并,只需要像下面这样:
# 载入基础底图
bg_image = Image.open('res/bg.jpg')
# 载入头像图片1
avatar1 = Image.open('res/avatar/1.jpg')
# 缩放头像图片至指定尺寸
avatar1.thumbnail((72, 72))
# 在基础底图上的指定区域渲染头像图片1
bg_image.paste(avatar1, (19, 16))
# 预览合成效果
bg_image.show(bg_image)
# 将合成效果保存为图片
bg_image.save(fileName)
举一反三,随机获取所有头像资源并在背景底图上完成渲染的代码如下:
# 载入底图
bg_image = Image.open('res/bg.jpg')
# 随机获取9个头像并载入
aList = getAvatarRandom()
avatar1 = Image.open('res/avatar/' + aList[0])
avatar2 = Image.open('res/avatar/' + aList[1])
avatar3 = Image.open('res/avatar/' + aList[2])
avatar4 = Image.open('res/avatar/' + aList[3])
avatar5 = Image.open('res/avatar/' + aList[4])
avatar6 = Image.open('res/avatar/' + aList[5])
avatar7 = Image.open('res/avatar/' + aList[6])
avatar8 = Image.open('res/avatar/' + aList[7])
avatar9 = Image.open('res/avatar/' + aList[8])
# 渲染9个头像
avatar1.thumbnail((72, 72))
bg_image.paste(avatar1, (19, 16))
avatar1.thumbnail((63, 63))
bg_image.paste(avatar1, (73, 686))
avatar2.thumbnail((63, 63))
bg_image.paste(avatar2, (77, 491))
avatar3.thumbnail((63, 63))
bg_image.paste(avatar3, (148, 491))
avatar4.thumbnail((63, 63))
bg_image.paste(avatar4, (216, 491))
avatar5.thumbnail((63, 63))
bg_image.paste(avatar5, (286, 491))
avatar6.thumbnail((63, 63))
bg_image.paste(avatar6, (355, 491))
avatar7.thumbnail((63, 63))
bg_image.paste(avatar7, (425, 491))
avatar8.thumbnail((63, 63))
bg_image.paste(avatar8, (497, 491))
avatar9.thumbnail((63, 63))
bg_image.paste(avatar9, (73, 593))
最终效果如下

3.2.2 文本渲染
使用Pillow进行文本渲染也很简单:
# 生成一个画板
draw = ImageDraw.Draw(bg_image)
text1 = "长大就是当你听到波涛汹涌,想到的却不是大海!"
# 载入样式
font1 = ImageFont.truetype("res/simhei.ttf", size=25)
# 使用draw在画板下面上指定区域,使用指定文字样式渲染文字
draw.text(xy=(108, 75), text=text1, font=font1, fill=(0, 0, 0, 0))
举一反三,所有文本的渲染源码如下:
# 文本声明
text1 = "长大就是当你听到波涛汹涌,想到的却不是大海!"
text2 = "骚骚的小马"
text3 = "老铁铁"
text4 = "精辟啊!"
text5 = "低调低调!"
# 创建画板
draw = ImageDraw.Draw(bg_image)
# 渲染文本
font1 = ImageFont.truetype("res/simhei.ttf", size=25)
draw.text(xy=(108, 75), text=text1, font=font1, fill=(0, 0, 0, 0))
font2 = ImageFont.truetype("res/simhei.ttf", size=29)
draw.text(xy=(110, 20), text=text2, font=font2, fill=(84, 99, 142, 0))
font3 = ImageFont.truetype("res/simhei.ttf", size=27)
draw.text(xy=(144, 591), text=text3, font=font3, fill=(84, 99, 142, 0))
draw.text(xy=(199, 722), text=text3, font=font3, fill=(84, 99, 142, 0))
draw.text(xy=(144, 684), text=text2, font=font3, fill=(84, 99, 142, 0))
font4 = ImageFont.truetype("res/simhei.ttf", size=27)
draw.text(xy=(144, 628), text=text4, font=font4, fill=(0, 0, 0, 0))
font5 = ImageFont.truetype("res/simhei.ttf", size=27)
draw.text(xy=(294, 721), text=text5, font=font5, fill=(0, 0, 0, 0))
# 存储最终图片
bg_image.save("tmp/" + fileName)
最终效果如下:

nao~,目前就只剩下画面正中的视频区域了。
3.3 背景图与视频合成
将视频素材渲染到背景图片的指定区域,其实就是FFmpeg的
基于这个功能的需求,我们使用的命令如下:
ffmpeg.exe
-i task_bg.png
-vf "movie=demo.mp4,scale=514x332[test]; [in][test] overlay=x=107:y=112 [out]"
output.mp4
为之前合成的最终背景图task_bg.png 为准备的视频素材demo.mp4 对视频素材进行了缩放处理scale 中overlay 指定了视频素材渲染的位置x、y
由于movie参数不支持
对于上面的问题,一般直接切换到视频素材的目录下,调用ffmpeg命令即可。如下:
cd 【视频素材路径】&&【ffmpeg所在目录】\ffmpeg.exe ……
看到这里,我们终于可以通过程序合成出“朋友圈模版视频”的扛鼎之作了!
4.结语
视频,往往倾注着创作者的灵感、传授知识的目的、分享讯息的愿望。我很反感类似做搬运这种毫无价值的腐食和偷窃行为。这类腐食的投机者往往钻营,【此处省略300字】,所以,程序和源码我还是不直接放这里了。
言而有信,结尾给出程序和完整源码:
print("想要源码和程序嘛?关注后私信我,我会酌情给予(仅限学习目的)~")