你说巧不巧,昨天刚好是我和女朋友在一起的第365天,本来想找个现成的背景视频发朋友圈,结果搜了半天,不是要会员就是有水印,干脆自己动手,用Golang写了个小工具,生成专属的纪念视频。
你可能觉得写视频生成器很复杂,但用Golang做这件事,其实比想象中简单,而且自己写的,想加什么特效加什么,想放什么照片放什么,完全自己做主。
为什么用Golang做这个事
先说说为什么选择Golang,市面上常见的视频处理工具有Python的moviepy、Node.js的fluent-ffmpeg,但Golang有个天然优势——编译成单个可执行文件,你写好程序,发给女朋友,她双击就能运行,不用装Python环境,不用管依赖版本。
Golang的并发模型特别适合处理视频这种耗时的任务,生成视频时,你可以一边渲染画面,一边让程序告诉你“进度到哪了”,这种体验,用其他脚本语言实现起来要麻烦不少。
你需要的基础工具
在写代码之前,得先把工具备齐,我用的核心库是ffmpeg-go,它是对FFmpeg的Golang封装,FFmpeg是什么?可以理解为视频界的瑞士军刀,几乎所有视频格式转换、剪辑、合成都能搞定。
| 工具 | 版本 | 用途 |
|---|---|---|
| Go | 20+ | 编程语言 |
| FFmpeg | 4+ | 视频编码解码 |
| ffmpeg-go | v0.2.0 | Golang调用FFmpeg的接口 |
安装FFmpeg时,记得把它的路径加到系统环境变量里,我第一次没加,程序跑起来报错,找了半天才发现是路径问题——这种小坑,踩一次就记住了。
核心代码:生成背景视频的骨架
先看最核心的部分:生成一段带文字的动态背景视频,代码不长,但每一步都有讲究。
package main
import (
"fmt"
"github.com/u2takey/ffmpeg-go"
)
func main() {
// 生成纯色背景,持续365秒,代表365天
// 这里用绿色,因为我女朋友喜欢绿色
err := ffmpeg-go.Input(
"color=c=green:s=1920x1080:d=365",
ffmpeg-go.KwArgs{"f": "lavfi"},
).Filter("drawtext", ffmpeg-go.Args{
"text": "在一起365天",
"fontsize": 72,
"fontcolor": "white",
"x": "(w-text_w)/2",
"y": "(h-text_h)/2",
}).Output("output.mp4").OverWriteOutput().ErrorToStdOut().Run()
if err != nil {
fmt.Printf("生成失败: %v\n", err)
} else {
fmt.Println("生成成功!")
}
}
等等,这代码有个问题——生成的视频是纯色背景加文字,太单调了,真正的“在一起365天”背景视频,得有照片轮播、渐变效果、背景音乐,我们慢慢加功能。
进阶:加入照片和音乐
要让视频有纪念意义,得放照片,假设你有365张照片,每天一张,那就做成幻灯片,我实际做的时候照片没那么多,只放了12张,每张循环播放30秒,刚好凑够365秒。
func buildSlideShow(photos []string, duration float64) *ffmpeg-go.Stream {
// 用concat协议把所有照片连起来
inputs := []*ffmpeg-go.Stream{}
for _, photo := range photos {
// 每张照片显示30秒
input := ffmpeg-go.Input(photo, ffmpeg-go.KwArgs{
"loop": "1",
"t": fmt.Sprintf("%f", duration/float64(len(photos))),
})
inputs = append(inputs, input)
}
// 加淡入淡出转场效果
// 这个功能我调了一下午,参数不对就会出现画面闪烁
filter := "fps=24,scale=1920:1080:force_original_aspect_ratio=1,pad=1920:1080:(ow-iw)/2:(oh-ih)/2"
return ffmpeg-go.Concat(inputs).Filter(filter)
}
注意,照片分辨率不一样时,要加scale和pad滤镜,否则画面会变形,我第一版没加,女朋友的照片被拉得脸都歪了,被嘲笑了一整天。

音乐方面更简单,找一首你们都喜欢的情歌,比如周杰伦的《365天》(如果没有这首歌,就用《简单爱》),用-i参数加进去:
ffmpeg-go.Input("music.mp3").Output("temp_audio.aac").Run()
// 然后把音频和视频合起来
ffmpeg-go.Input("video.mp4").Input("temp_audio.aac").
Output("final.mp4", ffmpeg-go.KwArgs{"c:v": "copy", "c:a": "aac"}).Run()
实际运行效果
代码写好后,我在自己的Mac上编译运行,生成一个365秒的视频,大概用了37分钟,中间我喝了两杯咖啡,打了把游戏,回来一看,视频已经放在桌面上了。
打开视频,第一张照片是我们认识那天的自拍,背景是绿色的(对,我们第一次见面在植物园),屏幕正中间跳出一行字:“第1天”,然后画面渐变到第二张照片,背景音乐恰好到副歌部分,那种感觉,怎么说呢,比自己想象的还要好。
你可能会担心性能问题,Golang编译后的程序,生成1080p视频时CPU占用率在60%左右,内存用了不到200MB,这比我用Python尝试时好太多了,Python直接吃到4GB内存还没跑完。
一些你可能遇到的坑
写这个程序时,我碰到好几个让人抓狂的问题,列出来免得你重走弯路:
- 字体路径问题:
drawtext滤镜需要指定字体文件,Windows上一般用C:/Windows/Fonts/msyh.ttc,Mac上用/System/Library/Fonts/PingFang.ttc,不指定字体,中文会显示成方块。 - 照片数量要匹配:如果想精确对应365天,照片数量要整除视频时长,多一张少一张,程序不会报错,但最后几秒画面会空白。
- 输出格式:MP4格式的编码器要选H.264,兼容性最好,如果选错了编码器,某些手机打不开视频。
最后的想法
其实用Golang写这个视频生成器,代码量不大,真正花时间的是调整参数、试错、看FFmpeg文档,但当你看到最终成品时,会觉得一切都值了,365天,说长不长,说短不短,Golang帮我把这些回忆串成了一部电影,送给最在乎的人。
对了,我女朋友看完视频后说:“这比淘宝上买的模板强多了。”然后她问我能不能在视频最后加个求婚的彩蛋,我说明年这时候再说吧——先把这个生成器的代码再优化优化,明年直接生成“两周年纪念视频”。
本文来自作者[kyadmin]投稿,不代表be365立场,如若转载,请注明出处:http://www.uss1.cn/lvyou/1960.html
评论列表(4条)
我是be365的签约作者“kyadmin”!
希望本篇文章《用Golang写一个在一起365天背景视频生成器》能对你有所帮助!
本站[be365]内容主要涵盖:be365,be365网站,be365网址,ball365体育,Be365排名
本文概览:你说巧不巧,昨天刚好是我和女朋友在一起的第365天,本来想找个现成的背景视频发朋友圈,结果搜了半天,不是要会员就是有水印,干脆自己动手,...