用Golang把第一天到第365天视频做成时间胶囊,我的年度记录工具开发手记

为什么突然想写这个?前两天整理手机相册,翻到去年元旦拍的视频——那天我信誓旦旦说要每天录一段生活,结果坚持了11天就夭折了,视频零散...

为什么突然想写这个?

前两天整理手机相册,翻到去年元旦拍的视频——那天我信誓旦旦说要每天录一段生活,结果坚持了11天就夭折了,视频零散地躺在各个文件夹里,有的在微信缓存里,有的在云盘角落,想拼起来看个时间线都费劲。

后来我在GitHub上逛,看到有人用Python写年度视频拼接工具,但Python环境配置对普通人实在不友好,我想,Golang编译出来是个干净的可执行文件,双击就能跑,这不正是给非程序员用的最佳方案吗?于是花了两个周末,写了这个小工具,今天把实现思路和代码片段分享出来,你也能做一个专属于自己的“第1天到第365天”视频记录系统。

核心思路:别把简单事搞复杂

我的需求其实很简单:每天用手机拍一段10-30秒的视频,晚上睡前丢进一个按日期命名的文件夹,然后工具自动把365个视频按顺序拼接,生成一个“年度时间轴”视频,听着像电影剪辑,但本质上就是三件事:

用Golang把第一天到第365天视频做成时间胶囊,我的年度记录工具开发手记

  1. 扫描:读取所有视频文件,按文件名中的日期排序
  2. 转码:统一分辨率、编码格式(否则拼接时会画面跳变)
  3. 拼接:用FFmpeg把视频流按时间顺序无缝连接

用Golang的好处在于——标准库里的 path/filepathsort 能搞定90%的文件操作,而 os/exec 可以直接调用系统里的FFmpeg。不用学复杂API,20行代码就能跑通核心流程。

第一步:设计文件命名规则(这是灵魂)

你最好在第一天就定好格式:2025-01-01.mp4,为什么用日期当文件名?因为排序就是字符串排序,sort.Strings() 一步到位,不用解析时间戳再转格式。

files, _ := filepath.Glob("videos/*.mp4")
sort.Strings(files) // 直接按字典序排列

看到没?两行代码,所有视频就按时间排好了。 但有个坑:如果某天你忘了拍,或者拍了没存进去,拼接时就会出现“时间跳跃”,我建议文件名改成 day001.mp4 格式,这样缺哪天看得一清二楚。

第二步:统一视频参数(不然后悔死你)

手机竖屏拍的1080p,录屏可能是720p,抖音下载的又是奇奇怪怪的尺寸,直接拼接的话,画面会忽大忽小,有的还带黑边,我的解决思路是先全部转为统一的1080x1920,25帧,H.264编码

这里用FFmpeg就够了,Golang只需要负责传参数:

cmd := exec.Command("ffmpeg", "-i", input, "-vf", "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2", "-r", "25", "-c:v", "libx264", "-preset", "medium", "-crf", "23", output)
cmd.Run()

那个 pad 参数值得说——它会在视频四周补黑边,让竖屏视频在横屏播放时居中显示,不会变形,我一开始没加这个,结果横屏视频被拉得人脸都是扁的,惨不忍睹。

第三步:拼接命令其实有陷阱

FFmpeg拼接有两种方式:concat demuxerfilter_complex强烈推荐用 demuxer,因为对内存友好,而且支持的文件数量没有上限。

先在Golang里生成一个列表文件:

fileList := "list.txt"
f, _ := os.Create(fileList)
for _, path := range sortedFiles {
    f.WriteString(fmt.Sprintf("file '%s'\n", path))
}
f.Close()

然后执行拼接:

cmd := exec.Command("ffmpeg", "-f", "concat", "-safe", "0", "-i", fileList, "-c", "copy", "year_2025.mp4")
cmd.Run()

注意那个 -c copy——这步千万别加滤镜或缩放,否则会重新编码所有视频,365个30秒的视频可能要跑三小时,直接copy音频视频流,几分钟就搞定了。

进阶玩法:给视频加日期水印

光有画面不够,你得知道这是哪一天,我试过在文件名里看日期,但播放时谁还看文件名啊,后来用FFmpeg的 drawtext 滤镜,每天的视频右上角都烙上“Day 057”的红字。

不过这个有个前提:字体文件路径要写对,Windows用 C\:\\Windows\\Fonts\\arial.ttf,macOS用 /System/Library/Fonts/Supplemental/Arial.ttf,Linux得自己装字体,这个路径问题当时卡了我半小时,气得我差点放弃水印功能。

cmd := exec.Command("ffmpeg", "-i", input, "-vf", fmt.Sprintf("drawtext=text='Day %s':fontfile=%s:fontsize=48:fontcolor=red:x=w-tw-20:y=20", dayStr, fontPath), "-c:a", "copy", output)

关于性能:别指望一台老笔记本扛全年

我最初想一天跑一次脚本,每天晚上自动拼接“至今为止的所有视频”,但到第30天时,拼接30个视频就要30秒;第100天可能要3分钟;到了第365天,光拼接就要近20分钟,中间还有转码步骤,CPU跑得呼呼响。

所以我的建议是:按季度拼接,1-3月生成Q1.mp4,4-6月生成Q2.mp4,最后拼接四个季度文件,这样每次操作都在5分钟以内,Golang的并发特性这时候就派上用场了——用 goroutine 并行转码不同批次的视频,效率能提升两倍。

这里放个简单的并发控制模板,避免把CPU吃光:

sem := make(chan struct{}, 4) // 限制同时转码4个
for _, file := range files {
    sem <- struct{}{}
    go func(f string) {
        defer func() { <-sem }()
        convert(f) // 转码函数
    }(file)
}

怎么处理“断更”的日子?

我这个工具最人性化的设计就是允许跳天,如果你3月5号没拍,3月6号的视频依然会正常拼接,只是中间没有过渡,更棒的是,我加了个 -missing 参数,能自动生成一张黑底白字的静态图片补位,上面写着“Day 064 —— 未记录,但这一天依然存在”。

func missingFrame(day int) {
    // 用FFmpeg生成2秒黑色视频
    cmd := exec.Command("ffmpeg", "-f", "lavfi", "-i", "color=c=black:s=1080x1920:d=2", "-vf", fmt.Sprintf("drawtext=text='Oops! Day %d skipped':fontsize=60:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2", day), fmt.Sprintf("missing_%d.mp4", day))
    cmd.Run()
}

这个功能说实话是我自己私心加的——因为我知道自己一定会断更。接受不完美,反而坚持得更久。

最终脚本的运行效果

你拿到我的代码后,只需要改一个配置文件(视频目录、输出格式),然后运行:

go build -o yearly_video.exe main.go
./yearly_video.exe -input ./videos -start 2025-01-01 -end 2025-12-31 -output year_review.mp4

命令执行完,一个366个片段(加上开头结尾标题卡)的年度视频就出现了,播放到第87天时,看到自己那天下雨没带伞,在便利店门口躲雨时拍的那段话,泪水突然就绷不住了——这就是时间胶囊的意义

最后的实际操作建议(血泪教训)

  • 每天的视频不要超过2分钟,否则后期处理崩溃是小事,关键是剪辑思路会很混乱
  • 用手机竖屏拍,别横屏。横屏竖屏混着拍,播放时体验会非常割裂
  • 我用的FFmpeg版本是6.1,你们装新版7.0也行,但命令行参数略有变动,遇到问题去查官方文档就行
  • 如果你用的是苹果手机,记得设置里把视频格式改成“兼容性最好”,不然HEVC编码在Windows上播放会卡

这套工具我用了快一年了,现在已经到第264天,有时深夜加班回来,想起没拍视频,还是会挣扎着拿起手机,对着窗外黑漆漆的街道说两句,不为别的,就为了哪天回看这些碎片时,能闻到当时的空气味道。

代码本身没多少技术含量,但我希望它能让你把生活的细节留住,毕竟,一年365天,每一天的你都值得被记录。

本文来自作者[kyadmin]投稿,不代表be365立场,如若转载,请注明出处:http://hljbesthome.com/nba/2430.html

(7)

文章推荐

发表回复

本站作者才能评论

评论列表(4条)

  • kyadmin
    kyadmin 2026-08-22

    我是be365的签约作者“kyadmin”!

  • kyadmin
    kyadmin 2026-08-22

    希望本篇文章《用Golang把第一天到第365天视频做成时间胶囊,我的年度记录工具开发手记》能对你有所帮助!

  • kyadmin
    kyadmin 2026-08-22

    本站[be365]内容主要涵盖:be365,be365网站,be365网址,ball365体育,Be365排名

  • kyadmin
    kyadmin 2026-08-22

    本文概览:为什么突然想写这个?前两天整理手机相册,翻到去年元旦拍的视频——那天我信誓旦旦说要每天录一段生活,结果坚持了11天就夭折了,视频零散...

    联系我们

    工作时间:周一至周五,9:30-18:30,节假日休息

    关注我们