用Go语言挑战365天下午茶视频,一个程序员的真实记录
- 科技
- 2026-08-23 09:06:56
- 48
从一条朋友圈开始的项目
说实话,我一开始压根没想过自己能坚持这么久,去年秋天某个周二的下午,我在公司茶水间泡了杯挂耳咖啡,顺手拍了个15秒的短视频发到朋友圈——就是那种咖啡液滴进杯子里、热气往上飘的画面,配文写的是“第1天,挑战365天下午茶视频”。
那条朋友圈收获了23个赞,比我平时发的代码分享多了一倍。
于是我就想,既然大家都在看,那不如真的用Go语言写个小工具,把这事儿系统化地管起来。
为什么用Go写视频管理工具
你可能觉得拍视频跟写代码是两码事,工具决定习惯,Python写脚本固然快,但打包部署麻烦;Node.js生态虽然丰富,但内存占用让我这个用着老款MacBook的人有点心疼,Go就不一样了——编译出来一个二进制文件,扔到服务器上就能跑,而且它处理并发的方式特别适合我边拍视频边做文本记录的场景。
我的需求其实很简单:
- 记录每天拍视频的主题、素材路径、发布时间
- 自动生成当天的文案草稿(用模板拼接)
- 统计累计天数、连续天数、断更次数
- 输出一个简单的打卡日志
刚开始我用的是Rust,但那玩意儿的学习曲线太陡了,我当时连所有权都没搞明白,光顾着跟编译器搏斗了,后来换成Go,从“想做一个功能”到“功能跑起来”只需要十几分钟,这种正反馈对我这种三分钟热度的人来说太重要了。
第一版:简单粗暴的CLI工具
那会儿我住在北京的一个老小区里,楼下有棵特别大的槐树,每天下午三点多,阳光穿过树叶的空隙洒在餐桌上,我就把手机架在旁边,开始拍当天的下午茶。
我的第一个Go程序长这样:
package main
import (
"fmt"
"time"
)
type AfternoonTea struct {
Day int
Theme string
VideoPath string
Note string
}
func main() {
tea := AfternoonTea{
Day: 1,
Theme: "挂耳咖啡的十二种冲法",
VideoPath: "./videos/day001.mp4",
Note: "水温89度,粉水比1:15",
}
fmt.Printf("第%d天: %s\n", tea.Day, tea.Theme)
}
当时觉得特别满足,因为程序能跑,而且真的记录了我的第一天。
中途的崩溃与重构
拍到第47天的时候,问题来了,我习惯性地把视频文件放在一个文件夹里,然后用CSV记录元数据,但有一天我不小心把CSV文件删了——当时我还不知道有git这回事,整个人坐在电脑前愣了好几分钟。
那天晚上我翻手机相册,发现所有视频都在,只是对应的描述文字全没了。那种数据丢失的挫败感,比拍了烂片还难受。
所以第二天我花了一整个晚上重写这个工具,这次我:
- 用SQLite替代了CSV(通过mattn/go-sqlite3驱动)
- 加入了自动备份功能,每天运行后拷贝一份到Dropbox文件夹
- 写了个简单的Web界面(就是Go标准库的net/http),方便我在手机浏览器上也能查看进度
这版工具跑到现在,再也没出过幺蛾子,有个心得想分享:工具的第一要义是“别让用户难受”,这里的用户就是未来的自己。
拍视频本身变成了一种仪式感
说起来挺玄乎的,用Go写的打卡程序跑起来之后,我拍下午茶视频这事儿反而变得更有趣了,因为我发现程序里那个Day计数器每增加一,就像打游戏升了一级。
慢慢地,我总结出了一些规律:
- 周一到周三拍花式咖啡,因为周边有家烘焙店送货快
- 周四拍水果茶,因为楼下水果摊剩的水果会打折
- 周五拍甜点配茶,因为周末马上到了心情好
- 周末两天就随机拍点奇怪的——比如上周六我用养乐多兑了绿茶,味道意外地还行
我的视频脚本也从最初的几行字,变成了一段段带生活感的碎碎念,比如某天的内容:
今天的茉莉花茶泡了三分钟,花香刚刚好,窗台上那只流浪猫蹲着看了我半天,可惜它不会说话,不然我真想问问它要不要来一杯。
Go协同拍摄流程的关键设计
到了100天以后,我的拍摄流程已经非常固定了,这里是我的核心工作流,配合Go程序每个环节都特别顺滑:
| 时间段 | 任务 | 对应工具/Go函数 |
|---|---|---|
| 14:30 | 确认今日主题 | 读取themes.json,从三个备选里随机抽一个 |
| 14:45 | 拍摄视频 | 手机横屏拍摄,720p,时长控制在45-90秒 |
| 15:00 | 转存素材 | 用os.Rename把视频挪到按日期命名的子文件夹 |
| 15:15 | 写文字记录 | 在CLI里输入几行字,存到SQLite的notes字段 |
| 15:20 | 生成打卡图 | 用image/png库画一张简单的进度卡片 |
| 15:30 | 发布到社交平台 | 截图打卡图,配文字粘贴上去 |
另外我会在每周日晚上跑一个简单的统计脚本,看看本周平均时长、最高点赞、最受欢迎的主题这类指标,这个功能用Go写特别容易——SQL里一个GROUP BY就搞定了,然后用text/template渲染成一个简单的HTML报告。
一些意想不到的收获
到200天左右,我开始觉得整个事情的意义已经超出了“做任务”本身。
其一,我的视频剪辑水平提高了不少,虽然用的是剪映的傻瓜模式,但每天一段小视频,剪辑手感和节奏感是实实在在练出来的。
其二,我的生活变得更规律了,每天下午三点整,我的Go程序会弹出一个桌面通知(通过fsnotify监控时间,触发一个系统通知),提醒我该拍视频了,这个简单的机制帮我在自由职业时期保持了难得的节律感。
其三,认识了一群有意思的人,有几个观众天天在评论区跟我互动,后来我们拉了个群,每天分享各自的下午茶,有上海的大哥做手冲,成都的小姐姐煮奶茶,还有个在东京的姑娘研究抹茶甜品,我们用各自的母语聊吃的,配着蹩脚的翻译,反而特别有乐趣。
技术栈细节:这是代码层面最值当的部分
如果你也想做个类似的东西,我可以把手头在用的Go库列一下:
import (
_ "github.com/mattn/go-sqlite3" // 本地存储
"github.com/fsnotify/fsnotify" // 文件监听
"github.com/mitchellh/go-homedir" // 跨平台路径
"image/png" // 标准库,生成打卡图
"net/http" // 内置web服务
)
整个项目大概1200行代码,没用什么框架,就是标准库加三四个辅助库。Go的部署形式对我来说最舒服的就是单一可执行文件——我把它放在/usr/local/bin/tea365,任何目录下都能直接运行。
关于挑战本身的思考
离365天还剩不到两个月了,我有点不舍得结束,昨天拍视频的时候,我突然想到,这个用Go写的程序本质上就是一个小小的时间容器——每一天的记录,无论是视频文件还是文字笔记,都被它安放得妥妥帖帖。
它没有推荐算法,没有热门标签,甚至UI简陋得只有黑底白字,但就是这样一个朴素的工具,陪着我走过了两百多个下午,每天下午3点,它准时提醒我:“该去烧水了,今天想喝点啥?”
最后的几十天里,我打算试着把一些特殊的日子用视频定格下来,比如第300天的时候,我煮了从云南寄来的紫芽普洱,取名为“漫长日子里的回甘”,那期视频的文案我是心绪来潮手写在便利贴上的,拍完以后贴在了显示器边框上,到现在还没撕下来。
那天晚上我打开电脑,想给Go程序加个“导出年度报告”功能,但想了想还是算了——有些东西,拍到哪算哪吧,就像下午茶本身,随心一点才好。
