跳转到内容

Streamlink — 把直播页变成可播的流

待复核

Streamlink 是一个 Python 写的 CLI + 库:你丢给它一个直播页 URL,它负责「拆开网页、找到真正的媒体地址」,再把流 pipe 进 VLC / mpv,或写成文件。

日常类比:直播网站像一家装修华丽的餐厅——菜单、广告、登录墙全挤在一起。Streamlink 是后厨取餐口:不问装修,只把「正在出锅的那盘菜」(媒体流)递到你自己的盘子(本地播放器)里。

最小例子:

Terminal window
streamlink "https://www.twitch.tv/some_channel" best

默认会拉起本机播放器(常见是 VLC)直接看;你也可以改成落盘或开本地 HTTP 端口给别的程序读。

不理解 Streamlink,下面这些事都很难讲清:

  • 为什么很多人「浏览器卡成幻灯片,命令行却能流畅看直播」——重页面和轻量取流是两回事
  • 为什么录播脚本常写成 streamlink … -o out.ts,而不是先开浏览器再点录制
  • 它和 yt-dlp 看起来都「给 URL 出媒体」,但一个偏直播实时管道,一个偏点播归档下载
  • 2016 年 Livestreamer 停更后,社区为什么要 fork 出 Streamlink 才能继续跟站点改版
  1. 插件(plugin)按站点拆解:每个站点一个插件,负责登录态、API、HLS/DASH 清单等脏活。类比:不同快递柜要不同开箱 App,Streamlink 给每个柜配一把钥匙。

  2. 解析与播放解耦:Streamlink 只负责「拿到可播的流」,真正解码交给 VLC / mpv / ffmpeg。类比:它是水管工,不是电视机——接好管子就走。

  3. CLI 与 Python API 同一套内核:命令行是薄壳;你也可以在脚本里选流、开 reader。类比:同一台咖啡机,既有按钮面板,也有给咖啡师用的侧门接口。

from streamlink import Streamlink
session = Streamlink()
streams = session.streams("https://www.twitch.tv/some_channel")
fd = streams["best"].open() # 得到可读的流句柄,再自己 read / 转推
Terminal window
# 先看有哪些流(不写 STREAM 时会列出)
streamlink "https://www.twitch.tv/some_channel"
# 选最高画质;也可用 720p,480p,best 做回退链
streamlink "https://www.twitch.tv/some_channel" "720p,480p,best"

逐部分解释

  • 第一个参数是页面 URL,不是 .m3u8(插件会自己去找)
  • best / worst / 720p 是流名字;逗号列表表示「从前到后试,谁可用用谁」
  • 未指定 --player 时,走默认播放器配置

案例 2:录到文件(给后期 / 备份)

Section titled “案例 2:录到文件(给后期 / 备份)”
Terminal window
streamlink "https://www.twitch.tv/some_channel" best -o "vod-$(date +%F-%H%M).ts"

逐部分解释

  • -o 把 stdout 管道改成写文件;直播中断时文件可能不完整,这是流式写入的常态
  • 扩展名常用 .ts(HLS 片段拼接友好);若要 mp4,多半再交给 ffmpeg 转封装
  • 适合「人不用盯着网页点录制」的定时任务

案例 3:开本地 HTTP,给别的播放器拉

Section titled “案例 3:开本地 HTTP,给别的播放器拉”
Terminal window
streamlink "https://www.twitch.tv/some_channel" best --player-external-http --player-external-http-port 51880
# 另开终端:mpv http://127.0.0.1:51880/

逐部分解释

  • --player-external-http 让 Streamlink 当本机源流服务器,不替你起 GUI 播放器
  • 端口可固定,方便写进 mpv / OBS / 自研播放器配置
  • 适合「解析逻辑用 Streamlink,播放壳子自己做」的分工
  1. 站点改版 → 插件失效:直播站前端一改,插件就要跟;版本过旧时常见「No playable streams」。原因:解析规则绑在站点实现上,不是绑在「直播」抽象上。

  2. 登录墙 / 会员流:有的源要 cookie 或 OAuth。原因:Streamlink 拿不到浏览器里的登录态,就只能看到游客可见的流(或直接失败)。

  3. 和 yt-dlp 用错场景:用 Streamlink 硬下完整 VOD 归档、或用 yt-dlp 硬扛低延迟直播,都会别扭。原因:一个优化「持续 pipe」,一个优化「选格式 + 后处理落盘」。

  4. 默认播放器路径不对:Linux 最小容器里没 VLC 时,命令「成功解析却打不开窗」。原因:解析成功 ≠ 播放器存在;录文件或 --player-external-http 可绕开。另:best 只是「站点暴露的最高档」,不是无损保证。

适用

  • 想绕开沉重网页,用本机播放器看 Twitch / YouTube 等已有插件的直播
  • 脚本化录直播一段(几十分钟到数小时),或把流转给 mpv / OBS / 自研播放器
  • 需要在 Python 里复用同一套站点插件逻辑(监控、转推、自建 UI)
  • 机器上有播放器或 ffmpeg,但你不想在浏览器里挂一整晚标签页

不适用

  • 大规模点播库归档、字幕/封面/playlist 元数据——优先 yt-dlp
  • 站点无插件且你也不打算写插件——Streamlink 不会「通用猜流」
  • 需要浏览器里那种弹幕 / 推荐 / 打赏 UI——它只取媒体,不复刻网站
  • 对延迟有广播级要求(亚秒交互)——它是「能看/能录」工具,不是专业低延迟分发栈(那更像 ovenmediaengine / WebRTC 一侧)
  • Livestreamer 时代:更早的社区工具把「网页 → 播放器」这条链路做出来,让人第一次习惯「命令行看直播」。
  • 维护停滞:上游更新跟不上站点改版后,用户开始大面积遇到「昨天还能看、今天 No streams」。
  • 2016 fork → Streamlink:社区 fork 后把插件生态当成生命线,文档站 streamlink.github.io 长期维护 CLI 与插件列表。
  • 双形态固定下来:CLI 给普通人一键播放;Python API 给脚本党嵌进录制/转推流水线。
  • 和下载器分家:同一时期 yt-dlp(及前身 youtube-dl)把「点播下载」做到极致;Streamlink 守住「直播管道」——两者常被一起装,但职责不同。
  1. 「页面」和「流」要拆开想——用户看见的是 HTML,播放器要的是媒体地址;中间这层解析值得独立成工具。
  2. 插件边界 = 产品边界——支持哪些站,几乎完全取决于插件是否跟上;通用口号救不了具体 DOM/API 变更。
  3. 管道优于一体化——解析归 Streamlink,解码归播放器 / ffmpeg,比做一个巨型「又解析又渲染」的客户端更抗变。
  4. 同类工具按时间轴选型——直播实时看/录用 Streamlink,事后归档用 yt-dlp,转封装用 ffmpeg;先问「直播还是点播」,再选锤子。
  • yt-dlp —— 同属「URL → 媒体」,但偏点播归档而非直播管道
  • ffmpeg —— 录下来的 .ts 常交给它转 mp4 / 剪辑
  • gstreamer —— 更底层的多媒体管道框架;Streamlink 是应用层取流
  • video.js —— 浏览器里播 HLS/DASH;Streamlink 把流拿到浏览器外
  • mediasoup —— WebRTC SFU,做互动低延迟;和「从网站抽流到本地」场景不同
  • ovenmediaengine —— 自建低延迟直播服务端;和「从别人网站取流」方向相反
  • yt-dlp —— yt-dlp — 统一多站点下载器 CLI