Automader 项目地址:Gitee 码云
项目简介
Automader 项目最开始只是给我自己使用的 Python 小工具,但是想着为音 mad 社区作出一点自己的共享,因此就把它的源代码放在了码云上面。
这个项目受到了 Manim 的一些影响,再加上自己的代码水平严重不足,所以目前(Alpha0.7版)没有图形界面,也没有很多功能。
许多人在用 VV,有人用 AE,亦有人用 Aviutl。我也有打听过一些其他的方便快捷的项目和脚本,其中最知名的应该是 某一个 AE 脚本 和 某一个 Vegas 脚本。理论上来说,如果用我的项目做左右抽什么的话,确实没有上述两个脚本方便,但是我认为,我的 Automader 的优势在于,它能够高度的个性化,通过一些表达式做到一些不限制于左右抽的效果,这里的用法是没有上限的,毕竟音 mader 们不能将自己困于左右抽嘛。
当然,需要注意的是,Automader 基于 Python 编写,所以使用 Automader 需要你有一定的 Python 基础。
项目搭建
搭建项目是一切的开始。我的项目很简单,只需要将源代码下载保存到你喜欢的位置,并且安装需要的 Python 库即可。在 README.md 中有讲,在这里就不详细叙述了。
我的建议是使用 Pycharm 等 IDE 编写,能够更加方便看到一些需要的参数等。
左右抽
在项目的 README 中,我只写了最基础的导入图片、生成视频的内容。下面,就让我们开始写一个左右抽吧。
首先,我们先导入需要的素材(这里的路径是我虚构的):
from automader.ImageReader import VideoPreloader
from automader.TimelineProcessor import MidiTimeline
from automader.TimelineReader import readMidi
if __name__ == "__main__":
akari = VideoPreloader("D:/videos/akari.mp4", length=1500)
timeline = MidiTimeline(readMidi("D:/midis/kitsune2_so_happy.mid"), track=1)
要注意的是,除了特殊说明以外,关于时间的单位都是毫秒。我们在这里只导入1.5秒的阿卡林,是因为 VideoPreloader 会将需求中的所有视频帧加载到内存中,假如你的 akari.mp4 足足有 24 分钟,那可能没加载完,Python 先崩掉了。
还有,由于这里的 mid 文件解析器是我自己写的(太懒了不会找轮子就造轮子了),所以可能会有 bug。目前已经发现的问题是不能够读取 FLStudio 的 Midiout 生成的 midi 序列,只能够在钢琴卷轴的视窗中 Ctrl+shift+M 导出的才能用。
接着,我们创建一个容器,用以盛放我们每一个音的顺序数。我的程序有的优化是,对于和弦,能够将和弦中的多个音归于一个顺序数。
from automader.ImageReader import VideoPreloader
from automader.TimelineProcessor import MidiTimeline
from automader.TimelineReader import readMidi
from automader.NumberBasic import FuncMappingValueContainer
if __name__ == "__main__":
akari = VideoPreloader("D:/videos/akari.mp4", length=1500)
timeline = MidiTimeline(readMidi("D:/midis/kitsune2_so_happy.mid"), track=1)
doFlip = FuncMappingValueContainer(0, lambda x: x % 2)
意思是,当某个音的顺序数为奇数时翻转,偶数时不反转,学过数学的朋友应该能很快反应。这里的 FuncMappingValueContainer 能够将输入的数字按照预定的函数进行处理,而第一个参数 0 是缺省值,当没有数字输入时,默认的输入是 0。
现在,让我们应用翻转效果。
from automader.ImageReader import VideoPreloader
from automader.TimelineProcessor import MidiTimeline
from automader.TimelineReader import readMidi
from automader.core.NumberBasic import FuncMappingValueContainer
from automader.VideoProcessor import FlipMiddleware
if __name__ == "__main__":
akari = VideoPreloader("D:/videos/akari.mp4", length=1500)
timeline = MidiTimeline(readMidi("D:/midis/kitsune2_so_happy.mid"), track=1)
doFlip = FuncMappingValueContainer(0, lambda x: x % 2)
flip_akari = FlipMiddleware(akari, doFlip=doFlip)
此时,当我们的 doFlip 输出为 1 时,flip_akari 输出的图像就会是翻转的,不然就不会是翻转的。最后,我们把我们的 timeline 与 flip_akari 结合:
from automader.ImageReader import VideoPreloader
from automader.TimelineProcessor import MidiTimeline
from automader.TimelineReader import readMidi
from automader.core.NumberBasic import FuncMappingValueContainer
from automader.VideoProcessor import FlipMiddleware
from automader. OtomadProcessor import OtomadHandler
if __name__ == "__main__":
akari = VideoPreloader("D:/videos/akari.mp4", length=1500)
timeline = MidiTimeline(readMidi("D:/midis/kitsune2_so_happy.mid"), track=1)
doFlip = FuncMappingValueContainer(0, lambda x: x % 2)
flip_akari = FlipMiddleware(akari, doFlip=doFlip)
output = OtomadHandler(flip_akari, timeline)
output.singleNoteIndex.register(doFlip)
当我们用 singleNoteIndex 注册 doFlip 后,只要 output 的帧需要被读取,就会更新当时的音的顺序数,并输入到 doFlip 中。此时 doFlip 处理顺序数(取模2)并且输出到 flip_akari 的 doFlip 参数中,flip_akari 就能够根据当前的音的顺序数进行左右抽。
最后,我们将视频导出。
from automader.ImageReader import VideoPreloader
from automader.TimelineProcessor import MidiTimeline
from automader.TimelineReader import readMidi
from automader.core.NumberBasic import FuncMappingValueContainer
from automader.VideoProcessor import FlipMiddleware, VideoRender
from automader. OtomadProcessor import OtomadHandler
if __name__ == "__main__":
akari = VideoPreloader("D:/videos/akari.mp4", length=1500)
timeline = MidiTimeline(readMidi("D:/midis/kitsune2_so_happy.mid"), track=1)
doFlip = FuncMappingValueContainer(0, lambda x: x % 2)
flip_akari = FlipMiddleware(akari, doFlip=doFlip)
output = OtomadHandler(flip_akari, timeline)
output.singleNoteIndex.register(doFlip)
VideoRender(output, "D:/videos/akari_output.mp4").render(log=True, output=True, preview=False)
要注意的是,如果 akari_output.mp4 已经存在,是会报错的。我们可以在 render 方法中代入 ignoreFileCurrent=True 的参数,就可以忽略当前存在的文件并覆盖。
最后,等导出完毕,然后看看(没有声音的)左右抽的效果吧!接下来就可以把它放在你的音 mad 作品当中了。
想说的话
真的感谢你有耐心来看我的 Sh*t mountain 代码的教程,本身这个项目不是很好,但是我用着顺手就一直坚持写下去了,希望大家喜欢。
这个教程也会不定期更新,更新以后我会把链接贴到这里的。
说实话,我觉得我这个项目可以弄成 Blocky 积木式编程,然后再导入代码到 automader 中自动处理,岂不妙哉(
还有,如果真的迫切想了解亿些我写的其他功能,可以看看协助我做音 mad 的项目文件,里面很多是我对新写的东西的试验。看看吧!
- Shapes Of Shibamata: BV1sS4y1L75J ShibamataShape.py
- 卖瓜循环: BV1GQ4y1X7qR sellingWatermelon.py
- Sitting next to you(仅用Automader完成): BV12y4y1V7zr mad3.py