用 Go 语言和 FFmpeg 做365天倒计时视频?别懵,其实就这几步

家人们,今天聊个有点意思的事:你刷短视频时,肯定见过那种“距离2026年还有XXX天”的倒计时视频吧?说实话,第一次看到那玩意儿,我还真...

家人们,今天聊个有点意思的事:你刷短视频时,肯定见过那种“距离2026年还有XXX天”的倒计时视频吧?说实话,第一次看到那玩意儿,我还真以为是某个大神用AE(After Effects)一帧帧抠出来的,直到有天我闲着没事,用Go写了个小工具,才发现——这玩意儿根本不用碰PR(Premiere Pro),一行代码都不用改视频剪辑软件,纯靠代码就能搞定,今天我就把这块硬骨头,用最接地气的方法给你拆开揉碎了讲。

倒计时视频到底是个啥?

说白了,365天倒计时视频就是一张不断变化的数字图——今天是365,明天是364,后天是363……直到最后一天变成0,但你要真把这365张图扔到视频剪辑软件里,一帧帧手动调,那估计得累到住院。

核心问题就仨:

  • 怎么自动生成带数字的图片?
  • 怎么把这些图片变成视频?
  • 怎么让视频每天自动更新?

而我们的武器,就是Go语言和FFmpeg,听起来高大上?放心,你不需要成为程序员,只要你能复制粘贴代码,就能搞定。

准备工作:你需要的东西

先列个清单,别嫌麻烦,就三样东西:

工具 用途 怎么弄到
Go语言(版本1.20+) 写代码自动生成图片 官网下载,安装时一路“下一步”
FFmpeg 把图片合成视频 官网下,解压后记得加到系统环境变量
一个文本编辑器 写代码 记事本都行,但推荐VS Code

安装检测小技巧: 打开终端(Windows是CMD或PowerShell,Mac是终端),分别输入 go versionffmpeg -version,看到版本信息就算装好了。

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

很多人觉得生成图片得用Photoshop,其实Go自带的image库就能搞定,你看这代码,核心就20行:

package main
import (
    "fmt"
    "image"
    "image/color"
    "image/png"
    "os"
    "time"
)
func main() {
    // 计算到目标日期的天数
    target := time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)
    days := int(time.Until(target).Hours() / 24)
    // 创建一张1920x1080的图片
    img := image.NewRGBA(image.Rect(0, 0, 1920, 1080))
    // 背景设为黑色
    for y := 0; y < 1080; y++ {
        for x := 0; x < 1920; x++ {
            img.Set(x, y, color.RGBA{0, 0, 0, 255})
        }
    }
    // 上面只是骨架,实际你得用第三方库绘制文字
    // 咱们下一点会说怎么用更省事的库
}

等等,上面这段跑不了,因为Go标准库没法直接画文字。 别急,我给你推荐个神器:golang.org/x/image/fontgithub.com/golang/freetype,这两个库能加载字体文件,然后把文字“摁”到图片上。

实际能跑的版本长这样:

// 用第三方库 gg(go-graphics)来画图
package main
import (
    "fmt"
    "github.com/fogleman/gg"
    "time"
)
func main() {
    const W, H = 1920, 1080
    dc := gg.NewContext(W, H)
    // 设置背景色
    dc.SetRGB(0, 0, 0)
    dc.Clear()
    // 加载字体(提前下载一个.ttf字体文件)
    if err := dc.LoadFontFace("/path/to/your/font.ttf", 200); err != nil {
        panic(err)
    }
    // 计算天数
    target := time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)
    days := int(time.Until(target).Hours() / 24)
    // 画数字
    dc.SetRGB(1, 1, 1) // 白色
    dc.DrawStringAnchored(fmt.Sprintf("%d", days), W/2, H/2, 0.5, 0.5)
    // 保存图片
    dc.SavePNG("countdown.png")
}

注意: 这个库需要先安装:go get github.com/fogleman/gg,别怕报错,终端里敲一遍就行。

第二步:把图片转成视频

图片有了,现在要把它变成视频,FFmpeg命令非常简单:

ffmpeg -loop 1 -i countdown.png -c:v libx264 -t 10 -pix_fmt yuv420p countdown.mp4

这个命令的意思是:把countdown.png这张图片循环显示10秒,输出一个MP4文件,但365天的倒计时不能只有10秒啊,你至少得让数字显示5秒以上,不然观众看不清。

优化版本: 生成多张图片,然后合成视频,比如生成365张图,每张显示1帧:

ffmpeg -framerate 1 -i frame_%03d.png -c:v libx264 -r 30 -pix_fmt yuv420p output.mp4

这里framerate 1表示每秒1帧,-i frame_%03d.png会读取frame_001.pngframe_002.png这种命名规则的文件。

用 Go 语言和 FFmpeg 做365天倒计时视频?别懵,其实就这几步

第三步:自动生成365天的所有图片

用手一张张生成365张图不现实,得写个循环,在Go里很简单:

target := time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)
for i := 0; i < 365; i++ {
    // 第i天距离目标的天数
    days := 365 - i
    // 生成图片代码同上
    // 文件名:frame_001.png, frame_002.png ...
    fileName := fmt.Sprintf("frame_%03d.png", i+1)
    // 保存图片
}

但等等—— 你要是真这么干,会发现生成的视频只有12秒左右(365帧/30fps≈12秒),而且数字变化太快,根本看不清。建议改成: 每张图显示5帧,即-framerate 0.2(每秒0.2帧),这样总时长就是365/0.2=1825秒,约30分钟,或者每张图显示1秒,生成30fps的视频,需要把每张图复制30次,这样总时长还是365秒。

更省事的做法: 在FFmpeg里直接指定每张图的持续时间:

ffmpeg -framerate 1/5 -i frame_%03d.png -c:v libx264 -r 30 -pix_fmt yuv420p output.mp4

framerate 1/5表示每张图显示5秒,这样总时长就是365*5=1825秒。

第四步:让视频每天自动更新

这才是真正牛逼的地方——你不想每天手动跑代码吧?

写个定时任务,Windows用“任务计划程序”,Mac/Linux用cron,每天凌晨0点跑一次Go程序,生成当天的新图片,然后用FFmpeg替换掉视频文件。

放到服务器上,用Nginx或者云存储,视频链接保持不变,但文件每天自动更新,这样你在网站上嵌入的倒计时视频,每天都是新的。

举个例子(Linux cron):

0 0 * * * /usr/local/bin/go run /home/user/countdown.go && ffmpeg ... && cp output.mp4 /var/www/video/

简单说,就是午夜12点,自动生成新视频,然后覆盖掉旧的

实际会遇到的问题(我踩过的坑)

你以为照着上面做就成了?天真,我实践时遇到了至少5个问题:

  1. 字体乱码:中文显示成方框,解决方法:下载中文字体(比如思源黑体),用绝对路径加载。
  2. 视频黑屏:FFmpeg报错pix_fmt问题,加上-pix_fmt yuv420p就能解决。
  3. 数字位置不对:文字居中时,不同字体基线不一样,用DrawStringAnchored函数的最后两个参数调整锚点。
  4. 生成太慢:365张图如果用Go的gg库一张张生成,大概需要10秒,优化方法:用goroutine并行生成,或者只生成一张图然后用FFmpeg的t参数控制时长。
  5. 云存储同步:如果你用阿里云OSS,注意设置Cache-Control头为no-cache,否则CDN缓存会让你看到旧的视频。

终极优化:只生成一张图,用FFmpeg搞定一切

完全不用生成365张图,因为倒计时的数字是每天变化的,但视频里的背景、字体、位置都是固定的,所以只需要一张模板图,然后让FFmpeg在运行时动态嵌入当前日期。

方法: 用FFmpeg的drawtext滤镜。

ffmpeg -i background.jpg -vf "drawtext=text='%{eif\:floor((2026-1-1-t)/86400)\:d}':fontfile=/path/to/font.ttf:fontsize=200:fontcolor=white:x=(w-tw)/2:y=(h-th)/2" -t 10 output.mp4

这个命令里,%{eif\:floor((2026-1-1-t)/86400)\:d}的意思是:计算从当前时间到2026年1月1日的秒数差,除以86400得天数,然后显示在视频中央。

优点:

  • 代码量从50行变成1行
  • 不需要每天生成新文件
  • 视频文件只有几百KB

缺点:

  • 只能在支持FFmpeg的环境下播放(浏览器里没问题)
  • 需要服务器每天重新渲染(或者用流媒体协议)

最后说点大实话

说实话,整个方案最麻烦的不是代码,而是测试,你得反复调字体的位置、大小、颜色,还要考虑视频在不同平台的兼容性——抖音、B站、视频号,每个平台的画面裁剪比例都不一样。

我的建议是: 先用Go生成静态图片,确认效果满意了,再决定是用逐帧生成还是FFmpeg动态方案,别一上来就搞复杂了。

文章写到这里,我也饿了,你去试试那些代码吧,有问题回来评论区留言,咱们接着唠。

对了,别忘了给Go程序加个time.Sleep防止午夜瞬间生成失败,这事儿我吃过大亏。

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

(14)

文章推荐

发表回复

本站作者才能评论

评论列表(4条)

  • kyadmin
    kyadmin 2026-06-26

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

  • kyadmin
    kyadmin 2026-06-26

    希望本篇文章《用 Go 语言和 FFmpeg 做365天倒计时视频?别懵,其实就这几步》能对你有所帮助!

  • kyadmin
    kyadmin 2026-06-26

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

  • kyadmin
    kyadmin 2026-06-26

    本文概览:家人们,今天聊个有点意思的事:你刷短视频时,肯定见过那种“距离2026年还有XXX天”的倒计时视频吧?说实话,第一次看到那玩意儿,我还真...

    联系我们

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

    关注我们