你有没有那种感觉,手机里存了几千张照片,但一年到头也翻不了几次,去年年底我翻相册,看到365天前的自己,突然想——要不把这些零碎的记忆,做成一个快闪视频?就是那种每张照片闪一两秒,配着音乐刷过去的效果,我本来想找现成软件,但要么收费,要么乱七八糟的广告,后来一想,我写Go的啊,干嘛不自己搞一个?
于是就有了这篇——用Go语言一步步实现365回忆快闪视频,不是那种教科书式的教程,就是我自己踩坑之后,把真正能跑通的方法记下来。
为什么选Go?不选Python?
很多人第一反应是Python,确实Python处理视频的库多,但Go有个好处——编译出来一个二进制文件,扔到哪都能跑,你想啊,如果你做好了要给爸妈用,难道还让人家装Python环境?Go就直接双击运行。
而且Go的并发处理在渲染大量图片的时候很有优势,365张图,如果用单线程一张张处理,等得能睡着,Go的goroutine一上,速度直接起飞。
准备工作:你需要装什么?
| 工具 | 说明 | 安装方式 |
|---|---|---|
| FFmpeg | 视频编码核心 | brew install ffmpeg (Mac) / apt install ffmpeg (Linux) |
| Go | 18以上版本 | go.dev 下载 |
| 图片素材 | 365张,建议统一尺寸 | 手机相册导出即可 |
安装好之后,打开终端敲 ffmpeg -version,看到版本号就说明成了。
第一步:把图片整理成序列
快闪视频的原理很简单——把图片按顺序拼接成视频,FFmpeg要求图片文件名有规律,img_0001.jpg、img_0002.jpg。
但我们的照片可能叫 2024-01-15-生日.jpg、2024-03-20-爬山.jpg,所以第一件事就是批量重命名。
我写了个Go程序干这事:
package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
)
func main() {
srcDir := "./photos"
destDir := "./renamed"
os.MkdirAll(destDir, 0755)
files, _ := ioutil.ReadDir(srcDir)
for i, f := range files {
ext := filepath.Ext(f.Name())
newName := fmt.Sprintf("img_%04d%s", i+1, ext)
// 复制到新目录
input, _ := ioutil.ReadFile(filepath.Join(srcDir, f.Name()))
ioutil.WriteFile(filepath.Join(destDir, newName), input, 0644)
}
fmt.Println("重命名完成!共处理", len(files), "张图片")
}
这代码不高级,但实用,跑完之后 renamed 文件夹里就是排序好的图片,注意顺序是按文件名排序的,如果你想让某张照片先出现,可以提前在文件名里加日期前缀。
第二步:用FFmpeg生成快闪视频
图片整理好了,接下来就是调用FFmpeg,Go里执行外部命令用 os/exec 包:
cmd := exec.Command("ffmpeg",
"-framerate", "1", // 每秒1帧,也就是每张图显示1秒
"-i", "./renamed/img_%04d.jpg",
"-c:v", "libx264",
"-pix_fmt", "yuv420p",
"-vf", "scale=1920:1080", // 统一分辨率
"output.mp4",
)
err := cmd.Run()
我一开始设的 -framerate 是 1,也就是说每张照片停留1秒,但365张就要6分钟,太长了,后来改成 2,也就是每秒2帧,每张图0.5秒,节奏就对了。
如果你想更炫酷,可以加转场效果,但快闪视频的精髓就是快,转场反而拖节奏。
第三步:加背景音乐
光有图片没音乐,就像吃面没汤,我找了一段无版权的轻快BGM,加到视频里:
cmd := exec.Command("ffmpeg",
"-i", "output.mp4", // 视频文件
"-i", "bgm.mp3", // 音乐文件
"-shortest", // 以较短的为准(视频)
"-c:v", "copy",
"-c:a", "aac",
"-map", "0:v:0",
"-map", "1:a:0",
"final.mp4",
)
这里有个坑——音乐时长可能超过视频,用 -shortest 参数,FFmpeg会自动裁剪到和视频一样长,另外要注意音乐版权,别随便用流行歌,万一发到朋友圈被投诉就尴尬了。
第四步:高级玩法——按月份分组
365张图全闪一遍,其实挺累的,我后来改成了按月份分组,每个月选10张最有代表性的照片,12个月就是120张,节奏更舒服。
做法很简单:重命名的时候,先按月份建子文件夹:

renamed/
01-一月/
02-二月/
...
然后每个文件夹独立生成一段小视频,最后用 concat 协议拼接:
// 生成文件列表
listContent := ""
for i := 1; i <= 12; i++ {
monthDir := fmt.Sprintf("./renamed/%02d-*", i)
// 假设每个月份视频叫 month_01.mp4
listContent += fmt.Sprintf("file 'month_%02d.mp4'\n", i)
}
ioutil.WriteFile("filelist.txt", []byte(listContent), 0644)
// 拼接
cmd := exec.Command("ffmpeg",
"-f", "concat",
"-safe", "0",
"-i", "filelist.txt",
"-c", "copy",
"year_montage.mp4",
)
这样出来的视频,每个月一个片段,每段里是那个月的精选瞬间,配上音乐,看完真的会鼻子一酸——这一年原来经历了这么多。
关于代码的一点唠叨
上面的代码片段都是简化版的,实际用的时候要加错误处理,比如检查文件是否存在、FFmpeg有没有装、图片格式对不对,我在代码里加了 if err != nil 然后打印错误信息,至少知道哪一步挂了。
不要直接覆盖原图,我一开始就干过这事,重命名的时候不小心把原图搞乱了,恢复花了半天,血的教训——操作之前先备份,或者复制到新目录操作。
一点小建议
如果你着急用,其实可以直接用FFmpeg命令行,连Go都不用写,但如果你像我一样,想每年自动生成一个回忆视频,那写个Go程序就是一次投入、年年复用。
今年年底,我打算把程序改一改,加上文字水印,每张照片右下角显示日期,这样以后看视频,能准确知道是哪天拍的,代码大概长这样:
"-vf", "drawtext=text='2024-01-15':x=10:y=10:fontsize=24:fontcolor=white"
FFmpeg的 drawtext 滤镜功能很强,但需要编译时开启 --enable-libfreetype,如果你下载的是官方版,一般默认就有。
好了,这就是我用Go做365回忆快闪视频的全部过程,代码不完美,但够用,视频做出来的那一刻,看着一年里的点点滴滴从眼前闪过,那种感觉,值得你折腾一个下午。
本文来自作者[kyadmin]投稿,不代表be365立场,如若转载,请注明出处:http://www.uss1.cn/fnagchan/1057.html
评论列表(4条)
我是be365的签约作者“kyadmin”!
希望本篇文章《用Go语言给365回忆做快闪视频?这招我试过了,真香》能对你有所帮助!
本站[be365]内容主要涵盖:be365,be365网站,be365网址,ball365体育,Be365排名
本文概览:你有没有那种感觉,手机里存了几千张照片,但一年到头也翻不了几次,去年年底我翻相册,看到365天前的自己,突然想——要不把这些零碎的记忆,...