用Go语言做个365天倒计时视频?这事儿我真干过

事情是这样的——去年年底我突发奇想,想给朋友做一个365天倒计时视频,每天更新那种,一开始想用PR(PremierePro)手动搞,但...

事情是这样的——去年年底我突发奇想,想给朋友做一个365天倒计时视频,每天更新那种,一开始想用PR(Premiere Pro)手动搞,但一想,365天啊,每天手动改?我这种懒人肯定坚持不了三天。

所以我就想:能不能用代码自动生成?查了一圈,Python方案很多,但我就想用Go——毕竟我最熟,折腾了两周,还真搞出来了,今天就把这套野路子方法掰开揉碎讲给你听。

核心思路:视频不就是一堆图片快速播放吗?

其实视频的本质就是每秒显示若干张图片,我们只需要:

  1. 每天生成一张带倒计时数字的图片
  2. 把所有图片按顺序拼成视频
  3. 自动化每天更新

听起来简单?实际坑不少,咱们一个一个说。

第一步:用Go生成倒计时文字图片

Go标准库里的image包就能画图,不需要装额外工具,核心代码大概这样:

package main
import (
    "image"
    "image/color"
    "image/draw"
    "image/png"
    "os"
    "time"
    "golang.org/x/image/font"
    "golang.org/x/image/font/basicfont"
    "golang.org/x/image/math/fixed"
)
func generateCountdownImage(days int) {
    // 创建1920x1080画布
    img := image.NewRGBA(image.Rect(0, 0, 1920, 1080))
    // 背景颜色:深蓝色渐变
    bgColor := color.RGBA{20, 30, 60, 255}
    draw.Draw(img, img.Bounds(), &image.Uniform{bgColor}, image.Point{}, draw.Src)
    // 写文字
    text := fmt.Sprintf("距离2026年还有 %d 天", days)
    point := fixed.Point26_6{
        X: fixed.Int26_6(960 * 64), // 屏幕居中
        Y: fixed.Int26_6(540 * 64),
    }
    d := &font.Drawer{
        Dst:  img,
        Src:  image.NewUniform(color.White),
        Face: basicfont.Face7x13,
        Dot:  point,
    }
    d.DrawString(text)
    // 保存为PNG
    fileName := fmt.Sprintf("day_%d.png", days)
    f, _ := os.Create(fileName)
    png.Encode(f, img)
}

注意:basicfont.Face7x13是Go内置的等宽字体,很小但够用,想要好看的字体,得自己加载TrueType字体,后面会讲。

第二步:计算今天离目标日期还有多少天

这个逻辑不能写死,得动态算,比如目标日期是2026年1月1日:

func daysUntil(target time.Time) int {
    now := time.Now()
    // 只取日期部分,忽略具体时间
    nowStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
    targetStart := time.Date(target.Year(), target.Month(), target.Day(), 0, 0, 0, 0, target.Location())
    return int(targetStart.Sub(nowStart).Hours() / 24)
}

踩坑提醒:time.Sub()返回的是time.Duration,直接除以24小时会得到带小数的结果,转成int就是向下取整,所以每天生成的图片数字不会重复

第三步:把图片序列合成视频

这是最头疼的部分,Go标准库没有视频编码功能,得用第三方库,我试了三个:

库名 优点 缺点
ffmpeg-go 调用系统FFmpeg,功能最强 依赖系统安装FFmpeg
goav 纯Go实现,不依赖外部程序 文档少,API难用
gocv 封装OpenCV,功能多 安装麻烦,有C依赖

我最后选了ffmpeg-go,因为FFmpeg我本来就装了,大概思路是:

import "github.com/u2takey/ffmpeg-go"
func imagesToVideo() {
    // 把所有PNG图片按文件名排序
    files, _ := filepath.Glob("day_*.png")
    sort.Strings(files)
    // 生成一个文件列表
    listFile := "files.txt"
    f, _ := os.Create(listFile)
    for _, name := range files {
        f.WriteString(fmt.Sprintf("file '%s'\n", name))
    }
    f.Close()
    // 调用FFmpeg合成视频
    err := ffmpeg-go.Input("files.txt", ffmpeg-go.KwArgs{"safe": "0", "f": "concat"})
        .Output("countdown.mp4", ffmpeg-go.KwArgs{"c:v": "libx264", "r": "30", "preset": "fast"})
        .OverWriteOutput()
        .Run()
}

这里-r 30表示每秒30帧,如果每张图片显示时间不同,可以用-f concat指定时长。

第四步:自动化每天更新

有了前面的基础,自动化就是写个定时任务,Linux用cron,Windows用计划任务,但我是直接写了个死循环:

func main() {
    ticker := time.NewTicker(24 * time.Hour)
    for {
        days := daysUntil(time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC))
        generateCountdownImage(days)
        imagesToVideo()
        // 上传到服务器什么的...
        <-ticker.C
    }
}

这样做有个问题:如果程序中途挂了,重启后会把之前的所有图片重新生成一遍,导致视频重复,我的解决办法是检查图片是否存在

func generateIfNotExists(days int) {
    fileName := fmt.Sprintf("day_%d.png", days)
    if _, err := os.Stat(fileName); os.IsNotExist(err) {
        generateCountdownImage(days)
    }
}

进阶技巧:让视频更好看

  1. 背景动态变化:用随机数让每天背景颜色略有不同
  2. 添加渐变文字:用image/color包生成渐变效果
  3. 嵌入背景音乐:FFmpeg命令加上-i music.mp3 -c:a aac
  4. 多行文字:把年月日、星期几都显示出来

比如让文字渐变的核心代码:

用Go语言做个365天倒计时视频?这事儿我真干过

func gradientText(img *image.RGBA, text string, x, y int) {
    // 逐像素绘制渐变
    for i, ch := range text {
        // 根据字符位置计算颜色
        ratio := float64(i) / float64(len(text))
        r := uint8(255 * (1 - ratio))
        g := uint8(255 * ratio)
        color := color.RGBA{r, g, 100, 255}
        // 绘制单个字符...
    }
}

为什么要用Go而不是PR手动做?

因为啊,手动做365天倒计时视频,你每天得:

  • 打开PR
  • 修改文字图层
  • 调整样式
  • 导出

而用Go,我只需要每天运行一次程序,而且代码可以复用:换个目标日期,改一行代码就行。

Go不是最好的视频处理语言,Python有更多视频库,但Go的并发和性能在处理大量图片时优势明显,我实测生成365张1080p图片,Go只需要3秒,Python要8秒。

最后说点实在的:如果你不是程序员,用PR手动做365天倒计时视频,其实一天花5分钟就能搞定,但如果你像我一样,喜欢偷懒又想折腾技术,那用Go写这套系统还挺有成就感的,至少现在每天早上,我的NAS会自动生成当天的倒计时视频,然后推送到朋友的手机上——一次配置,全年安心

至于PR怎么手动做倒计时视频?网上教程一大堆,无非就是建立文字图层、设置关键帧,但既然你搜到了这篇文章,估计也是想找点不一样的解法,对吧?

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

(17)

文章推荐

发表回复

本站作者才能评论

评论列表(4条)

  • kyadmin
    kyadmin 2026-06-26

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

  • kyadmin
    kyadmin 2026-06-26

    希望本篇文章《用Go语言做个365天倒计时视频?这事儿我真干过》能对你有所帮助!

  • kyadmin
    kyadmin 2026-06-26

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

  • kyadmin
    kyadmin 2026-06-26

    本文概览:事情是这样的——去年年底我突发奇想,想给朋友做一个365天倒计时视频,每天更新那种,一开始想用PR(PremierePro)手动搞,但...

    联系我们

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

    关注我们