皮肤制作

skin.xml + skin.css + skin.js 三层分离的皮肤架构,灵活打造任意界面

目录结构

skins/myskin/
├── skin.xml    (必需)布局结构:窗口位置 + 子元素坐标
├── skin.css    (必需)视觉样式:按钮、歌词、进度条等
└── skin.js     (可选)自定义逻辑:通过 hooks 接管播放器事件
皮肤目录还可以包含 PNG/JPG/SVG 素材文件(按钮图标、窗口底图等),CSS 中用相对路径引用即可。皮肤也支持 ZIP 包和远程 URL。

坐标系统(xywh)

所有元素的 xywh 支持混合单位,实现灵活的响应式布局。

单位含义示例
纯数字像素值50 = 50px
P父容器百分比100P = 100% / 50P = 50%
R从右/下边反向算像素50R = 距右边/底部 50px
C水平/垂直居中0C = 在该轴居中
Bborder-box:父容器尺寸 - 2×值50B = 父容器 - 100px
xywh="0C, 50R, 600, 46"
       ↑   ↑    ↑    ↑
       x   y    w    h

x = 0C  → 水平居中
y = 50R → 距底部 50px
w = 600 → 宽 600px
h = 46  → 高 46px

skin.xml(最简布局)

skin.xml

5 个顶层窗口:media(视频/封面)、lrc(歌词)、console(控制台)、list(列表)、option(设置)。

<skin name="myskin" version="1.0" author="你的名字">

  <!-- ① media 窗口:铺满全屏,放视频/封面/频谱 -->
  <media xywh="0, 0, 100P, 100P">
    <video xywh="0, 0, 100P, 100P" />
  </media>

  <!-- ② lrc 窗口:底部居中,高 150px -->
  <lrc xywh="0, 200R, 100P, 150">
    <text xywh="0, 0, 100P, 100P"
          align="center" size="24" color="#888,#fff" leading="36">
    </text>
  </lrc>

  <!-- ③ console 窗口:水平居中,距底 50px -->
  <console xywh="0C, 50R, 600, 46">
    <bt_play  xywh="0,   0,  46, 46"  tips="播放/暂停" />
    <bt_prev  xywh="54,  11, 24, 24"  tips="上一首" />
    <bt_next  xywh="82,  11, 24, 24"  tips="下一首" />
    <title    xywh="116, 11, 200, 24" />
    <progress xywh="320, 20, 200, 8"  tips="进度" />
    <time     xywh="528, 15, 60, 16"  />
    <bt_mute  xywh="594, 13, 20, 20"  tips="静音" />
    <volume   xywh="620, 17, 70, 8"   tips="音量" />
    <bt_list  xywh="700, 13, 24, 24"  tips="列表" />
  </console>

  <!-- ④ list 窗口:右侧,上下留 50px,默认隐藏 -->
  <list xywh="20R, 50, 260, 50B" display="0">
    <tree xywh="0, 0, 100P, 100P" />
  </list>

  <!-- ⑤ option 窗口:设置面板 -->
  <option xywh="20R, 50, 260, 50B" display="0">
    <pane xywh="0, 0, 100P, 100P" />
  </option>

</skin>

顶层窗口标签

标签子元素说明
<media><video> <spectrum>视频/封面/频谱容器
<lrc><text> <kmc>歌词显示区
<console>各种按钮/进度条/文字播放控制台
<list><tree>播放列表
<option><pane>设置面板

控制台子元素标签

标签说明标签说明
bt_play播放/暂停bt_prev上一首
bt_next下一首bt_mute静音
volume音量条progress进度条
time当前/总时长title歌曲标题
status状态文字bt_list列表开关
bt_option设置开关bt_fullscreen全屏
bt_lrc歌词开关bt_video视频开关
所有元素都支持 tips="..." 属性设置鼠标悬停提示文字。

lrc/text 标签属性

属性说明示例
align水平对齐center / left / right
size字号(px)24
font字体"楷体"
color普通色,高亮色#888,#fff
leading行高(px)36

skin.css(最简样式)

skin.css

所有皮肤元素都有统一的 CSS 类名前缀 lmp-。

/* 窗口:透明背景,无边框 */
.lmp-window { background: transparent; border: none; }

/* 按钮:圆形半透明黑底 */
.lmp-btn {
  background: rgba(0, 0, 0, 0.5);
  border-radius: 50%;
  cursor: pointer;
  transition: background 0.2s;
}
.lmp-btn:hover { background: rgba(0, 0, 0, 0.8); }
.lmp-bt_play { width: 46px; height: 46px; }

/* 歌词行 */
.lmp-lrc-line {
  font-size: 22px;
  color: rgba(255, 255, 255, 0.5);
  text-align: center;
  line-height: 1.5;
  padding: 4px 0;
  transition: all 0.3s;
}
.lmp-lrc-line.lmp-active {
  font-size: 28px;
  color: #fff;
  font-weight: bold;
  text-shadow: 0 0 10px rgba(0, 0, 0, 0.8);
}

/* 进度条 */
.lmp-progress-track {
  background: rgba(255, 255, 255, 0.3);
  border-radius: 4px;
}
.lmp-progress-loaded { background: rgba(255, 255, 255, 0.4); }
.lmp-progress-played { background: #0969da; }

/* 播放列表 */
.lmp-tree {
  background: rgba(0, 0, 0, 0.7);
  color: #fff;
  font-size: 13px;
  border-radius: 8px;
  padding: 8px;
}

/* 加载动画 */
.lmp-loading {
  background: rgba(0, 0, 0, 0.5);
  border-radius: 50%;
}

skin.js(可选自定义逻辑)

skin.js

通过 LMP34.hooks 监听播放器事件,接管默认行为。不写也能正常播放。

(function () {
    var hooks = LMP34.hooks;
    var NAMES = hooks.NAMES;

    // 播放状态变化:切换按钮图标
    hooks.addAction(NAMES.MEDIA_STATE, function (state) {
        var btn = document.querySelector('.lmp-bt_play');
        if (!btn) return;
        // state: 1=播放 2=暂停 3=停止
        btn.textContent = (state === 1) ? '❚❚' : '▶';
    });

    // 歌曲切换:控制台标题
    hooks.addAction(NAMES.ITEM_CHANGE, function (item) {
        var title = document.querySelector('.lmp-title');
        if (title && item) title.textContent = item.title || item.label || '';
    });

    // 皮肤初始化完成
    hooks.addAction(NAMES.SKIN_READY, function () {
        console.log('skin loaded');
    });

})();

皮肤 CSS 类名速查

类名说明
.lmp-window所有顶层窗口的公共类
.lmp-btn所有按钮的公共类
.lmp-bt_play播放按钮
.lmp-bt_prev上一首按钮
.lmp-bt_next下一首按钮
.lmp-progress-track进度条轨道
.lmp-progress-loaded已缓冲部分
.lmp-progress-played已播放部分
.lmp-volume-track音量条轨道
.lmp-lrc-text歌词容器
.lmp-lrc-line每一行歌词
.lmp-lrc-line.lmp-active当前高亮行
.lmp-video-container视频容器
.lmp-cover封面图
.lmp-loading加载动画
.lmp-spectrum频谱 canvas
.lmp-tree播放列表树
.lmp-item列表中的单曲项
.lmp-item.lmp-current当前播放项

启用皮肤

LMP34.init({
    container: 'lmp34-player',
    skins: 'skins/myskin',          // 单个皮肤目录
    // 或多个:skins: 'skins/default,skins/qqplayer,skins/myskin'
    // 默认选第 3 个:skin_id: 3
    lists: 'list.xml',
    name: '我的播放器',
    url: ''
});

事件钩子(hooks.NAMES)

事件名触发时机回调参数
MEDIA_STATE播放状态变化state (1播放/2暂停/3停止)
ITEM_CHANGE切歌item 对象
LRC_LOADED歌词加载完成歌词文本
LRC_RENDER_LINES歌词行渲染后lines 数组, elements
SKIN_READY皮肤加载完成-
PLUGIN_READY插件加载完成插件名