[Python/Rust] 基于 "投屏" 的视频抓包

查看 54|回复 8
作者:三滑稽甲苯   
 前言
众所周知,众多流媒体平台不再提供网页端的服务,只能在 APP 内看视频,而这就在一定程度上妨碍了我们抓包、获取网址、下载视频的工作流。为了让用户能够在智能电视上看视频,这些平台又往往会提供一个投屏到电视的选项。
虽然大家都约定俗成地说是“投屏”,但实际上这个称呼是有歧义的,既可以指“将屏幕镜像到另一个设备”,也可以指“将某媒体流投送到另一个设备”。前者需要在局域网内实时传输画面,而后者往往只需要将一个网址传输给目标设备。这里我们仅针对第二种情况展开讨论。
犯 Windows Media Player
既然电视上能够播放投屏的媒体流,那么理论上我们可以用电脑模拟成一个电视,让电脑接收媒体流的网址。如果我们能够得到这个网址,那么下载媒体也就不在话下了。经过一番搜索,我发现 Windows Media Player 可以接受媒体流推送,那么让我们尝试利用它来获取媒体流网址。
启用媒体流
首先打开控制面板,进入“网络共享中心”,点击左侧栏的“媒体流式处理选项”:


control_media_stream.jpg (116.95 KB, 下载次数: 0)
下载附件
媒体流式处理选项
2025-6-13 21:36 上传

然后单击“启用媒体流”按钮:


control_enable_media_stream.png (62.8 KB, 下载次数: 0)
下载附件
启用媒体流
2025-6-13 21:36 上传

若出现下图所示“媒体流未启用”的提示:


control_media_stream_disabled.png (52.92 KB, 下载次数: 0)
下载附件
媒体流未启用
2025-6-13 21:36 上传

那么点击下方的“Windows 服务管理工具”,然后找到“Windows Media Player Network Sharing Service”服务:


service_wmp.png (129.27 KB, 下载次数: 0)
下载附件
“Windows Media Player Network Sharing Service”服务
2025-6-13 21:38 上传

右键,选择“属性”,将其启动类型设置为“自动”或者“自动(延迟启动)”,点击“应用”后再次点击“启动”:


service_wmp_prop.png (90.09 KB, 下载次数: 0)
下载附件
“Windows Media Player Network Sharing Service”服务属性设置
2025-6-13 21:38 上传

若提示下述信息:
Windows 无法启用 Windows Media Player Network Sharing Service 服务 (位于 本地计算机 上)
错误 1068: 依赖服务或组无法启动。
则先用同样方法启动“依存关系”中的五个服务 (ref):


service_dependencies.png (73.59 KB, 下载次数: 0)
下载附件
依存关系
2025-6-13 21:38 上传

  • Windows Search
  • Background Tasks Infrastructure Service
  • Remote Procedure Call (RPC)
  • DCOM Server Process Launcher
  • RPC Endpoint Mapper

    启动成功后即可关闭“服务”窗口,然后 重新进入 控制面板的“媒体流选项”。
    随后,在所有网络中允许访问共享媒体:


    control_allow_accessing_media.png (85.51 KB, 下载次数: 0)
    下载附件
    允许访问共享媒体
    2025-6-13 21:36 上传

    完成上述步骤后即可关闭控制面板。
    允许远程控制我的播放器
    打开 Windows Media Player (找不到可以搜索) 软件,在“媒体流”选项中勾选“允许远程控制我的播放器”:


    wmp_legacy_allow_remote_control.png (69.17 KB, 下载次数: 0)
    下载附件
    允许远程控制我的播放器
    2025-6-13 21:39 上传

    注意,这一步之后不能关闭 Windows Media Player,否则会导致后续找不到设备。
    开始投屏
    将手机或其他设备连接到同一局域网,打开一个支持 DLNA 的 APP (如哔哩哔哩),并打开任意视频 (例如 BV1GJ411x7h7),在播放界面点击投屏按钮,选择你的电脑:


    bilibili_screencast.jpg (254.41 KB, 下载次数: 0)
    下载附件
    哔哩哔哩投屏
    2025-6-13 21:41 上传

    如果一切正常,Windows Media Player 就会开始播放此视频:


    wmp_legacy_playing.png (684.33 KB, 下载次数: 0)
    下载附件
    Windows Media Player 播放
    2025-6-13 21:39 上传

    查看网址
    右键画面,点击“显示播放列表”:


    wmp_legacy_show_playlist.png (443.43 KB, 下载次数: 0)
    下载附件
    显示播放列表
    2025-6-13 21:39 上传

    随后在播放列表中找到刚才投屏的视频,右键点击,选择“属性”:


    wmp_legacy_playlist_properties.png (563.3 KB, 下载次数: 0)
    下载附件
    播放列表属性
    2025-6-13 21:39 上传

    在弹出的属性窗口中的“文件”选项卡中即可看到视频的 URL,使用鼠标从头到尾选中后即可复制:


    wmp_legacy_playlist_url.png (61.72 KB, 下载次数: 0)
    下载附件
    播放列表属性 URL
    2025-6-13 21:39 上传

    随后可以将此 URL 粘贴到浏览器或下载工具中进行下载。
    DLNA
    显然,上面的方法还是太吃操作了,那么有没有更自动化的方式呢?答案是有的,但需要编写一个程序扮演 DLNA DMR (Digital Media Renderer) 的角色,自动接收媒体流并提取 URL。首先,我们简单介绍一下 DLNA 协议:

    Digital Living Network Alliance (DLNA) is a set of interoperability standards for sharing home digital media among multimedia devices.

    这个标准主要包括下面五个角色:
  • Digital Media Server (DMS): 数位媒体伺服器,存储并提供媒体文件。
  • Digital Media Renderer (DMR): 数位媒体渲染器,可接收并播放从 DMC 推送过来的媒体档案。(接收并执行 DMC 发送的指令)
  • Digital Media Controller (DMC): 数位媒体控制器,作为遥控装置使用,可寻找 DMS 上的多媒体档案,并指定可播放该多媒体档案的 DMR 进行播放或是控制多媒体档案上下传到 DMS 的装置。
  • Digital Media Player (DMP): 数位媒体播放器,寻找并播放或输出 DMS 所提供的媒体文件。(DMP≈DMR+DMC)
  • Digital Media Printer (DMPr): 数位媒体印表机,可以在 DLNA 网路架构下提供列印功能。

    在使用哔哩哔哩软件投屏至电视的场景下,哔哩哔哩公司的服务器就是 DMS,手机上的哔哩哔哩软件即为 DMC,而智能电视就是 DMR。因此,为了达成“DLNA 捕获”的目的,我们需要解决两个关键问题:
    [ol]
  • 告知 DMC:“我是 DMR,我可以接受媒体流然后渲染”
  • 接收发给自己的控制指令,然后输出指令的内容,从而获得网址
  • 由于我们做的是假 DMR (dummy DMR),因此不需要实现指令的执行

    [/ol]
    DMR 实际上由两个服务器构成:一个是 SSDP 服务器,负责通过 SSDP 协议 控制设备的发现、更改与离开;一个是 HTTP 服务器,负责托管各种描述文件,以及指令的接收和结果的返回。
    SSDP
    Simple Service Discovery Protocol (SSDP) 是基于文本的协议。除了它使用 UDP 外,其它方面,例如报文结构,和 HTTP 不能说十分相似,只能说一模一样。例如,一个经典的广播消息可以长这样:
    NOTIFY * HTTP/1.1
    Host: 239.255.255.250:1900
    NT: upnp:rootdevice
    NTS: ssdp:alive
    Location: http://192.168.14.122:2869/upnphost/udhisapi.dll?content=uuid:04f976f9-14d8-4205-a6c4-950dad87c430
    USN: uuid:04f976f9-14d8-4205-a6c4-950dad87c430::upnp:rootdevice
    Cache-Control: max-age=1800
    Server: Microsoft-Windows/10.0 UPnP/1.0 UPnP-Device-Host/1.0
    通过 SSDP 告知自己是 DMC 主要有两种途径:
    [table]
    [tr]
    [td]途径[/td]
    [td]HTTP Method (?)[/td]
    [td]主/被动[/td]
    [td]备注[/td]
    [/tr]
    [tr]
    [td]广播

    媒体, 下载次数

  • xixicoco   

    其实主要讲的还是投屏,支持
    crystalZ   

    很详细的技术分享
    yibaoshutiao   

    思路不错,但是好像有优酷这种会员只能手机上看的不给投屏
    senooo   

    学习了,很强大,大佬讲解的很细致。而且python和rust都非常棒
    m_h   

    好复杂,牛!
    popdes   

    有用的知识又增加了
    daoye9988   

    学习了,非常详细教程
    三滑稽甲苯
    OP
      


    xixicoco 发表于 2025-6-13 22:14
    其实主要讲的还是投屏,支持

    写代码实际上没花多少时间,理解协议是最费时间的
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部