用Golang扒下365dni游轮那一段插曲视频,一个普通程序员的折腾手记

那段视频到底藏在哪?前两天刷手机又刷到《365天:今时之欲》的游轮片段,弹幕里一堆人问“背景音乐叫啥”“这段拍摄地在哪”,我寻思着,...

那段视频到底藏在哪?

前两天刷手机又刷到《365天:今时之欲》的游轮片段,弹幕里一堆人问“背景音乐叫啥”“这段拍摄地在哪”,我寻思着,与其在评论区当复读机,不如自己写个小工具把那段视频扒下来分析分析,说干就干,打开电脑,Golang的logo在那儿冲我眨眼——得,就用它了。

为什么非要用Golang?Python它不香吗?

说实话,我平时写Python更多,但这次选Golang有三个实打实的原因:

用Golang扒下365dni游轮那一段插曲视频,一个普通程序员的折腾手记

  1. 编译成单个可执行文件——扔到服务器上就跑,不用管依赖环境
  2. 并发是亲儿子——抓取多个分片视频时,goroutine甩开Python的线程几条街
  3. 标准库够硬——net/httpio这些包处理流媒体下载,比Python的requests+urllib组合拳省心

你要是问我Python行不行?当然行,但咱今天聊的是Golang,对吧?

第一步:找到视频的真实地址(这步最坑)

游轮那段视频在流媒体平台上,直接<video>标签里的src是个blob:协议,压根没法直接下载,得用浏览器开发者工具翻Network面板,找.m3u8文件。

这里我踩了个坑——跨域请求的Referer和User-Agent必须伪装成浏览器,不然服务器直接甩个403,代码长这样:

client := &http.Client{
    CheckRedirect: func(req *http.Request, via []*http.Request) error {
        req.Header.Set("Referer", "https://www.example.com/")
        req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
        return nil
    },
}

第二步:解析m3u8文件——Golang的strings.Split够用了

.m3u8文件本质就是个文本清单,记录了视频分片的URL,用bufio.Scanner逐行读,遇到不以开头的行就是分片地址:

scanner := bufio.NewScanner(resp.Body)
var segments []string
for scanner.Scan() {
    line := strings.TrimSpace(scanner.Text())
    if line != "" && !strings.HasPrefix(line, "#") {
        segments = append(segments, line)
    }
}

有的m3u8里分片地址是相对路径,得用url.Parse拼上base URL,不然下载一堆404,这步我一开始没注意,白白浪费了5分钟调试。

第三步:并发下载分片——goroutine+WaitGroup

游轮那段视频有300多个分片,每个几百KB,串行下载得等半天,用并发瞬间就能拉完:

var wg sync.WaitGroup
segChan := make(chan string, 10) // 缓冲通道控制并发数
for i := 0; i < 8; i++ { // 8个worker
    wg.Add(1)
    go func() {
        defer wg.Done()
        for segURL := range segChan {
            // 下载逻辑,存为seg_001.ts类似的文件
        }
    }()
}
for _, seg := range segments {
    segChan <- seg
}
close(segChan)
wg.Wait()

注意:并发数别开太大,有的服务器有限流,开20个worker反而容易触发反爬,8个挺稳的。

第四步:合并分片——ffmpeg来收尾

下载下来的.ts分片得合并成完整的mp4,最省事的方式是调系统命令:

cmd := exec.Command("ffmpeg", "-f", "concat", "-safe", "0", "-i", "filelist.txt", "-c", "copy", "output.mp4")
cmd.Run()

前提是得提前生成一个filelist.txt,格式是file 'seg_001.ts',用Golang写这文件比手打快多了:

var files strings.Builder
for i := 0; i < len(segments); i++ {
    fmt.Fprintf(&files, "file 'seg_%03d.ts'\n", i)
}
os.WriteFile("filelist.txt", []byte(files.String()), 0644)

踩坑记录:这五个坑我帮你先踩了

现象 解决办法
分片文件名补零 100号分片排到2号前边 fmt.Sprintf("%03d", i)强制三位数
内存溢出 大文件一次性ReadAll卡死 io.Copy边读边写
加密m3u8 分片是加密的,合并后花屏 解析#EXT-X-KEY,用openssl解密
重试机制 网络抖动导致分片下载失败 加个简单的错误重试循环
磁盘空间不足 忘了清理临时ts文件 合并完用os.Remove清理

优化:如果你还想玩点花的

拿到视频后,我突然想知道游轮那段插曲到底用了哪个镜头角度,顺手用github.com/u2takey/ffmpeg-go这个库做了关键帧提取,每隔10秒抓一帧,直接拼成九宫格,效果还挺惊艳。

代码就不全贴了,核心就是:

err := ffmpeg.Input("output.mp4").
    Output("frame_%02d.png", ffmpeg.KwArgs{"vf": "fps=1/10"}).
    OverWriteOutput().
    ErrorToStdOut().
    Run()

最后的多嘴一句

折腾完这段视频,我突然觉得Golang特别适合这种“小工具型”任务——写起来不像Java那么啰嗦,跑起来又比Python靠谱,你要是也想扒点东西,建议先从这下边几个地方入手:

  • go-rod:用代码控制浏览器,自动抓取m3u8链接
  • go-m3u8:专门的解析库,不用自己手写逻辑
  • aria2(RPC调用):下载速度比自带http包快好几倍

好了,我得去给视频配字幕了,下次见,如果还有什么想看的视频不知道怎么搞,留言告诉我,咱们接着折腾。

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

(1)

文章推荐

发表回复

本站作者才能评论

评论列表(4条)

  • kyadmin
    kyadmin 2026-08-25

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

  • kyadmin
    kyadmin 2026-08-25

    希望本篇文章《用Golang扒下365dni游轮那一段插曲视频,一个普通程序员的折腾手记》能对你有所帮助!

  • kyadmin
    kyadmin 2026-08-25

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

  • kyadmin
    kyadmin 2026-08-25

    本文概览:那段视频到底藏在哪?前两天刷手机又刷到《365天:今时之欲》的游轮片段,弹幕里一堆人问“背景音乐叫啥”“这段拍摄地在哪”,我寻思着,...

    联系我们

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

    关注我们