开头先唠两句
哎,说起来你可能不信,我最近接了个活儿——用Go语言写个工具,专门处理东北二人转365首视频的元数据整理,就是那种“正月里来是新年儿”的经典唱段,配上现代编程语言,这反差感绝了,你别笑,真有人需要这个,咱东北那旮旯的民间艺术,现在也讲究数字化管理了。
为啥非得用Golang?
你可能要问,处理视频列表用Python不香吗?PHP不也挺顺手?但咱得说实话,Go在这件事上有几个硬道理:
第一,并发处理视频信息,365首视频,每首都要读时长、解析文件名、提取标签、生成缩略图索引,Go的goroutine天生就是干这个的,咱写个sync.WaitGroup,一把梭,几十个视频同时处理,那效率蹭蹭的。
第二,部署简单,给剧团老师傅装个工具,你总不能让人家先装Python环境吧?Go编译出来就是单个可执行文件,Windows上一跑,完事儿,双击就运行,跟打开视频播放器一样顺手。
第三,标准库够硬。encoding/json处理配置,net/http起个本地服务,os文件操作,全内置,真不用第三方依赖,干净利落。
核心代码思路(边写边琢磨)
package main
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"sort"
"strings"
"sync"
"time"
)
type ErRenZhuan struct { string `json:"title"`
FileName string `json:"file_name"`
Duration float64 `json:"duration"`
Tags []string `json:"tags"`
Index int `json:"index"`
}
type VideoProcessor struct {
mu sync.Mutex
videos []ErRenZhuan
dirPath string
}
这段代码没啥稀奇的,就是定义了数据结构,但你细品,sync.Mutex锁,就是为了防止多个goroutine同时写切片的时候数据错乱,咱东北人办事儿讲究个“稳当”,可不能因为并发把数据写花了。
文件遍历,得讲究个顺序
365首视频,文件名可能是“001_夫妻回门.mp4”、“002_猪八戒背媳妇.mp4”这种,咱得按数字排好序,不然播放器列表乱糟糟的。

func (vp *VideoProcessor) scanFiles() error {
entries, err := os.ReadDir(vp.dirPath)
if err != nil {
return fmt.Errorf("读目录失败: %w", err)
}
files := make([]string, 0)
for _, e := range entries {
if !e.IsDir() && strings.HasSuffix(e.Name(), ".mp4") {
files = append(files, e.Name())
}
}
sort.Strings(files) // 字符串排序,数字开头的基本靠谱
for i, name := range files {:= strings.TrimSuffix(name, filepath.Ext(name))
// 提取标签:可以把“二人转”、“传统”这种词自动打上
tags := extractTags(title)
vp.videos = append(vp.videos, ErRenZhuan{ title,
FileName: name,
Index: i + 1,
Tags: tags,
})
}
return nil
}
你看,排序用的sort.Strings,虽然简单但管用,文件名要是“第1集”和“第10集”这种,字符串排序就不太灵光了,但咱这情况,数字前缀占多数,凑合能用,要是真遇到不规整的,回头再写个自然排序函数,不耽误正事儿。
并发读取视频时长
读取视频时长,咱不能一个个来,太慢,用ffprobe命令行工具(Go标准库没有直接读视频的),然后goroutine并发执行:
func (vp *VideoProcessor) getDurationsConcurrently() {
var wg sync.WaitGroup
for i := range vp.videos {
wg.Add(1)
go func(idx int) {
defer wg.Done()
dur := getFFprobeDuration(vp.videos[idx].FileName)
vp.mu.Lock()
vp.videos[idx].Duration = dur
vp.mu.Unlock()
}(i)
}
wg.Wait()
}
func getFFprobeDuration(filePath string) float64 {
// 这里假装调了ffprobe,实际代码略长
// 主要就是用exec.Command执行命令,解析输出
return 157.5 // 写死个示例时长,谁让咱这是示例呢
}
并行处理的时候一定得加锁,不然数据写重叠了,那视频列表就乱套了,这个在Go里面是常识,但新手特容易踩坑。
生成HTML播放列表文件
搞了半天,最后得给用户一个能看的界面,咱直接用Go生成一个静态HTML页面,把365首视频的标题、时长、标签都列出来,表格,对,就用表格,一目了然。
func (vp *VideoProcessor) generatePlaylistHTML() string {
html := `<h1>东北二人转365首经典视频</h1>`
html += `<table border="1" cellpadding="6" style="border-collapse:collapse;">`
html += `<tr><th>序号</th><th>曲目名称</th><th>时长(秒)</th><th>标签</th></tr>`
for _, v := range vp.videos {
html += fmt.Sprintf("<tr><td>%d</td><td>%s</td><td>%.1f</td><td>%s</td></tr>",
v.Index, v.Title, v.Duration, strings.Join(v.Tags, ", "))
}
html += "</table>"
return html
}
这代码看着土,但就是实用,你想想,剧团里的大爷大妈,打开这个HTML文件,浏览器里一翻,所有视频信息清清楚楚,比手抄本强多了。
实际跑起来的坑
-
坑一:文件名乱码,有些视频文件是从老光盘里拷出来的,文件名是GBK编码,Go默认按UTF-8处理,就会出现“�”这种符号,解决办法:用
golang.org/x/text/encoding/simplifiedchinese转码,这个包不是标准库的,得go get一下,但不亏。 -
坑二:视频文件太大,有个别视频可能2-3个GB,你不能读整个文件去判断时长,用
ffprobe只读头部信息,不读全量数据,快得很。 -
坑三:并发数开太大,电脑配置一般的话,goroutine开几百个同时跑ffprobe,CPU风扇直接起飞,得用
chan做个简单的信号量限制并发,比如最多同时跑8个。
365首”这个数字的碎碎念
说实话,我数过那文件夹,其实只有363个文件,少了俩,老板说“365首”是为了图个吉利,天天放一首,一年不重样,但咱代码不能编瞎话,实际扫描到几个就是几个,你就用len(vp.videos)输出真实数量,别硬凑,用户要是问起来,你就说“有两首正在棚里重新录制,回头补上”。
写Go代码时候的生活哲学
写这个工具的时候,我一直在想,这跟二人转的表演也挺像。台上十分钟,台下十年功,写代码也一样,看着简单,但边界情况得处理干净,你得防着文件夹里混进几个.txt文件,得防着视频文件名里有空格,得防着用户把目录路径搞错,这些if判断,就像二人转演员的“现挂”,得随时顶上。
最终文件长啥样
跑完程序,目录下会生成:
- manifest.json —— 所有视频的结构化数据,方便以后二次开发
- playlist.html —— 给非技术人员看的播放索引
- config.ini —— 用户自己可以改配置,比如默认并发数、是否生成缩略图等
我习惯把配置放在一个简单的ini文件里,用gopkg.in/ini.v1这个库去读,但咱这篇用的是纯标准库,那就自己写个简单的解析函数,也没几行。
结尾不总结了,就唠叨一句
其实搞这些东西,真不是为了炫技,就是觉得,咱东北的老玩意儿,也得跟上时代,你说那《小拜年》《回杯记》《西厢观画》,都是好东西,我用Go写个工具,把视频整理得明明白白,回头再做个手机端访问的简单页面,那老人儿在炕头上一划拉手机就能点播,多带劲。
工具写完了,我还真跟着视频听了好几段二人转,别说,那唱腔配上现代编程逻辑,居然挺搭的,行了,代码还有地方能优化,但饭得一口口吃,活儿得一项项干,先这样,下班去撸串了。
本文来自作者[kyadmin]投稿,不代表be365立场,如若转载,请注明出处:http://hljbesthome.com/jiankang/2265.html
评论列表(4条)
我是be365的签约作者“kyadmin”!
希望本篇文章《用Golang折腾东北二人转365首视频那点事儿》能对你有所帮助!
本站[be365]内容主要涵盖:be365,be365网站,be365网址,ball365体育,Be365排名
本文概览:开头先唠两句哎,说起来你可能不信,我最近接了个活儿——用Go语言写个工具,专门处理东北二人转365首视频的元数据整理,就是那种“正月...