一、这是什么
VDVD 影音是一款 Windows 桌面播放器(Win10 / Win11)。拿它当访客的播放端,你有两条路:
唤起式 vdvd:// | 桥接式 window.VDVDPlayer | |
|---|---|---|
| 访客在哪 | 自己平时的浏览器 | 在 VDVD 影音的内置浏览器里浏览你的站 |
| 站点怎么做 | 播放按钮的链接换成 vdvd://… | 页面里调一句 JS |
| 选集(剧集清单) | 协议只带一条地址,不支持选集 | 支持整套线路 / 集数 |
| 典型场景 | 第三方站推荐访客用本机播放器 | 站点本身就在播放器里被打开(如 MacCMS 站,零改动) |
两条路可以同时存在,互不冲突。
对访客的好处(两种方式一致):
- 走桌面播放器的硬解与网络栈,比浏览器里播更稳、更省电;
- 自动注入
Referer/User-Agent,防盗链源在浏览器里播不了、在这里能播; - 弹幕、播放进度记忆。
对你的好处:不换播放器、不改后端。播放地址还是你站自己给的地址。
二、唤起式接入:vdvd://
访客在自己浏览器里浏览你的站点,点一下播放按钮 → 本机 VDVD 影音弹出来播放。 你不需要访客先打开播放器,也不需要知道访客装没装(怎么兜底见 2.4)。
2.1 链接长什么样
vdvd://play?url=<媒体地址>&title=<片名>&referer=<本页地址>&back=<返回地址>
所有参数值都要 encodeURIComponent(空格必须编成 %20,播放器不把 + 当空格)。
2.2 最小示例
<a href="vdvd://play?url=https%3A%2F%2Fcdn.example.com%2Fa%2Findex.m3u8&title=%E7%89%87%E5%90%8D%20%E7%AC%AC1%E9%9B%86">用 VDVD 播放器播放</a>
用 JS 拼更省事:
function vdvdUrl(playUrl, title) { var q = 'url=' + encodeURIComponent(playUrl) + '&title=' + encodeURIComponent(title || document.title) + '&referer=' + encodeURIComponent(location.href) + '&back=' + encodeURIComponent(location.href); return 'vdvd://play?' + q; } document.querySelector('#play-btn').addEventListener('click', function () { location.href = vdvdUrl('https://cdn.example.com/a/index.m3u8', '片名 第 1 集'); });
2.3 参数
| 参数 | 必填 | 说明 |
|---|---|---|
url | ✅ | 媒体地址(m3u8 直链等),不是详情页地址。缺失时播放器只是被调出来,不播放。 |
title | 片名 / 集名。用于播放器窗口标题、进度记忆、弹幕匹配。为空时取该媒体地址。 | |
referer | 请求媒体时携带的 Referer。防盗链站点建议传本页地址(不传就只有 User-Agent)。 |
|
back | 顶栏「返回网站」要回到的地址。不传时用 referer;两个都没传,界面就不出现这个按钮。 |
2.4 访客没装播放器怎么办(必看)
通用做法是「先唤起、再兜底跳下载页」:
function launchVdvd(uri, downloadUrl) { var left = false; // 唤起成功的话浏览器会失焦(播放器抢到前台) window.addEventListener('blur', function () { left = true; }, { once: true }); var timer = setTimeout(function () { if (!left && !document.hidden) { location.href = downloadUrl; // 没唤起成功 → 当作未安装,去下载页 } }, 1500); location.href = uri; }
- 这只是经验判断(失焦 ≈ 唤起成功),不是精确探测。弹窗确认框会占用这段时间,所以延迟别设太短;
- 下载页建议带上说明,告诉访客装完再回来点一次。
2.5 播放器收到唤起后做什么
- 已经开着播放器 → 把这次播放转交给那一个窗口(不会多开一个),并把它还原到前台;
- 没开着 → 启动播放器,直接进播放界面;
- 登记为当前播放源,补上
Referer/User-Agent; - 有
back就显示「返回网站」,点击回到你给的那个地址。
2.6 其他用法
vdvd://open—— 只把播放器调出来(不播放)。适合「打开我的播放器」这类入口;play后面漏了url时,等同于open,不会报错。
如果你想知道访客是否在播放器内(而不是唤起),用第三节的 isEmbedded。
三、桥接式接入:window.VDVDPlayer
访客在 VDVD 影音内置浏览器里浏览你的站点时(例如从导航站跳进来),
播放器会向页面注入全局对象 window.VDVDPlayer。站点可以用它把播放交给本机播放器。
3.1 方式 A:MacCMS 站点 —— 什么都不用做
播放页存在全局 window.VOD 的站点(MacCMS 一类),只要访客在播放器里打开播放页,
播放器会自动接管:取第一条线路第一集开播,并把全部线路 / 集数搬进「选集」面板。
自动接管需要同时满足:
| 条件 | 说明 |
|---|---|
| 页面在播放器内打开 | 页面里存在 window.chrome.webview |
| 不是播放器自己的界面 | 排除 *.local 与 qvqweb.0871pc.com |
地址不带 #__vdvd=back | 播放器「返回网站」时打的一次性标记,读到就不再接管(防死循环) |
| 路径是详情页 / 播放页 | 命中 /vod/数字.html、/detail/数字.html、/play/、/vodplay/、/index.php/vod/(不分大小写)。首页、列表页、搜索页不会被接管 |
| 页面有可播集 | window.VOD.lines[].episodes[].u |
时间点:等 document.readyState === 'complete' 后开始尝试(每 500ms 检查一次,最多 30 秒),
避开站点的二次跳转与异步渲染。
3.2 方式 B:显式调用(任何站点)
<script> document.querySelector('#play-btn').addEventListener('click', function () { // 不在播放器内(比如普通浏览器)→ 什么都不做,走你自己的播放器 / 唤起式链接 if (!window.VDVDPlayer || !window.VDVDPlayer.isEmbedded) return; window.VDVDPlayer.play('https://cdn.example.com/vod/a/index.m3u8', '片名 第 1 集'); }); </script>
四、接口一览
window.VDVDPlayer = {
version: '1.1', // string,接口版本
isEmbedded: true, // boolean,是否运行在 VDVD 影音内
play: function (url, title, options) { /* → boolean */ },
openLibrary:function () { }
};
脚本在文档创建时注入,页面自己的 JS 可以直接用,不需要等 DOMContentLoaded。
undefined——务必先判断存在性。
五、play(url, title, options)
参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
url | string | ✅ | 播放地址(m3u8 等)。为空则不处理,返回 false。 |
title | string | 片名 / 集名。用于窗口标题、进度记忆、弹幕匹配。为空时取本页 document.title。 | |
options | object | 见下表。 |
options 字段:
| 字段 | 类型 | 说明 |
|---|---|---|
referer | string | 请求媒体时携带的 Referer。默认取当前页面地址(location.href),防盗链站点一般不用传。 |
playlist | array | 剧集清单,格式见第六节。不传时,播放器自动从当前页面的 window.VOD 读取。 |
startAt | number | 预留字段,当前版本不生效。播放器按自己的本地播放记忆续播;保留传参以便日后兼容,不要依赖它。 |
返回值
| 返回 | 含义 | 你该做什么 |
|---|---|---|
true | 已受理,播放器会切到自己的界面开始播 | 不用做别的,页面即将被切走 |
false | 没有桥(不在播放器内)或 url 为空 | 回退到站点自己的播放器 |
true / false。
六、剧集清单(选集)格式
window.VDVDPlayer.play(url, '片名', { playlist: [ { name: '线路一', episodes: [ { name: '第 1 集', url: 'https://cdn.example.com/1/index.m3u8' }, { name: '第 2 集', url: 'https://cdn.example.com/2/index.m3u8' } ] }, { name: '线路二', episodes: [ { name: '第 1 集', url: 'https://cdn2.example.com/1/index.m3u8' } ] } ] });
规则:
- 顶层是线路数组,每条线路含
name+episodes; - 集对象只需要
name与url;url为空的集会被忽略,整条线路没有有效集则整条丢弃; - 一条也没有时清单视为空,只播你传的
url,不显示选集。
不传 playlist 时,播放器按下面规则自动读当前页面的 window.VOD:
| 播放器读的字段 | 站点原字段 | 缺省处理 |
|---|---|---|
| 线路名 | window.VOD.lines[i].name | 缺省 线路N |
| 集名 | window.VOD.lines[i].episodes[j].n | 缺省 第N集 |
| 集地址 | window.VOD.lines[i].episodes[j].u | 无值则忽略该集 |
vdvd://)不支持选集——协议只带一条地址。要选集就走桥接式。
七、openLibrary()
window.VDVDPlayer.openLibrary();
回到播放器自带的界面(资源库 / 搜索),同样带「返回网站」。无参数、无返回值。
播放器还会在你站点的页面上自动放一个小小的「播放器」悬浮按钮(右下角,id="__vdvd_entry"),
点击等于调用 openLibrary()。
id="__vdvd_entry" 的元素(哪怕是
<div id="__vdvd_entry" hidden></div>)占位即可——脚本检测到同名 id 就不再插入自己的按钮。
八、推荐写法:两种方式 + 优雅降级
function playVideo(mediaUrl, title, playlist) { var p = window.VDVDPlayer; // ① 正在播放器内置浏览器里浏览本站 → 直接交给桥接 API(可带选集) if (p && p.isEmbedded) { p.play(mediaUrl, title, playlist ? { playlist: playlist } : undefined); return; } // ② 在普通浏览器里 → 唤起式(装了就弹播放器,没装就跳下载页) launchVdvd(vdvdUrl(mediaUrl, title), 'https://pc.vdvd.net/'); }
要点:
- 判断用
isEmbedded,不要用typeof window.VDVDPlayer !== 'undefined'——普通 Chrome 里未来可能出现同名对象,isEmbedded才是准确信号; - 手动调用与自动接管只会生效一次:显式调过
play()后,自动接管不会再插一脚。
九、常见问题
浏览器里调试,window.VDVDPlayer 是 undefined?
正常。它只在 VDVD 影音内注入。浏览器里走 isEmbedded 分支或唤起式链接。
点 vdvd:// 链接没反应?
① 访客是否装了 VDVD 影音(1.1.0 及以上);② url 是否编码正确(空格要 %20);③ 浏览器是否弹了确认框而访客没点「打开」。没装的情况按 2.4 兜底跳下载页。
播放器没回到我原来的页面?
会回,入口是顶栏「返回网站」,回的是 back(没传就是 referer)。回跳地址带一次性标记(#__vdvd=back),所以不会来回跳。
防盗链 / 需要 Referer 的源怎么办?
唤起式请显式传 referer(本页地址);桥接式默认就用当前页地址,一般不用管。
url 传网页地址会怎样?
播放器只当它是媒体地址。请传可播的媒体地址(m3u8 直链等)。
会重复接管、或选集停在上一部剧吗?
不会。同一页面只接管一次;唤起式不带选集,会先清掉上一次的选集,不会串剧。
一次能传几百集吗?
桥接式的 playlist 可以。清单只存在播放器内存里用于渲染选集,不发网络请求。
Mac / 手机 / Linux 能用吗?
不能。目前只有 Windows 版,其他平台一律走你自己的播放器或提示下载。
十、版本与兼容
| 版本 | 内容 |
|---|---|
1.1 |
version / isEmbedded / play(url, title, options) / openLibrary();
MacCMS 自动接管;playlist 选集;referer 注入;
vdvd:// 唤起(安装时注册协议)。
|
约定:只增不改、不删字段。新增能力会体现在 version 上,老代码不用跟着改。
排查问题第一步:console.log(window.VDVDPlayer.version)。
十一、边界与合规
- 唤起式只在 Windows 10 / 11 上有效;桥接式只在 VDVD 影音内置浏览器里有效;
- 播放器不代理、不存储、不分发视频内容,串流全程从你的地址直连访客设备;
Referer仅用于适配你站点的防盗链; - 播放地址由站点提供,内容合法性由站点自行负责;
- 站点页面上的「播放器」悬浮按钮与「返回网站」是播放器提供的通用体验,不影响页面其他功能。