当前位置:首页 > 单站 > 正文

一年有365个舞蹈视频,我用Golang记录每一天的舞动

  • 单站
  • 2026-07-15 12:20:12
  • 235
摘要: 这事儿得从去年元旦说起,那天我刷到一个博主,说ta坚持每天拍一个跳舞视频,一年下来攒了365个,我当时就想,这不就是我想要的吗?...

这事儿得从去年元旦说起,那天我刷到一个博主,说ta坚持每天拍一个跳舞视频,一年下来攒了365个,我当时就想,这不就是我想要的吗?但问题来了——我拍得乱七八糟,存在手机里,文件名都是“视频_20230101_203015”,跟乱码似的,找起来简直要命。

作为一个写代码的,我第一反应是:写个程序来管理这些视频,用什么语言?Python?也行,但我想挑战点新鲜的,就选了Golang,为啥?因为Go编译快、跑起来利索,处理文件操作和并发特别顺手,说干就干,我边学边写,最后还真整出了个能用的工具。

为啥要用Golang来管舞蹈视频

先列几个理由,你感受下:

  • 编译成单个二进制文件,丢哪都能跑,不用装环境
  • 并发处理,同时分析多个视频的时长、分辨率,不卡壳
  • 标准库强大osiotimeencoding/json,基本不用第三方包
  • 跨平台,Windows、macOS、Linux通吃

我当时想的是,每天拍一个视频,一年就是365个。如果用手工整理,光改文件名、写标签、记日期,每天至少花10分钟,一年下来就是3650分钟,超过60个小时。有这时间,我都能多练30支舞了

我写的第一个版本:结构体和文件扫描

先定义数据结构,这是我纠结最久的部分——既要存基本信息,又得能扩展。

type DanceVideo struct {
    FileName    string   // 原始文件名
    Renamed     string   // 重命名后的文件名
    Date        string   // 拍摄日期,格式:2023-01-01
    DanceName   string   // 舞蹈名称
    Duration    float64  // 时长(秒)
    Resolution  string   // 分辨率,"1920x1080"
    Tags        []string // 标签,["hip-hop", "编舞"]
    Notes       string   // 备注,状态不错,节奏卡得准”
}

我让程序扫描指定文件夹,把所有视频文件列出来。关键点:通过文件的修改时间或者Exif信息提取拍摄日期,Go里有个os.Stat()能拿到ModTime,再格式化成2006-01-02这个奇怪但固定的格式(Go的时间格式化就是这德行,习惯了就好)。

func scanVideos(dir string) ([]DanceVideo, error) {
    entries, err := os.ReadDir(dir)
    if err != nil {
        return nil, err
    }
    var videos []DanceVideo
    for _, entry := range entries {
        if isVideoFile(entry.Name()) {
            info, _ := entry.Info()
            v := DanceVideo{
                FileName: entry.Name(),
                Date:    info.ModTime().Format("2006-01-02"),
            }
            videos = append(videos, v)
        }
    }
    return videos, nil
}

自动重命名:让文件名有灵魂

一年365个视频,按日期重命名是最基本的,我设的规则是:日期_舞蹈名称_序号.mp4,2023年1月1日拍的waacking,就叫2023-01-01_waacking_001.mp4

但问题来了——程序怎么知道舞蹈名称? 我一开始想用API识别,后来觉得太麻烦,就偷懒了:每天拍完后,手动输个舞蹈名,或者用命令行参数传进去,我的工具支持两种模式:

  1. 交互模式:扫描出所有视频,一个一个问你要名字
  2. 批量模式:提前写好一个csv,程序照着改名

我大部分时间用交互模式,因为每天拍完,脑子里还记得今天跳的啥。直接在终端里敲个名字,几秒钟搞定,这比在手机相册里一个个重命名快太多了。

用并发提速:处理365个视频不卡

最让我得意的改进,是我加了并发处理,Go的goroutine太适合这种场景了——每个视频独立分析时长和分辨率,互不干扰。

func analyzeVideos(videos []DanceVideo) []DanceVideo {
    var wg sync.WaitGroup
    sem := make(chan struct{}, 5) // 限制最多5个并发
    for i := range videos {
        wg.Add(1)
        go func(v *DanceVideo) {
            defer wg.Done()
            sem <- struct{}{}
            duration := getVideoDuration(v.FileName)
            resolution := getVideoResolution(v.FileName)
            v.Duration = duration
            v.Resolution = resolution
            <-sem
        }(&videos[i])
    }
    wg.Wait()
    return videos
}

这里用了sem作为信号量,控制同时只跑5个任务,防止CPU爆炸,实测,分析365个视频的总时长从原来串行的15分钟,缩短到不到2分钟。生活就像并发,心里装太多事反而跳不好——我这个程序大概也懂。

生成标签和统计:跳了什么,一目了然

我一开始只存基本信息,后来发现没有标签,找视频还是费劲,比如我想找“跳得特别开心的那些”,按日期翻不如按标签搜快。

所以我加了个标签系统,每个视频可以打多个标签,"hip-hop""编舞""即兴""跳错了但贼开心"(我没开玩笑,这个标签我用了很多次),然后程序能生成一个标签云,统计每个标签出现的次数。

半年下来,我统计了一次:

  • hip-hop:出现最多,132次
  • 编舞:87次
  • 即兴:56次
  • 状态不好但硬跳:43次
  • 跳错了:28次
  • 完美一遍过:才12次(说明我对自己挺严格)

这些数字让我突然意识到:我其实更喜欢自由发挥,即兴的占比不低,而且那些“跳错了但贼开心”的视频,回头看反而笑得最大声。

年度回顾:365个视频,我看见了什么

用这个程序跑完一整年的视频,我生成了一个年度统计报告,用Go写了个简单的HTML生成器,把数据渲染成一个表。

年度舞蹈数据汇总(节选)

月份 视频数 总时长(分钟) 最常用标签
1月 31 467 新年新舞
2月 28 422 编舞
3月 31 480 hip-hop
4月 30 455 即兴
5月 31 478 状态不错
6月 30 451 跳错了
总计 365 5489 即兴

5489分钟,大概91个小时。也就是说,这一年里,我有将近4天的时间,在跳舞,平均每个视频15分钟,最长的一个跳了45分钟(那次状态实在太好,停不下来),最短的2分钟(感冒了跳不动,但不想断掉)。

程序还统计了我的最佳时段:大部分视频在晚上8点到10点之间拍,偶尔早上拍,都是周末,这说明我白天都在工作、写代码,晚上才是自己的时间。数据不会说谎,它只是忠实地记录你

Golang帮了我什么

我用Go写这个工具,不是为了炫技,是真的需要个趁手的家伙,Go的静态编译让我一键部署——生成的exe文件扔进DanceVideo文件夹,双击就开干。defergoroutine让代码干净利落,我最喜欢的一点是:Go的error处理逼着你直面问题,比如视频文件损坏时,程序不会静悄悄跳过,而是打印一条警告,让你决定怎么办,这比某些语言默默吞掉异常强多了。

当然也有不爽的地方,Go的ffmpeg绑定库不太好用,我索性直接用exec.Command调用系统ffmpeg,简单粗暴,还有,写GUI太麻烦,我就用终端命令行了,朋友笑我“2023年了还对着黑框框操作”,但我觉得:命令行有命令行的浪漫,当我对着Terminal敲下dance --year 2023 --stats,然后看到一整年的数据铺展开来时,那种掌控感是鼠标点不出来的。

一年是365个舞蹈视频,也是365次按下录制键,写Go让我看到了代码之外的东西——它不只是解决技术问题,更是把你跟生活连接起来的桥梁,我跳的每一段舞,都被记录下来了,不是因为视频在硬盘里,而是因为有个程序,替我记住了每一刻的汗水、笑容、跑调的音乐,和偶尔的没错我就是跳错了但我不在乎。

如果你也在做一件需要坚持一年的事,不管是什么,找个趁手的工具,不一定是Go,可以是任何让你觉得舒服的东西,关键是,不要一个人硬撑着,代码可以帮你扛一部分,剩下的,交给时间。

一年有365个舞蹈视频,我用Golang记录每一天的舞动