# projection **Repository Path**: ylwu/projection ## Basic Information - **Project Name**: projection - **Description**: 一个面向 VIDAA、HappyCast/乐播及其他 DLNA/UPnP MediaRenderer 的 Windows 桌面投屏工具。启动后自动搜索局域网设备,并把设备连接、媒体兼容性、字幕处理和播放记忆整合到同一条使用链路中。 - **Primary Language**: Python - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 7 - **Forks**: 3 - **Created**: 2026-07-12 - **Last Updated**: 2026-07-23 ## Categories & Tags **Categories**: application-software **Tags**: None ## README # 随享投屏 简体中文 | [English](./README_EN.md) 一个面向 VIDAA、HappyCast/乐播及其他 DLNA/UPnP MediaRenderer 的 Windows 桌面投屏工具。启动后自动搜索局域网设备,并把设备连接、媒体兼容性、字幕处理和播放记忆整合到同一条使用链路中。 ## 当前能力 - 自动发现同一局域网内的 DLNA 电视,兼容电脑同时开启 WLAN、VPN 和虚拟网卡的情况。 - 自动读取电视名称、动态端口和实际控制地址;发现失败时可只填写电视 IP 扫描常见端口。 - 选择本地视频、外部字幕、音轨和内嵌字幕。 - 投屏前根据容器、视频/音频编码、分辨率和字幕形式提示兼容性风险,并记录某台电视的真实播放反馈。 - 直接投原文件,或无损生成只含所选音轨/字幕且设置为默认的 MKV 兼容副本。 - 在独立任务页制作硬字幕兼容版,显示进度和预计剩余时间,支持排队、取消及硬件编码失败后回退软件编码。 - 暂停、继续、停止、时间跳转、进度拖动、音量调节和播放状态查询。 - 播放期间自动记录电视进度,再次选择同一文件时可从上次位置继续;文件移动或重命名后仍可通过内容指纹识别。 - 文件投屏期间主动保持 Windows 和网络工作,显示器可以正常熄灭,不会因 Modern Standby 暂停本地媒体服务。 - 本地媒体服务支持 HTTP Range,电视可按需读取大文件和拖动进度。 - 支持本地 M3U8 清单,可直接加载,也可在后台快速合并成 MP4 后投屏或保存。 - 提供“网址投屏”,解析公开 MP4 和非 DRM HLS,按清晰度选择后通过电脑安全中转给电视。 - 提供独立“电脑投屏”入口,通过 Windows 无线显示镜像整个桌面和系统声音。 - 提供最近播放、常用目录、输出清理、运行日志和一键复制诊断报告。 ## 普通用户下载 发行版已经内置 Python、FFmpeg、FFprobe 和 yt-dlp,不需要另外安装运行环境: - 推荐下载 `ProjectionTool-v0.4.5-Windows-x64.zip`,解压后运行 `ProjectionTool.exe`;启动更快,适合长期使用。 - 也可以直接下载 `ProjectionTool-v0.4.5-Windows-x64.exe`;它是单文件版本,无需解压,但每次启动需要先释放运行组件。 - 两个下载文件均控制在 100 MB 以下,便于直接上传到常见代码托管平台的 Release。 - Windows 可能因为发行版尚未购买代码签名证书而显示“未知发布者”,请确认下载来源和 Release 中的 SHA-256 后再运行。 M3U8 合并文件、兼容副本和硬字幕视频默认输出到当前用户的 `Videos\随享投屏输出` 目录。 ## 从源码启动 双击 [启动投屏工具.bat](./启动投屏工具.bat),或把视频文件拖到这个批处理文件上直接打开。也可以在 PowerShell 中运行: ```powershell git clone <仓库地址> cd projection python -m pip install -r requirements.txt python app.py # 直接打开指定视频 python app.py "<视频文件路径>" ``` 源码模式需要 Python 3.10 或更高版本。网页解析需要 `requirements.txt` 中固定版本的 yt-dlp;直接投本地文件或直接加载 M3U8 不要求 FFmpeg,M3U8 合并、媒体分析、兼容副本和硬字幕任务需要 FFmpeg。程序依次查找项目内置目录、`PATH` 和常见 WinGet 安装目录。 ## 推荐使用流程 1. 等待启动时自动发现电视,并在设备下拉框中选中它。 2. 如果没有发现设备,展开“手动连接”,填写电视 IP 后扫描;通常不需要自己猜端口。 3. 选择视频,等待音轨、字幕和兼容性信息加载。 4. 兼容性为低风险时优先“直接投屏”;需要调整默认音轨或软字幕时选择“生成兼容副本并投屏”。 5. 如果电视不显示软字幕,在“字幕任务”中制作硬字幕版;任务在后台运行,可以取消。 6. 再次播放同一视频时,按提示从上次位置继续。 7. 最近播放、常用目录、清理输出和诊断报告位于“记录与工具”。 兼容副本和硬字幕视频不会修改原文件。 ## 投本地 M3U8 选择 `.m3u8` 后,工具会先递归检查主清单、子清单、媒体分片、初始化片段和本地密钥是否齐全。清单中的文件应位于主清单所在目录或其子目录;为避免读取意外文件,本地清单不接受网络地址和越出该目录的路径。 - **直接加载 M3U8**:立即投屏,不生成新文件;速度最快,但最终播放能力取决于电视是否支持 HLS 以及清单内的音视频编码。 - **合并为 MP4 并投屏**:在后台生成 MP4,完成后自动投屏。H.264/AAC 通常只重新封装,不压制画面;如果编码不兼容,才自动转换为 H.264/AAC。 - **仅保存 MP4**:执行相同的后台处理,但完成后不占用电视,适合先准备好文件再投屏。 合并或转码不会修改原 M3U8 和分片。请保留所有分片文件到任务完成;如果清单引用的是在线分片,应使用“网址投屏”,而不是本地 M3U8 入口。 ## 投网页视频 “网址投屏”不依赖 AI、大模型或云端推理服务。它在用户电脑上使用固定解析规则:先调用内置 yt-dlp 站点解析器,再检查网页公开提供的 `video/source` 标签、Open Graph 媒体信息、脚本中的 MP4/M3U8 地址和一层内嵌播放器。电脑随后充当安全中转,电视不会直接接触上游 Cookie、Referer 或带签名的真实媒体地址。 1. 选择一台已经发现的 DLNA 电视。 2. 点击“粘贴并解析”,或者输入网址后按 Enter;不需要填写视频直链或配置解析规则。 3. 先查看结果表上方的当前状态,再在表格第一列查看“推荐 / 兼容 / HLS / 需电视支持”。工具会自动选择推荐流。 4. 点击“投屏所选清晰度”。软件保持运行并实时代理媒体请求。 能否直接读到视频地址取决于网站怎样实现播放器。公开写在页面、播放器配置或 yt-dlp 已支持站点中的 MP4/HLS 通常可以直接识别;由浏览器运行复杂 JavaScript 后临时生成的 `blob:` 地址、强登录 Cookie、验证码、付费墙、Widevine/PlayReady DRM,以及只有分离式 DASH 音视频流的页面不能直接读取或不会绕过。失败状态会明确显示原因,并提供重新解析、修改网址或复制错误详情。部分临时地址过期后需要重新解析;HLS 最终能否播放仍取决于电视自身解码能力。 ## 投整个电脑 “电脑投屏”使用 Windows 自带的无线显示能力,把整个桌面和系统声音交给 Windows 传输: 1. 在电视或投屏器上打开“无线显示”“Miracast”或“屏幕镜像”接收功能。 2. 打开工具的“电脑投屏”页,确认本机能力检查通过。 3. 点击“打开无线显示设备列表”,在 Windows 的 Win+K 面板中选择电视。 4. 连接后可按 Win+P 选择复制或扩展桌面。 电脑镜像与 DLNA 视频投屏是两条独立链路。电视只开启乐播 DLNA 接收并不代表支持 Miracast;如果 Win+K 列表里没有电视,需要电视同时开启无线显示接收,或使用乐播官方电脑端。当前版本没有发布 FFmpeg 转码的 DLNA 桌面直播:这条方案无法在不同电脑上可靠获取系统声音,并且必须经过具体电视真机验收后才能保证兼容性。 ## 字幕说明 DLNA 协议没有统一规定电视必须显示 MKV 内嵌字幕、MP4 软字幕或外部 SRT。工具可以把字幕设为默认、把外部字幕随媒体地址一起声明,但最终是否显示仍由电视播放器决定。 “生成兼容副本”采用无损封装,速度快,但不能解决电视完全忽略软字幕的问题。“硬字幕兼容版”会重新编码整个画面,因此耗时与视频时长、分辨率和显卡编码能力直接相关。 ## 端口检测如何工作 正常路径是 SSDP 自动发现,电视会主动返回自己的描述地址和端口。手动扫描是兜底方案,会检测: - 常见设备端口:`80`、`3000`、`5000`、`7000`、`8000`、`8008`、`8060`、`8080`、`8888`。 - VIDAA/HappyCast 常见动态端口范围:默认 `49152-49200`,可在界面修改。 - 开放端口上的常见 UPnP 描述文件,并从描述文件读取真实控制地址。 不要把范围设置成 `1-65535`。局域网电视检测没有必要做全端口扫描,耗时长,也容易被防火墙拦截。 ## 故障排查 - 电脑与电视必须连接同一个家庭局域网,访客 Wi-Fi 的设备隔离会阻止发现和播放。 - 先在电视上打开“投屏”“无线显示”或可接收投屏的应用,使 DLNA 服务处于运行状态。 - Windows 防火墙提示时,允许 Python 在“专用网络”通信;电视需要访问电脑临时开启的本地媒体端口。 - 开着 VPN 时仍应能搜索 WLAN,但部分 VPN 的“阻止局域网访问”选项必须关闭。 - 自动发现失败时,可在电视网络设置中查看当前 IP,再使用“扫描此 IP”。 - “记录与工具”可一键复制诊断报告;日志位于 `%LOCALAPPDATA%\ProjectionTool\logs\projection.log`。 ## 项目结构 ```text projection/ ├── app.py # 程序入口与日志配置 ├── projection/ │ ├── compatibility.py # 设备兼容档案和风险预检 │ ├── config.py # 配置持久化 │ ├── diagnostics.py # 网络与防火墙诊断报告 │ ├── discovery.py # SSDP 发现和端口检测 │ ├── dlna.py # UPnP/DLNA 控制 │ ├── local_hls.py # 本地 M3U8 检查、路径约束和清单重写 │ ├── media.py # FFprobe 分析、无损封装和硬字幕转码 │ ├── media_server.py # 本地文件与网页视频/HLS 安全代理 │ ├── power.py # 投屏期间的 Windows 系统保活 │ ├── state.py # 文件指纹、播放记忆和时间处理 │ ├── tasks.py # 可取消的后台任务队列 │ ├── ui.py # Tk 桌面界面 │ ├── web_video.py # 网页视频解析、格式模型和 URL 安全检查 │ └── wireless_display.py # Windows 无线显示能力检测与入口 └── tests/ # 标准库 unittest 测试 ``` 运行测试: ```powershell python -m unittest discover -s tests -v ``` 当前 40 项测试覆盖设备描述解析、DLNA SOAP、本地及远程 HTTP Range、本地 M3U8 检查与服务、网页视频格式解析、错误恢复、SSRF 防护、多级 HLS 重写、播放指纹与续播存储、兼容性反馈、诊断报告脱敏、仓库隐私检查、Windows 投屏保活、无线显示检测和后台任务队列。 构建 Windows 发行版: ```powershell .\构建发行版.bat ``` 构建脚本会安装 `requirements-build.txt` 中的构建工具,下载并校验固定版本的 FFmpeg,运行测试,然后生成单文件 EXE、便携版 ZIP 和 `SHA256SUMS.txt`。构建缓存、FFmpeg 二进制和发行产物不会提交到 Git。 ## 安全与边界 媒体服务只在程序运行期间启动,使用随机地址标识文件或远程资源,不提供目录浏览。它监听本机所有网络接口是为了让电视能访问,因此只应在可信家庭网络使用。关闭程序后媒体服务会停止。 网址解析只接受 HTTP/HTTPS,拒绝带账号密码的地址,并在初始请求、重定向及 HLS 子资源阶段阻止本机、内网和保留地址。网页请求头只保留媒体访问所需字段且不会写入界面日志。此功能仅用于用户有权访问的内容,不提供 DRM、付费墙或访问控制绕过。