Python 实战:用 DLNA 协议捕获微信视频号直播流地址
背景
最近想录制一些微信视频号的直播内容做存档,但发现这事儿比想象的麻烦 —— 视频号不像 B 站、抖音那样有成熟的第三方工具链,直播流的获取一直是个老大难。
网上搜了一圈,常见的方案基本就这几种:
- 抓包 + 代理:Fiddler / Charles 挂代理,手机装证书,然后抓 HTTPS 流量。能用,但配置折腾,而且微信对证书钉扎越来越严格
- 逆向客户端:Hook 微信进程拿内存里的 URL。风险高,版本一更新就挂
- 模拟器方案:在安卓模拟器里跑微信,用 root 权限抓。环境搭建成本太高
这些方案要么太重,要么太脆弱。我就想,有没有什么 不需要动微信客户端 的办法?
换个思路:从投屏入手
想了想,微信投屏到电视用的是标准 DLNA 协议。电视能收到直播流地址,那如果我的电脑 假装自己是一台电视 呢?
DLNA 的工作流程很简单:
1. 设备通过 SSDP(组播)在局域网宣告自己是 MediaRenderer
2. 微信发现设备后,发送 SOAP 请求把流地址 POST 过来
3. 设备播放 — 但我们只要地址,不需要真的播
关键在于:微信根本无法区分真电视和假电视。因为这就是标准协议,不存在什么「检测」的可能。
实现
整个工具我用纯 Python 标准库实现了,零外部依赖,核心就 500 多行代码。
架构上分了几个模块:
- ssdp.py — SSDP 组播广播,让微信能在投屏列表里发现我们
- upnp.py — HTTP 服务,处理设备描述请求和 SOAP 控制请求
- descriptors.py — UPnP XML 模板,模拟 MediaRenderer 设备描述
- net.py — 局域网 IP 检测
核心捕获逻辑很短:
from wechat_finder_dlna import capture
url = capture(name="我的录制器")
print(f"直播流地址: {url}")
# 拿到 m3u8 地址后,想怎么用都行
命令行也很简单:
# 只拿地址
wechat-finder-dlna
# 直接录制
wechat-finder-dlna --record live.mp4 --duration 01:00:00
# 丢给 VLC 播放
wechat-finder-dlna | xargs vlc
为什么不用第三方库?
一开始考虑过用现有的 DLNA 库,但看了一圈发现都太重了 —— 完整的 DLNA 实现要处理媒体播放、传输控制、事件订阅一大堆东西。我的需求很单一:只要能接收到投屏 URL 就够了。
所以干脆自己用标准库撸了一个最小实现,只实现 SSDP 发现和 AVTransport 的 SetAVTransportURI 动作。整个项目零依赖,pip install 之后直接用,不需要编译任何东西。
实际效果
$ wechat-finder-dlna
📺 "wechat-finder-dlna" ready on 192.168.1.100:9090
Open WeChat > live/video > cast > select "wechat-finder-dlna"
Captured: http://pull-l1.wxlivecdn.com/...m3u8?...
手机和电脑在同一个 WiFi 下,打开视频号直播,点投屏,选我们的设备,URL 就到手了。整个过程不到 10 秒。
拿到 m3u8 之后可以用 ffmpeg 录制、用 VLC 播放、或者写脚本批量处理 —— 想怎么折腾都行。
其他投屏类 App 也能用
虽然项目名字带 wechat,但实际上任何支持 DLNA 投屏的 App 都能用:B 站、爱奇艺、优酷、腾讯视频 —— 因为底层都是同一套 DLNA 协议。
安装
# 推荐 uv
uv tool install wechat-finder-dlna
# 或者 pip
pip install wechat-finder-dlna
Python 3.10+,零依赖。录制功能需要系统装 ffmpeg。
欢迎提 Issue 和 PR,有问题随时交流。