用Go语言手搓一个在一起365天纪念视频模板

说实话,第一次被女朋友问到“我们能不能做一个在一起一周年的视频”时,我整个人是懵的,不是不想做,是市面上那些App生成的视频模板,千篇一...

说实话,第一次被女朋友问到“我们能不能做一个在一起一周年的视频”时,我整个人是懵的,不是不想做,是市面上那些App生成的视频模板,千篇一律,换个名字就能给别的情侣用,我是个写Go的程序员啊,怎么能用别人写好的模板?我得自己写一个,于是就有了这个念头:用Golang写一个能生成“在一起365天”纪念视频的模板工具。

为什么选Go语言来做这件事

你可能觉得奇怪,做视频不应该是用Python或者JavaScript吗?Python有moviepy,JS有ffmpeg.wasm,但我选Go,有几个很实在的理由。

第一,Go编译出来是单个二进制文件,我做出来的工具,发给女朋友,她不用装Python环境,不用装Node.js,双击就能跑,我甚至可以把配置文件写好,她只需要把照片丢进文件夹就行。

第二,Go的并发处理照片和视频片段特别顺手,你要知道,一个365天的纪念视频,可能要处理几百张照片、几十段小视频,如果用Python,多线程那套东西写起来多少有点别扭,Go的goroutine和channel,天然就是干这个的。

第三,Go调用FFmpeg特别稳,底层视频编码解码,还是得靠FFmpeg,Go的os/exec包执行外部命令,配合管道读取输出,比Python的subprocess用起来清爽多了。

我用的核心依赖就两个:ffmpeg-go(一个Go语言的FFmpeg绑定库)和imaging(图片处理库),再加一个自己写的配置文件解析器,齐活。

视频模板的整体设计

我想做的不是那种生硬的幻灯片,而是有节奏感的纪念视频,设计思路大概是这样的:

时间线结构

我把视频分成四个篇章,对应四季更替,也对应恋爱中的不同阶段:

篇章 时间跨度 视觉风格 背景音乐建议
初遇 Day 1-90 暖色调,阳光感 轻快的木吉他
热恋 Day 91-180 高饱和度,动态效果多 节奏感强的流行乐
磨合 Day 181-270 冷色调为主,穿插温暖瞬间 钢琴曲
相守 Day 271-365 金色调,温暖柔和 舒缓的弦乐

每个篇章大约15-20秒,总共1分到1分20秒左右,太长没人愿意看完,太短又显得敷衍。

每一帧的构成

视频的每一帧,不仅仅是照片叠加,我设计了三层结构:

  1. 底层:毛玻璃效果的照片模糊版,铺满全屏,作为背景
  2. 中层:照片本身,居中显示,带一点圆角和阴影
  3. 顶层:文字信息,包括“在一起的第X天”和一句当时的心情记录

这种三层结构,看起来有层次感,不单调,照片模糊做背景这个想法,是我在看了Apple的回忆视频后抄来的,但抄得好也是本事嘛。

核心代码实现:一步一步来

第一步:读取配置文件

用户不需要写代码,只需要填一个JSON文件就行,我用了一个叫config.json的文件,结构大概是这样的:

{
  "couple_name": "小明 & 小红",
  "start_date": "2023-05-20",
  "background_music": "music/sweet.mp3",
  "photo_dir": "photos/",
  "output": "output/anniversary.mp4",
  "daily_notes": {
    "2023-05-20": "第一次见面,在咖啡馆聊了三个小时",
    "2023-06-01": "一起去海边看日出"
  }
}

Go里解析这个很简单,定义一个struct,然后json.Unmarshal就行,这里有个小坑:照片文件名最好按日期命名,比如jpg,这样代码里才好按时间排序。

第二步:照片预处理

照片不可能直接丢进去用,手机拍的照片,有的横屏有的竖屏,尺寸还不一样,我写了一个预处理函数:

func preprocessPhotos(photoDir string) ([]Photo, error) {
    // 读取所有照片文件
    // 统一调整为1080x1920(竖屏)或1920x1080(横屏)
    // 裁剪时保持人物居中,用人脸检测库判断
    // 生成模糊背景图
}

照片裁剪这块,我用了imaging库,人脸检测没有现成的Go库好使,我干脆不做了,直接在配置里让用户指定“照片中人物的位置”,默认居中,完美主义害死人,60分的答案比100分的空白强。

模糊背景生成用的是高斯模糊算法,Go的gaussian库有这个功能,模糊半径设为20,看起来就像毛玻璃效果了。

第三步:生成视频片段

这是最核心的部分,对于每一天,我生成一个2-3秒的视频片段:

func generateDayClip(day int, photo Photo, note string) (*ffmpeg-go.Clip, error) {
    // 加载照片和模糊背景
    // 叠加文字:第XX天 + 心情记录
    // 添加转场效果:淡入淡出
    // 输出为临时视频片段
}

文字叠加用的是FFmpeg的drawtext滤镜,中文字体需要单独指定,我打包了一个开源字体SourceHanSansCN-Regular.ttf在二进制里,字体大小28,颜色白色,带一点黑色阴影,在照片上就看得清了。

转场效果我做了三种:淡入淡出、向左滑动、放大缩小,随机分配,但相邻两个片段不能用同一种,这些转场在FFmpeg里都有现成的滤镜,不需要自己造轮子。

第四步:合并所有片段

片段都生成好了,最后用FFmpeg的concat协议合并成一个完整的视频,同时混入背景音乐,音量调低到30%,不要喧宾夺主。

func mergeAllClips(clipPaths []string, musicPath string, outputPath string) error {
    // 写一个临时文件列表
    // 调用FFmpeg concat
    // 混音背景音乐
    // 输出最终视频
}

混音这里有个细节:背景音乐的长度可能和视频长度不一致,如果音乐比视频短,就循环播放;如果音乐比视频长,就截断,我用ffmpegamix滤镜和loop参数搞定。

遇到的那些坑,踩过的都给你说

做这个项目过程中,我踩了不少坑,说出来你听听,能少走弯路。

第一个坑:时间戳对齐。 照片的文件名是日期,但用户可能不是每天都有照片,比如第100天和第101天都有照片,但第102天空了,如果直接按日期生成,视频中间就会有一个空洞,我的解决办法是:不管有没有照片,每天都生成一个片段,没照片的日子,就用一张默认的“空镜头”照片,配上“今天没有记录,但心里有你”这样的文字,反而成了视频中的小彩蛋。

第二个坑:文字排版。 Go和FFmpeg的drawtext配合,中文换行是个大问题,用户的notes有时候很长,超过15个字就出屏幕了,我写了一个自动换行函数,每14个汉字换一行,最多显示两行,多余的字用省略号结尾。

第三个坑:性能问题。 一开始我串行处理,365个片段一个一个生成,跑了40分钟还没跑完,后来改成用goroutine并发处理,启动10个worker并行生成片段,速度提升了5倍,10分钟搞定,这里要注意,FFmpeg本身是多线程的,所以并发数不要超过CPU核心数,不然反而会慢。

第四个坑:颜文字和特殊符号。 有用户的notes里带了emoji,❤️”,FFmpeg的drawtext默认不支持emoji渲染,我干脆在预处理时把所有emoji过滤掉,换成对应的文字描述,爱心”,虽然丢了点趣味,但至少不会报错中断。

实际效果与使用感受

做好了之后,我先用自己的照片跑了一遍,365张照片,加上一些日常记录的文字,生成出来的视频还挺像那么回事,女朋友看了之后,眼眶红了,说这是她收到过最用心的礼物。

用Go语言手搓一个在一起365天纪念视频模板

工具的使用流程是这样的:

  1. 把照片按日期命名放进photos/文件夹
  2. 编辑config.json,填上两个人的名字、开始日期和想说的话
  3. 双击运行anniversary-tool.exe
  4. 等10-15分钟,拿到视频

我在Go里还加了一个进度条,用pb库实现的,每生成一个片段就更新一次,用户看到进度在走,就不会焦虑。

后来我把这个工具发布到了GitHub上,加了MIT协议,谁都可以用,两个月下来,居然有200多个star,还有用户提了PR,加了自动人脸裁剪功能,有一个用户留言说,他女朋友看完视频后哭了,专门跑来感谢我,那一刻真的觉得,代码不只是0和1,也能传递感情。

一些可以优化的方向

这个模板目前够用,但离完美还差得远,如果你有兴趣,可以在这些方向上改进:

添加视频素材支持。 现在只支持照片,但很多人可能想插入一些短视频片段,比如生日那天录的吹蜡烛视频,这个需要把视频片段截取成统一时长,再拼接到对应的时间点上。

更好的转场效果。 我用的都是FFmpeg内置的简单转场,其实可以做更复杂的,比如3D翻转、粒子消散之类的,这些需要自定义GLSL着色器,学习成本高,但效果确实好。

智能选片。 如果有太多照片,比如365天拍了1000张,手动选很麻烦,可以做一个智能推荐,根据照片的人脸数量、清晰度、表情自然程度打分,自动选出每天最好的一张。

语音旁白。 加上两个人的声音,读当天的日记,语音合成可以用百度或者阿里的API,但会引入外链,这个看你自己取舍。

云端生成。 做成一个Web服务,用户上传照片和配置,服务器帮你生成视频,然后下载,这个方案最适合不懂技术的用户,但成本高,需要买服务器。

不管怎么优化,核心的理念没变:用代码记录真实的生活,而不是用模板套出千篇一律的纪念品。

前几天那个用户又给我留言了,说他们结婚了,婚礼上放了这个视频,我回了句“祝你幸福”,心里头挺暖的,代码写得好不好不重要,重要的是它帮人留住了那些值得记住的瞬间。

本文来自作者[kyadmin]投稿,不代表be365立场,如若转载,请注明出处:http://www.uss1.cn/nengyuan/1534.html

(3)

文章推荐

发表回复

本站作者才能评论

评论列表(4条)

  • kyadmin
    kyadmin 2026-07-07

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

  • kyadmin
    kyadmin 2026-07-07

    希望本篇文章《用Go语言手搓一个在一起365天纪念视频模板》能对你有所帮助!

  • kyadmin
    kyadmin 2026-07-07

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

  • kyadmin
    kyadmin 2026-07-07

    本文概览:说实话,第一次被女朋友问到“我们能不能做一个在一起一周年的视频”时,我整个人是懵的,不是不想做,是市面上那些App生成的视频模板,千篇一...

    联系我们

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

    关注我们