当前位置:首页 > 健康 > 正文

用Golang陪孩子看365儿歌视频二年级,我踩过的坑和总结的干货

  • 健康
  • 2026-07-09 00:23:37
  • 300
摘要: 说起来你可能不信,我学Go语言最开始不是写服务端,也不是搞云原生,而是为了陪我家娃看365儿歌视频二年级,听起来是不是有点离谱?...

说起来你可能不信,我学Go语言最开始不是写服务端,也不是搞云原生,而是为了陪我家娃看365儿歌视频二年级,听起来是不是有点离谱?但还真就是这么回事。

我家孩子上二年级,老师推荐了一套365儿歌视频,说每天看一个,一年刚好轮一遍,孩子倒是挺爱看,问题出在家长这边——我每天下班回来要帮她在电脑上找对应的视频,翻文件夹、点播放器、调音量,有时候播到一半还卡住,一开始我用批处理写了个简单的播放器,用os.StartProcess调系统播放器,勉强能用,但后来需求越来越多,比如要按周记录观看进度、标注哪些儿歌孩子最喜欢、甚至统计“这首歌今天看了几遍”,批处理和Python搞来搞去,越改越乱,于是我想:“要不试试Go吧?”

这一试,还真试出了点东西。

为什么我用Golang来处理365儿歌视频二年级的播放

不是我故意要装技术大佬,实际原因很朴素:Go打包成单个exe,拿到家里那台老Windows笔记本上就能跑,不用装Python环境,不用管VLC的DLL依赖,我只需要写一个简单的命令行工具,调用os/exec包执行播放命令就行。

下面是我最早期的核心代码片段,大概长这样:

package main
import (
    "fmt"
    "os/exec"
    "path/filepath"
)
func playVideo(path string) error {
    cmd := exec.Command("cmd", "/c", "start", "", filepath.Clean(path))
    return cmd.Run()
}

你看,就这么几行,在Windows上就能用默认播放器打开视频,但问题是“365儿歌视频二年级”这个合集文件夹里有100多个视频,文件名是“第001首 小星星.mp4”这种格式,手动选太累了,所以我加了个简单的菜单交互。

文件管理才是真正的坑

我本以为最麻烦的写播放功能,结果根本不是,最麻烦的是文件命名和排序,365儿歌视频二年级的资源来源渠道不同,有的文件名叫“01 小燕子.mp4”,有的叫“第2课 数鸭子.mp4”,还有的直接就叫“video_003.mp4”——这种没标题的根本不知道播的是啥。

Go的path/filepath包和os.ReadDir用起来倒是顺手,但排序时要按自然顺序而不是字典序,Golang的sort.Strings默认字典序,会导致“第10首”排在“第2首”前面,所以必须写个自定义排序。

我参考了网上的一些实现,写了个简单的数字提取函数:

func extractNumber(name string) int {
    re := regexp.MustCompile(`\d+`)
    match := re.FindString(name)
    num, _ := strconv.Atoi(match)
    return num
}

sort.SliceStable来排序,总算解决了播放顺序的问题,这让我意识到,处理365儿歌视频二年级这类资源,文件管理比播放本身更需要精力

进度跟踪的数据结构设计

孩子每天看一两首,但我记不住昨天看到哪了,用Excel记录也行,但我想着既然是程序员,就该用程序员的办法。

我用Go的encoding/csv包写了一个进度文件,结构很简单:

字段名 类型 说明
SongID int 歌曲编号
Viewed bool 是否已观看
Like bool 孩子是否喜欢
ViewCount int 观看次数
LastViewed string 最后观看日期

这个表格放在一个progress.csv里,每次播放完自动更新,刚开始我直接用os.ReadFilestrings.Split手动解析,后来觉得太糙,改用了encoding/csv,Go的CSV库好用得不像话,读出来的数据直接塞进结构体切片。

这里有个小发现:孩子最喜欢哪首儿歌这个数据特别好用,统计下来,365儿歌视频二年级里,我家娃最喜欢的是《蜗牛与黄鹂鸟》,看了17遍,排在后面的是《小毛驴》和《数鸭子》,这些数据让我能针对性调整播放顺序:把喜欢的那几首稍微隔开,避免孩子反复只听同一首。

播放列表的随机和去重

孩子看多了也会腻,所以我写了个随机播放功能,但必须保证“今天没看过的优先”,逻辑是这样的:

  1. 从365儿歌视频二年级的列表中筛选当天未播放的视频
  2. 如果全部已播放,就重置所有状态
  3. 在未播放列表中随机选一首
  4. 如果孩子手动选了某首歌,优先播放那首

这段代码用math/randtime.Now().UnixNano()做种子,Go的随机用起来很简单,但有一点要注意:默认的rand是伪随机,不加种子每次结果一样,我踩过这个坑,有次调试时连播三遍同一首歌,孩子说“爸爸你是不是只会放这一首”,尴尬得不行。

从命令行到简单GUI

命令行用了一段时间,老婆说“太丑了,字太小,我操作不来”,于是我开始找Go的GUI方案。

试过fyne,界面干净,但打包体积有点大,也试过walk(Windows专属),但回调写起来有点繁琐,最后用了webview,用HTML+CSS写界面,Go起一个本地HTTP服务,浏览器窗口嵌入进去。

前端界面很简单:左边是365儿歌视频二年级的列表,右边是播放区域,顶部有搜索框,底部显示播放进度,CSS用的是一套现成的儿童主题,圆角、鲜艳配色、大按钮。

核心逻辑变成了:

http.HandleFunc("/api/songs", func(w http.ResponseWriter, r *http.Request) {
    json.NewEncoder(w).Encode(songs)
})
http.HandleFunc("/api/play", func(w http.ResponseWriter, r *http.Request) {
    songID := r.URL.Query().Get("id")
    go playVideo(songs[songID].Path)
    w.Write([]byte("playing"))
})

前后端分离,Go只管数据和播放,界面交给前端,这样改完后,老婆操作起来没问题了,孩子自己也能点着玩——当然是在我监督下。

处理播放列表的“脏数据”

365儿歌视频二年级的资源有一个特点:质量参差不齐,有的视频码率低到离谱,有的音画不同步,还有的标题完全对不上内容,比如文件名写着“第50首 小燕子”,点开发现是《卖报歌》,这种脏数据用程序很难完美处理,但我写了一组辅助函数:

  • checkDuration:读取视频时长,如果少于10秒或超过10分钟,标记为异常
  • checkAudio:用ffprobe检查音频流是否存在
  • renameByContent:提取视频前几帧的文字标题,自动重命名

这些都不是Go本身的强项,需要调外部工具,Go的优势在于能把所有工具的调用整合起来,做成一个统一的命令行接口,调用ffmpegffprobe时,用exec.Command配合os.Pipe捕获输出,再解析JSON格式的返回结果。

日志和错误处理

孩子用的时候最怕出错弹框,所以我加了一套日志系统,所有错误都写到日志文件里,界面上只显示友好的提示:“视频加载失败,请帮我检查文件是否存在”,日志文件记录了:

  • 播放失败的视频路径
  • 错误类型(文件不存在、格式不支持、播放器异常)
  • 操作时间

Go的错误处理被很多人吐槽,但在这个场景下反而合适,每个可能出错的步骤都得处理,否则程序就崩,我用log.Fatalln处理严重错误,用log.Printf记录非致命错误。

现成的开源方案参考

我不是全从零造的轮子,参考了几个GitHub上的项目:

  • go-playlist:一个基于Go的命令行播放列表管理器,它的排序算法启发了我
  • vidlist:一个用Go写的视频列表生成工具,代码很简洁,我从中学习了很多关于文件遍历和元数据提取的思路
  • kids-video-manager:专门针对儿童视频资源管理的一个实验性项目,作者也是个家长,我们线上聊过

这些项目让我少走了很多弯路,特别是文件命名标准化那部分,直接拿来改改就能用。

实际效果和数据

用这套系统管理365儿歌视频二年级半个月后,我统计了一下:

  • 平均每天观看2.3首
  • 完整看完一遍需要大约4个月(按每天2首,每首3-4分钟算)
  • 孩子最喜欢的前五首:蜗牛与黄鹂鸟(17次)、小毛驴(14次)、数鸭子(13次)、小燕子(11次)、采蘑菇的小姑娘(10次)
  • 妈妈满意度指数:从30%上升到80%(主要因为不用手动找视频了)
  • 我的Go水平:从入门升到了能写小工具的程度

这个过程中,我边写边试,边试边改,有时候加点新功能,有时候修个bug,有时候干脆重写某个模块,就像一个菜谱一样,不是照着做一遍就完事了,得根据自家孩子的口味调整火候和调料。

最重要的一点是:不要试图一开始就做一个完美的系统,我第一版只用30行代码实现了播放,后面才慢慢加进度、统计、GUI、日志,如果上来就想整个大而全的东西,大概率会烂尾。

现在每天回到家,孩子会跑来跟我说:“爸爸,我今天想看‘蜗牛和鹂鸟’!”我打开电脑,点两下,视频就播起来了,她看得开心,我也松了口气——至少不用再翻文件夹了。

用Golang陪孩子看365儿歌视频二年级,我踩过的坑和总结的干货