用python一键生成动画(上)

简介

这种动画类型,我觉得可以叫做配音配画的小说。

微型小说:多余的话

第一篇文章,介绍一下设计过程的原理和流程,下一篇文章讲细节。

整个生成过程的起点包括两个部分:小说文字和素材。当然这种小说最好是对话比较多的类型,才能体现出配音的意义。如果是景物描写、心理描写比较多的,用这种形式就不理想。

实现过程,采用多步实现,每一步形成一个稳定的中间结果。这样做的好处是每步实现过程相对独立,便于局部改善。同时一个作品的形成过程中进行反复调试是难免的,针对中间结果进行调试可以节约时间。

基本流程

第零步:剧本改造,加入标注。根据约定,用#表示控制内容。

  • #read  表示旁白
  • #talk:表示角色朗读
  • #def:系列表示一些预定义,包含角色音色、声调、图片、位置等
  • #角色名:表示角色的移动和表情
  • #back:表现切换背景

等等

以及准备素材,包括背景、人物造型、物品图片,并做背景消除。

这一步的工作,虽然可以有一些辅助,但相比较来说,以手工为主。

下面的各步,都是程序一键实现。

第二步:从剧本的标注中提取待朗读的内容,生成语音

我们直接采用百度的声音接口把文字转成MP3,效果见视频,感觉还是可以接受的。

分段朗读,把每个MP3文件统一命名保存

此外把朗读的文字内容保存为独立文件,每个MP3文件的时间长度,也保存起来。用于作为时间线的参考。

第三步:从剧本的标志中提取背景、角色动作信息,形成动画操作脚本

这个文件以机读为主,所以直接使用了python的列表对象转文本保存

第四步:根据动画操作脚本,绘制所有的关键帧

这里的关键帧,和一般的概念有所不同。所有发生变化的图片,在这里都叫做关键帧。

也就是说,这里将绘制所有发生变化的图片。

每个角色一个单独的层进行绘制,便于叠加显示。

第五步:根据关键帧,形成整个动画的所有帧

在每帧画面中,根据时间的流动,从关键帧资料中获取各背景、角色、物品、文字、遮罩等各层,进行叠加。

形成所有的帧,独立保存。

第六步:生成多段独立的动画

第七步:音频视频融合

音频和动画难以完全同步,所以每段音频和动画必须独立匹配,然后再连接。

第八步:生成字幕文件并与整体视频融入

第三方库

其中用到比较多的FFMPEG处理,所有必须安装好ffmepg

用到百度TTS,应当安装好百度相应的库

另外,还用了moviepy来测量视频的长度;pydub来测量音频的长度;PIL来进行图片操作。

第三方的库,基本上就是这些。

剧本改造参考

剧本如下:

#read
#def:reader=4,6,5
#def:boy=106,5,5,boy00.png
#def:ticket=111,5,7,ticket00.png
#def:man=3,4,2,man00.png
#def:girl=110,6,6,girl00.png
#def:lady=103,5,3,lady00.png
#def:author=106,7,6,author00.png
#defobj:bag=bag00.png
#defobj:map=map00.png
#defobj:book=book00.png
#defpos:leftpos=200
#defpos:leftpos2=-50
#defpos:rightpos=200
#defpos:rightpos2=-50
#defpos:bagpos=(40,400)
#defpos:mappos=(220,270)
#defpos:bookpos1=(90,160)
#defpos:bookpos2=(300,-150)
#defpos:center=(640,430)
#back:车站.png
#author:leftin,100
。。。欢迎观看。。微型小说《多余的话》。。。。
那天我坐公交车去找朋友,

#back:公交车内.png
车上人不多,但也没有空位子,
#author:hide
有几个人还站着,吊在拉手上晃来晃去。
#boy:leftin
一个年轻人,干干瘦瘦的,戴个眼镜,身旁有几个大包,
#bag:show,bagpos
一看就是刚从外地来的。他靠在售票员旁边,
#map:show,mappos,0.8
手拿着一个地图在认真研究着,眼不时露出茫然的神情,估计是有点儿迷路了。

他犹豫了半天,很不好意思地问售票员:

#talk:boy
「去颐和园应该在哪儿下车啊?」

#read
#ticket:rightin
售票员是个短头发的小姑娘,
#ticket:action,blink
正剔着指甲缝呢。
#ticket:action,blink
她抬头看了一眼外地小伙子说:
#ticket:action,blink
#talk:ticket
「你坐错方向了,应该到对面往回坐。」

#read

要说这些话也没什么错了,大不了小伙子下一站下车到马路对面坐回去吧。

但是售票员可没说完,她说了那多余的最后一句话:
#talk:ticket
#ticket:action,blink
「拿着地图都看不明白,还看个什么劲儿啊!」

#read
#ticket:action,blink
售票员姑娘眼皮都不抬。

#ticket:rightout
外地小伙儿可是个有涵养的人,
#map:hide
他嘿嘿笑了一笑,把地图收起来,准备下一站下车换车去。

#man:rightin
旁边有个大爷可听不下去了,他对外地小伙子说:

#talk:man
「你不用往回坐,再往前坐四站换904也能到。」

#read
#man:action,blink
是他说到这儿也就完了那还真不错,
#man:action,blink
既帮助了别人,
#man:action,blink
也挽回北京人的形象。

#man:action,blink
可大爷哪儿能就这么打住呢?
#man:action,blink
他一定要把那多余的最后一句话说完:

#talk:man,action
「现在的年轻人哪,没一个有教养的!」

#read
#bag:hide
#boy:leftout
我心想,大爷这话真是多余。车上年轻人好多呢,打击面太大了吧。

#girl:leftin
可不,站在大爷旁边的一位小姐就忍不住了。。

#talk:girl
「大爷,不能说年轻人都没教养吧。
#girl:action,blink
没教养的毕竟是少数嘛,
您这么一说我们都成什么了!」

#read
这位小姐穿得挺时髦,
#girl:action,blink
两细带子吊个小背心,脸上化着鲜艳的浓妆,
#girl:action,blink
头发染成火红色。
#man:action,blink
可您瞧人这话,
#girl:action,blink
不像没教养的人吧,跟大爷还『您』啊『您』的。

#girl:action,blink
谁叫她也忍不住非要说那多余的最后一句话呢!

#talk:girl,action
「就像您这样上了年纪看着挺慈祥的,
一肚子坏水儿的可多了呢!」

#read
#man:rightout
没有人出来批评一下时髦的小姐是不正常的。
#girl:action,blink

#lady:rightin
可不,一个中年的大姐说了:

#talk:lady
#girl:action,blink
「你这个女孩子怎么能这么跟老人讲话呢?
#lady:action,blink
要有点儿礼貌嘛,你对你父母也这么说吗?」

#read
您瞧大姐批评得多好!
#lady:action,blink
把女孩子爹妈一抬出来,
#girl:action,blink
女孩子立刻就不吭声了。
#lady:action,blink
要说这会儿就这么结了也就算了,
#girl:action,blink
大家说到这儿也就完了,
大家该干嘛干嘛去。
#lady:action,blink
可不要忘了,大姐的「多余的最后一句话」还没说呢。

#talk:lady
「瞧你那样,估计你父母也管不了你。
#lady:action,blink
打扮得跟“鸡”似的!」


#read
#girl:leftout
后面的事大家就可想而知了。
#lady:rightout
简单地说,出人命的可能都有。

这么吵着闹着,车可就到站了。
#ticket:rightin

车门一开,售票员小姑娘说:
#ticket:action,02
#talk:ticket
「都别吵了,该下的赶快下车吧。
别把自己正事儿给耽误了。」

#read
当然,她没忘了把最后一句多余的话给说出来:
#ticket:action,00

#talk:ticket
「要吵统统都给我下车吵去。
不下去我车可不走了啊!烦不烦啊!」

#read
烦不烦?烦!
#ticket:action,blink
不仅她烦,所有乘客都烦了!
整个车厢这可叫炸了窝了。
#man:leftin,leftpos
骂售票员的,
骂外地小伙子的,
#girl:rightin,rightpos2
骂时髦小姐的,
骂中年大姐的,
#lady:leftin,leftpos2
骂天气的,
骂自个儿孩子的,
真是人声鼎沸,甭提多热闹了!
#boy:centerin

那个外地小伙子一直没有说话,估计他受不了了,他大叫一声:

#talk:boy
「大家都别吵了!都是我的错!
我自个儿没看好地图,让大家跟着都生一肚子气!
大家就算给我面子,都别吵了行吗?」

#read
#man:hide
听到他这么说,
#lady:hide
当然车上的人都不好意思再吵,
#girl:hide
声音很快平息下来,
#ticket:hide
少数人轻声嘀咕了两句也就不说话了。

但你们不要忘了,外地小伙子的『多余的最后一句』还没说呢。

#talk:boy
「早知道北京人都是这么一群不讲理的王八蛋,
我还不如不来呢!」

#ticket:show,700
#man:show,leftpos
#girl:show,leftpos2
#lady:show,900

#read
。。。。。。
#back:公交车内.png
想知道事情最后的结果吗?
#boy:hide
#man:hide
#lady:hide
#girl:hide
#ticket:hide

我那天的事情没有办成,
#author:centerin

大伙儿先被带到公安局录了口供,然后到医院外科把头上的伤给处理了一下,
#ticket:leftin,leftpos2
我头上的伤是在混战中被售票员小姑娘用票匣子给砸的。
#ticket:action,blink

你们可别认为我参与了他们打架,
#ticket:action,blink
我是去劝架来着。我呼吁他们都冷静一点儿,有话好好说,
#ticket:action,blink
没什么大事儿,没什么必要非打个头破血流。

我多余的最后一句话是这么说的:
#talk:author
#effect:circle
#book:show,bookpos1
#author:action,01
不就是售票员说话不得体吗?
#book:rotmove,bookpos2
你们就当她是个傻子,
#author:action,02
和她计较什么呢?!
#text:The End,70,center
#ticket:action,blink
#end:1

猜你喜欢

转载自blog.csdn.net/xiaorang/article/details/106169578