更新于 2026年8月29日 1.4k 字 6 分钟

为Hexo-Redefine主题启用MetingJs

本教程适配 Redefine v2.8.2

最近把Hexo的主题切换到了Redefine,用着还不错
看文档说支持Aplayer播放器,但是不支持MetingJs,只能自己添加音频直链,挺麻烦的(而且也不支持页面内嵌Aplayer播放器)
于是我就花了点时间捣鼓了一下,实现效果还不错,但是移动端好像无法正常显示🤔
不知道咋回事,先将就用着吧,看有没有大佬能够完善一下或者看作者会不会加到主题里面了>︿<

引入JS文件

第一步当然是引入相关的js文件了,我的选择是把文件保存本地然后在主题里面以相对路径引用。
由于Aplayer.min.js主题里面已经有了,所以我们只需要把Meting.min.js下载下来就行了。

Meting.min.js: Meting.min.js

随后将Meting.min.js移至 theme/redefine/source/js/build/libs 即可。

然后新建一个文件,路径为 theme/redefine/layout/components/plugins/meting_js_only.ejs ,内容为

<%- renderJS('libs/APlayer.min.js') %>
<%- renderJS('libs/Meting.min.js') %>

起这个名字的原因是 我仅想引入Aplayer和Meting的js文件而不直接创建一个Aplayer的容器,因为我不想搞那个全局吸底,我想弄的是页面内嵌播放器
页面内嵌播放器的格式跟全局吸底的不同

然后在同级目录里面创建一个名为 meting.ejs 的文件(路径: theme/redefine/layout/components/plugins/meting.ejs ),内容为:

<div id="meting-container"></div>
<%- renderJS('plugins/meting.js') %>

既然有纯js版的也就有创建容器版的,但是这个就只是创建容器而没有引入js了

Meting.js之构建全局播放器

欸,上面说不是有引入 js/plugins/meting.js吗?那文件呢?
你先别急,这不就来了吗
这个文件是用于 读取配置文件中的参数来构建一个全局吸底的播放器

此文件路径 themes/redefine/source/build/js/plugins/meting.js

meting.js内容:

// 从主题配置中获取 meting 配置
const metingConfig = theme.plugins.meting;
console.log('Meting Config:', metingConfig);

// 初始化播放器配置的函数
function initMetingPlayer() {
    // 检查必选参数
    if (!metingConfig.id || !metingConfig.server || !metingConfig.type) {
        console.error('Missing required parameters:', {
            id: metingConfig.id,
            server: metingConfig.server,
            type: metingConfig.type
        });
        return;
    }

    // 创建 meting-js 元素
    const metingElement = document.createElement('meting-js');
    
    // 设置必选属性
    metingElement.setAttribute('server', metingConfig.server);
    metingElement.setAttribute('type', metingConfig.type);
    metingElement.setAttribute('id', metingConfig.id);

    // 根据播放器类型设置 fixed 或 mini
    if (metingConfig.playerType === 'fixed') {
        metingElement.setAttribute('fixed', 'true');
    } else if (metingConfig.playerType === 'mini') {
        metingElement.setAttribute('mini', 'true');
    }

    // 设置其他可选属性
    if (metingConfig.autoplay !== undefined) {
        metingElement.setAttribute('autoplay', metingConfig.autoplay);
    }
    if (metingConfig.theme !== undefined) {
        metingElement.setAttribute('theme', metingConfig.theme);
    }
    if (metingConfig.loop !== undefined) {
        metingElement.setAttribute('loop', metingConfig.loop);
    }
    if (metingConfig.order !== undefined) {
        metingElement.setAttribute('order', metingConfig.order);
    }
    if (metingConfig.preload !== undefined) {
        metingElement.setAttribute('preload', metingConfig.preload);
    }
    if (metingConfig.volume !== undefined) {
        metingElement.setAttribute('volume', metingConfig.volume);
    }
    if (metingConfig.mutex !== undefined) {
        metingElement.setAttribute('mutex', metingConfig.mutex);
    }
    if (metingConfig.lrcType !== undefined) {
        metingElement.setAttribute('lrc-type', metingConfig.lrcType);
    }
    if (metingConfig.listFolded !== undefined) {
        metingElement.setAttribute('list-folded', metingConfig.listFolded);
    }
    if (metingConfig.listMaxHeight !== undefined) {
        metingElement.setAttribute('list-max-height', metingConfig.listMaxHeight);
    }
    if (metingConfig.storageName !== undefined) {
        metingElement.setAttribute('storage-name', metingConfig.storageName);
    }

    // 获取并清空 meting-container 容器
    const apContainer = document.getElementById('meting-container');
    if (apContainer) {
        apContainer.innerHTML = '';
        // 将 meting-js 元素添加到容器中
        apContainer.appendChild(metingElement);
    }

    console.log('Created meting element:', metingElement.outerHTML);
}

// 确保 DOM 加载完成后再执行初始化
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initMetingPlayer);
} else {
    initMetingPlayer();
}

注入主题文件

万事俱备,只欠东风。
现在我们只需要把这些组件给注入到主题文件里面就行了。
编辑布局文件 theme/redefine/layout/layout.ejs
将其修改为:

<!DOCTYPE html>
<html lang="<%= config.language %>">
<%- partial('components/header/head') %>
<body>
	<%- body %>
	<%- partial('components/scripts') %>
	<% if (theme.plugins.aplayer.enable) { %>
	<%- partial('components/plugins/aplayer') %>
	<% } %>
	<% if (theme.plugins.meting.enable) { %>
		<%- partial('components/plugins/meting_js_only') %>
	<% } %>
	<% if (theme.plugins.meting.global_sticky_enable) { %>
		<%- partial('components/plugins/meting') %>
	<% } %>
</body>
</html>

即可。

你可能会发现,在布局文件中有几个开关来控制是否引入这些文件,那么我们现在添加。
config.redefine.yml 添加一个配置项:(在plugins下,其实紧挨着 aplayer 配置项就行了,注意缩进)

  meting: # MetingJs相关配置
    enable: true # 是否全局注入Aplayer.js与Meting.js
    global_sticky_enable: false # 是否启用全局吸底,不启用的话下面的配置项无效
    id: '1926144232' # 歌曲ID / 歌单ID / 专辑ID
    server: 'netease' # 音乐平台
    type: 'song' # ID对应的类型
    playerType: 'fixed' # 吸底 / 迷你 | fixed & mini 
    preload: 'auto' 
    loop: 'all'
    theme: '#4586F3'

更多配置项可前往 Github 查看:Option

OK,大功告成。你现在可以使用 hexo s 预览你的播放器效果了。

我只是想在页面中插入播放器

差点忘了这一茬。

如果你只希望在页面中插入播放器的话(而非全局吸底),那么其实可以这样

  1. 先引入JS文件,将Meting.min.js移至 theme/redefine/source/js/build/libs
  2. 编辑布局文件,theme/redefine/layout/layout.ejs,修改为
<!DOCTYPE html>
<html lang="<%= config.language %>">
<%- partial('components/header/head') %>
<body>
<%- body %>
<%- partial('components/scripts') %>
<% if (theme.plugins.meting.enable) { %>
    <%- renderJS('libs/APlayer.min.js') %>
    <%- renderJS('libs/Meting.min.js') %>
<% } %>
</body>
</html>

此处我把主题原本的 Aplayer 相关给删了,如果有需要可以加回来

  1. config.redefine.yml 添加一个配置项:(在plugins下,其实紧挨着 aplayer 配置项就行了,注意缩进)
    meting:
      enable: true

插入格式为

<meting-js
	server="netease"
	type="song"
	id="5221167">
</meting-js>

效果:

更多使用方法可前往Github查看:Quick Start

评论