挑战365天发一个视频,我用Golang写了个自动化工具,结果把自己卷进去了
- 房产
- 2026-08-27 23:09:15
- 44
一开始,我只是想治好自己的“拖延癌”
你有没有过这种时刻——手机里存了几百个拍摄素材,相册都快爆炸了,但一个视频都没发出去?我就是这样,2023年元旦,我对着镜子里的自己说:“今年,我要挑战365天,每天发一个视频。”
第三天我就差点放弃了,不是没素材,不是没时间,是整理素材这件事把我劝退了,每次打开剪辑软件,光是把那些碎片化的视频、图片、文字说明归类,就得花掉两个小时,我拍视频只要十分钟,整理却要两小时,这账怎么算都不对。
然后我干了一件“程序员才会干的事”——用Golang写了个本地视频素材管理工具,本来只想解决自己的问题,结果这工具越写越上头,最后不仅帮我完成了挑战,还让我对“坚持”这件事有了完全不一样的理解。
为什么是Golang?因为懒
你可能觉得奇怪,挑战发视频跟编程语言有什么关系?关系大了,我需要的不是又一个大而全的剪映或PR,我需要的是一个极简的、命令行就能跑的、不占内存的素材管家。
选Golang有三个原因:
- 编译成单个二进制文件,扔到任何电脑上都能跑,不用配环境
- 并发处理能力强,批量重命名、生成缩略图、提取拍摄时间,多线程跑起来飞快
- 语法简单到令人发指,我这种半路出家的非科班选手,一边看文档一边写,两天就出了第一个可用版本
这个工具干的事情很笨:扫描我指定的素材文件夹,按日期自动归组,重命名成“2024-01-15_001.mp4”这种格式,然后生成一个index.html索引页,我在浏览器里就能看到所有素材的时间线和缩略图,就这么个东西,把我每天两小时的整理时间压缩到了十五分钟。
第100天:我发现了“坚持”的错觉
工具稳定运行后,我的视频更新频率确实上去了,但到了第100天,一个诡异的现象出现了——我发视频的时间越来越晚,有时候晚上11点58分才踩点发布。
为啥?因为我开始追求“完美素材”了,工具把素材整理得太清晰,我反而陷入了选择困难:这个视频构图差一点,那个视频语速太快,还有个视频当时光线不好……我每天花大量时间在“挑选”上,而不是“发布”上。
后来我做了一个大胆的决定:用Golang写了一个“随机选材”脚本,每天到了晚上8点,如果我还决定不了发哪个素材,就让脚本从“已整理且未发布”的素材池里随机挑一个,配上固定的片头片尾,直接生成成片。
你猜怎么着?随机选的素材,观众反馈反而比我自己挑的还好,有个随手拍的菜市场人流的视频,播放量惊人地过了十万,我盯着后台数据愣了半天,终于明白一个道理:你的观众没那么在意“完美”,他们在意的是“真实”和“持续”。
第200天:工具反噬了我
别急着羡慕我,到了第200天,新的麻烦来了,我的Golang工具越来越智能,我给它加了自动字幕、自动配乐、自动转场……它开始替我创作了。
有个星期我特别忙,连续五天用了完全自动生成的视频:素材是随机的,字幕是自动识别的,背景音乐是从免费音乐库随机匹配的,结果粉丝评论区炸了,有人说“你是不是换团队了”,有人说“这风格不像你”,还有人说“感觉没灵魂了”。
我反复看了那几天的成片,确实——太顺滑了,顺滑得没有人的味道,我忘了最初挑战的目的是什么,我想通过视频记录生活,而不是生产工业化的内容。
然后我又干了一件事:把工具里“智能推荐”的模块全部删掉,只保留最基础的整理和格式转换功能,重新回到那个“笨笨的”命令行工具。
第300天:意外收获比打卡更重要
坚持到300天的时候,我的视频可能只积累了三万多粉丝,不算多,但有意思的事情发生了。
因为每天整理素材,我被迫养成了随手拍的习惯,以前我总想着“等有个完美场景再拍”,现在我会在等公交时拍雨滴,在超市里拍夕阳透过货架的光,在深夜加班时拍空荡荡的办公室。
因为每天用那个简陋的Golang工具处理素材,我逐渐理解了编码、文件格式、元数据这些底层概念,后来我把这个工具开源了,居然有十几个陌生人给我提了issue和PR,大家一起改进它。
哦对了,最意外的是——一个小工具帮我重新理解了内容创作,以前我总以为“灵感是玄学”,现在我发现灵感就是素材库里那些你没注意到的碎片,工具不创造灵感,但它帮你把灵感的海滩清理干净,让你有机会看到那枚贝壳。
我的Golang工具大概长这样
如果你也是视频创作者,也面临素材管理的痛苦,我把我这个工具的核心逻辑写在这里(不全,但够用了):
核心功能一:按日期自动归类
func organizeByDate(files []string) {
for _, file := range files {
info, _ := os.Stat(file)
modTime := info.ModTime()
folderName := modTime.Format("2006-01-02")
os.MkdirAll(folderName, 0755)
newPath := filepath.Join(folderName, filepath.Base(file))
os.Rename(file, newPath)
}
}
核心功能二:生成缩略图索引
func genThumbnails(dir string) {
files, _ := ioutil.ReadDir(dir)
for _, f := range files {
if strings.HasSuffix(f.Name(), ".mp4") {
cmd := exec.Command("ffmpeg", "-i", f.Name(), "-ss", "00:00:01", "-frames:v", "1", "thumb_"+f.Name()+".jpg")
cmd.Run()
}
}
}
核心功能三:随机选材(第100天时的“救场侠”)
func randomPick(dir string) string {
files, _ := filepath.Glob(filepath.Join(dir, "*.mp4"))
rand.Seed(time.Now().UnixNano())
picked := files[rand.Intn(len(files))]
return picked
}
别嫌代码简陋,它真的帮我完成了365天的挑战,而且我真心觉得,工具的价值不在于它多强大,在于它解决了你的具体问题。
第365天:我没有变成大V,但成了另一个自己
现在回头想,这个挑战最难的其实不是每天发视频,而是每天面对真实的自己。
有30天,我拍的视频模糊、晃动、内容无聊;有20天,我发的是纯文字卡片配上截图;还有几天,我用了重复素材,被粉丝抓包了,但这就是真实的我——一个普通人,也想坚持做一件事,也会疲惫,也会敷衍,但只要还在发,就没输。
用Golang写工具的那些深夜,我盯着终端里滚动的输出日志,突然觉得这个过程很像种地:你不能控制天气,但你可以按时播种、浇水、除草,素材就是种子,工具就是农具,而坚持本身,就是最好的肥料。
第365天那天,我发了个没什么特别的视频——就是我家窗台上一盆多肉,缓慢地在光影里移动,配文写了很简单的一句话:“365天前,我以为我挑战的是日更;现在我才明白,我挑战的是每天接受自己一次。”
没人知道这视频花了多少时间,但我知道——我用一年时间,验证了一件小事:坚持,+工具思维,+接纳不完美,是可以让你走到终点的。 哪怕终点之后,没有鲜花和掌声,只有你脚上实实在在的泥土。
