播放器皮肤开发制作说明
瑞亿播放器支持导入自定义皮肤包。你只需编写一个 .json 文件,
描述配色、圆角、模糊、背景与自定义 CSS 规则,即可在不修改播放器源码的前提下
制作属于自己的界面皮肤,并可限定皮肤仅在视频或音乐模式生效。
一、开发概览
整个流程只有三步,不需要编译工具链,也不需要改动播放器任何代码:
- 编写用任意文本编辑器新建一个
.json文件,填写元信息与vars配色变量,可选填写css自定义规则。 - 导入打开播放器 → 设置 → 上传皮肤 → 导入
.json皮肤包,导入时即校验字段合法性。 - 生效在「视频界面风格」或「音乐播放器风格」中选择该皮肤,设置会保存在本机。
皮肤是「覆盖」而非「重写」。播放器的基础布局与交互始终由内置样式保证,你的皮肤只改变配色与外观细节,因此不会出现皮肤导致功能不可用的情况。
皮肤能做什么
二、皮肤包格式
皮肤包是一个 UTF-8 编码的 .json 文件,顶层为单个对象。
{
"id": "neon-night",
"name": "霓虹夜色",
"author": "你的昵称",
"version": "1.0.0",
"desc": "深色霓虹风格,适合夜间观影",
"mode": "both",
"vars": {
"accent": "#22d3ee",
"accent2": "#f472b6",
"base": "#0a0f1c",
"text": "#e8eefb",
"textDim": "#9fb0cc",
"surface": "rgba(255,255,255,0.06)",
"border": "rgba(255,255,255,0.12)",
"radius": 18,
"blur": 24
},
"bg": "linear-gradient(160deg,#0b1530,#05070f)",
"css": ".stage { border-color: rgba(34,211,238,.28); }"
}
JSON 不支持注释,请勿写入 // 或 /* */。文件必须是标准 JSON,否则导入会失败。
三、字段详解
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 必填 | 皮肤唯一标识,用于本地存储与作用域匹配。只能包含小写字母、数字、下划线 _ 与短横线 -,长度 2–32。 |
name | string | 必填 | 显示名称,超出 24 字符会被截断。 |
author | string | 选填 | 作者名,缺省显示「匿名作者」,超出 24 字符截断。 |
version | string | 选填 | 版本号,缺省为 1.0.0。 |
desc | string | 选填 | 皮肤描述,缺省为「用户导入皮肤」,超出 60 字符截断。 |
mode | string | 选填 | 生效范围:video 仅视频 / music 仅音乐 / both 两者都生效。缺省为 both。 |
vars | object | 选填 | 配色与形状变量,详见第四章。 |
bg | string | 选填 | 背景图 CSS 值,接受 url(...) 或任意渐变函数。 |
css | string | 选填 | 自定义 CSS 规则,会被拼接到选择器之后,详见第五章。长度上限 20000 字符。 |
校验规则
导入时会执行以下校验,任一不通过即拒绝导入并给出明确原因:
- 顶层必须是 JSON 对象
id必填,且满足^[a-z0-9_-]{2,32}$name必填mode只能是video/music/bothvars若存在必须是对象- 颜色变量须为
#RGB或#RRGGBB十六进制值
四、配色与形状变量
播放器界面完全由 CSS 变量驱动,你只需覆盖这些变量即可完成整体换肤。
| 变量键 | 对应 CSS 变量 | 类型 | 作用 |
|---|---|---|---|
accent | --ry-accent | 颜色 | 主色:进度条、按钮、高亮文字 |
accent2 | --ry-accent-2 | 颜色 | 辅色:与主色组成渐变 |
base | --ry-base | 颜色 | 底色:抽屉、浮层等实色背景 |
text | --ry-text | 颜色 | 主文字色 |
textDim | --ry-text-dim | 颜色 | 次要文字色 |
surface | --ry-surface | 颜色 | 卡片/面板半透明底色 |
border | --ry-border | 颜色 | 边框线颜色 |
radius | --ry-radius | 数字 | 圆角基准值(px),同时派生 sm/lg 两档 |
blur | --ry-blur | 数字 | 毛玻璃模糊强度(px) |
设置 radius: 18 时,播放器会自动得到 --ry-radius: 18px、--ry-radius-sm: 12px(基准减 6)、--ry-radius-lg: 24px(基准加 6),无需分别设置。
可复用的完整 CSS 变量
除上表九个之外,界面还提供以下变量,可直接在 css 字段中使用:
/* 文字三级色 */
--ry-text /* 主文字 */
--ry-text-dim /* 次要文字 */
--ry-text-mute /* 弱化文字 */
/* 表面三级底色 */
--ry-surface /* 卡片底色 */
--ry-surface-2 /* 悬浮态 */
--ry-surface-3 /* 强调块 */
/* 形状 */
--ry-radius-sm --ry-radius --ry-radius-lg --ry-radius-pill
--ry-blur
/* 阴影与渐变 */
--ry-shadow --ry-shadow-sm
--ry-accent-grad /* 主色渐变,自动由 accent/accent2 组成 */
/* 字体 */
--ry-font --ry-font-mono
五、可用选择器
css 字段中的每条规则会被自动拼接到作用域选择器之后。默认作用域为:
[data-user-skin~"你的皮肤id"] /* 你写的选择器 */
若 mode 为 video 或 music,作用域会额外限定模式,
例如 [data-skin-active="music"][data-user-skin~="your-id"]。
这意味着你不需要担心自己的规则污染其他模式。
常用界面元素
| 选择器 | 对应元素 |
|---|---|
.stage | 主播放区域容器 |
.side | 播放列表面板 |
.topbar | 顶部导航栏 |
.brand__mark | Logo 图标 |
.nav__item | 导航按钮(.is-active 为选中态) |
.item | 播放列表项(.is-current 为当前播放) |
.slider__fill | 进度条/音量条填充 |
.ctrl--play | 主播放按钮 |
.stage__center | 画面中央的大播放键 |
.chip | 画质/倍速等小标签 |
.drawer | 设置抽屉 |
.music-now | 音乐模式主面板 |
.music-lyric__line.is-on | 当前高亮歌词行 |
.ctx__item | 右键菜单项 |
.toast | 提示气泡 |
实用示例
/* 更强的玻璃质感 */
.stage, .side { backdrop-filter: blur(30px) saturate(150%); }
/* 方形界面(覆盖圆角变量) */
.stage, .side, .item { border-radius: 4px; }
/* 隐藏不需要的控件 */
.stage__tools { display: none; }
/* 加大播放按钮 */
.ctrl--play { width: 64px; height: 64px; }
/* 列表项更紧凑 */
.item { padding: 5px 8px; }
.item__thumb { width: 48px; height: 30px; }
上表列出的选择器属于稳定的对外契约。未列出的内部类名可能在版本更新中变化,请勿依赖它们,否则升级后皮肤可能失效。
六、完整示例
下面是一个可直接使用的完整皮肤包,保存为 neon-night.json 即可导入。
{
"id": "neon-night",
"name": "霓虹夜色",
"author": "瑞亿智创",
"version": "1.0.0",
"desc": "深色霓虹风格,适合夜间观影与听歌",
"mode": "both",
"vars": {
"accent": "#22d3ee",
"accent2": "#f472b6",
"base": "#080d18",
"text": "#eaf2ff",
"textDim": "#94a9c8",
"surface": "rgba(255,255,255,0.055)",
"border": "rgba(34,211,238,0.22)",
"radius": 18,
"blur": 26
},
"css": ".stage { border-color: rgba(34,211,238,.3); box-shadow: 0 18px 48px rgba(0,0,0,.55); }\n.side { backdrop-filter: blur(30px) saturate(140%); }\n.item:hover { background: rgba(34,211,238,.1); }\n.stage__center { box-shadow: 0 0 44px rgba(34,211,238,.5); }\n.nav__item.is-active { color: #f472b6; }"
}
音乐专用皮肤示例
如果你的皮肤只想作用于音乐播放器,把 mode 设为 music 即可:
{
"id": "warm-vinyl",
"name": "暖调黑胶",
"mode": "music",
"vars": {
"accent": "#fbbf24",
"accent2": "#b45309",
"base": "#191613",
"radius": 10
},
"css": ".music-now__art { border-radius: 50%; }"
}
七、调试与上架
本地调试
开发过程中建议直接在浏览器控制台验证,无需反复导入:
// 查看当前生效的皮肤
RuiYi.Skins.loadUserSkins();
// 实时预览配色(不落盘)
document.documentElement.style.setProperty('--ry-accent', '#ff6b6b');
// 校验你的皮肤包,返回 { ok, err } 或 { ok, skin }
RuiYi.Skins.validate({ id: 'test', name: '测试' });
// 查看全部可用变量当前值
getComputedStyle(document.documentElement).getPropertyValue('--ry-accent');
常见问题排查
| 现象 | 原因 | 解决 |
|---|---|---|
| 导入提示「JSON 格式错误」 | 文件含注释或尾逗号 | 改为标准 JSON,删除所有 // 注释与末尾多余逗号 |
| 导入提示「id 只能包含小写字母…」 | id 含大写或非法字符 | 改为 a-z 0-9 _ -,长度 2–32 |
| 导入成功但界面没变化 | 未在风格列表中选中它 | 在「视频界面风格」或「音乐播放器风格」中点击该皮肤卡片 |
| 配色改了但没生效 | 被更高优先级的内联样式覆盖 | 不要在 css 里写 style="...",改用变量覆盖 |
| 只在一种模式下生效 | mode 设成了单一值 | 改为 both |
| 提示「皮肤包过大」 | 本地存储超出配额(约 5MB) | 精简 css 内容,或改用外部图片 URL |
提交到皮肤市场
完成 skin 包后,可在皮肤市场投稿,需一并提供:
.json皮肤包文件- 一张 1280×720 的界面截图(视频、音乐各一张)
- 50–150 字的皮肤介绍
- 确认不含版权争议素材与恶意代码
我们会校验 JSON 合法性、确认文字与背景对比度满足 WCAG AA、并在各模式下实测截图。通过后即在皮肤市场展示,用户可直接下载使用。
八、常见问题
皮肤会覆盖我的其他设置吗?
不会。皮肤只影响视觉表现,音量、播放模式、均衡器等播放行为设置完全独立,互不干扰。
皮肤里的 CSS 会影响网站吗?
不会。皮肤作用域限定在播放器根节点(data-user-skin 属性)内部,官网与在线体验页不受影响。
换电脑后皮肤会同步吗?
皮肤保存在本机浏览器,不随账号同步。把 .json 文件带到新设备重新导入即可,文件本身就是最可靠的载体。
可以使用外部图片吗?
可以。bg 字段接受 url("https://...") 形式。但需注意:跨域图片在部分平台可能因安全策略无法加载,正式发布建议使用图床直链或纯 CSS 渐变。
如何让皮肤适配浅色背景?
设置 text 为深色(如 #0f1a2e)、textDim 为中灰,并让 base 使用浅色。同时在 css 中为 .stage 指定浅色背景以保证对比度。