MENU

任意站点引入 APlayer 和 Meting 的简单方法

2020 年 02 月 11 日 • 阅读: 53985 • 博客

关于 音视频播放,之前介绍过 DPlayerYoduPlayer,今天介绍下 APlayerMeting,可播放 网易云QQ 音乐酷狗虾米百度 以及 自定义的 单曲和歌单,按需加载 JS,不依赖插件和服务器计算存储,任意站点都可使用。

引入 JS

对于 本主题,依次进入 控制台 - 外观 - 设置外观 - 主题自定义扩展,将代码加入到 自定义 HTML 元素拓展 - 标签: head 头部 (meta 元素后)。其他主题,加入到主题对应的 header.php 中的 </head> 标签前。

Almost JavaScript Code

<script>
    // APlayer API
    document.addEventListener('DOMContentLoaded', initAplayer);
    window.aplayers = window.aplayers || [];
    function initAplayer(option) {
        const common = {
            loadResource: function (id, resource, type) {
                return new Promise(function (resolve, reject) {
                    let loaded = document.head.querySelector('#' + id);
                    if (loaded) {
                        resolve('success: ' + resource);
                        return;
                    }
                    const element = document.createElement(type);
                    element.onload = element.onreadystatechange = () => {
                        if (!loaded && (!element.readyState || /loaded|complete/.test(element.readyState))) {
                            element.onload = element.onreadystatechange = null;
                            loaded = true;
                            resolve('success: ' + resource);
                        }
                    }
                    element.onerror = function () {
                        reject(Error(resource + ' load error!'));
                    };
                    if (type === 'link') {
                        element.rel = 'stylesheet';
                        element.href = resource;
                    } else {
                        element.src = resource;
                    }
                    element.id = id;
                    document.getElementsByTagName('head')[0].appendChild(element);
                });
            },
            loadResources: function (callback) {
                const loadResource = this.loadResource;
                const pt = '//s0.pstatp.com/cdn/expire-1-M/';
                const jd = '//cdn.jsdelivr.net/npm/';
                const resources = [
                    pt + 'aplayer/1.10.1/APlayer.min.css',
                    pt + 'aplayer/1.10.1/APlayer.min.js',
                    jd + 'meting@2/dist/Meting.min.js'
                ];
                const loadPromises = [];
                resources.forEach(resource => {
                    loadPromises.push(loadResource(btoa(resource).replace(/[=+\/]/g, ''), resource,
                        ({
                            'css': 'link',
                            'js': 'script'
                        })[resource.split('.').pop()]
                    ));
                });
                Promise.all(loadPromises).then(
                    function () {
                        if (typeof callback !== 'function') return;
                        let flag = false;
                        const waitAM = setInterval(() => {
                            if (!flag
                                && typeof APlayer === 'function'
                                && typeof MetingJSElement === 'function') {
                                flag = true;
                                callback();
                                clearInterval(waitAM);
                            }
                        }, 100);
                    }
                );
            },
            createAplayers: function (sources) {
                for (let i = 0; i < sources.length; i++) {
                    const child = document.createElement('div');
                    sources[i].parentNode.insertBefore(child, sources[i]);
                    sources[i].style.display = 'none';
                    const songsTag = sources[i].querySelectorAll('s');
                    const songs = [];
                    songsTag.forEach(songTag => {
                        const song = {};
                        for (let i = 0; i < songTag.attributes.length; i++) {
                            song[songTag.attributes[i].name] = songTag.attributes[i].value;
                        }
                        songs.push(song);
                    });
                    const options = { container: child, preload: 'none', autoplay: false, audio: songs };
                    const optionMap = sources[i].attributes;
                    for (let i = 0; i < optionMap.length; i++) {
                        options[optionMap[i].name] = optionMap[i].value;
                    }
                    this.loadResources(() => window.aplayers.push(new APlayer(options)));
                }
            }
        };

        if (option == 'manual') return new Promise((resolve, reject) => {
            common.loadResources(() => resolve('success'));
        });

        const aps = document.querySelectorAll('ap');
        if (aps.length !== 0) common.createAplayers(aps);

        const mts = document.querySelectorAll('meting-js');
        if (!window.refreshing && mts.length !== 0) common.loadResources(
            function () {
                mts.forEach(mt => {
                    if (!mt.aplayer) {
                        const html = mt.outerHTML;
                        mt.aplayer = { destroy: new Function(), list: { index: undefined } };
                        mt.outerHTML = '\n' + html;
                    }
                });
                document.querySelectorAll('meting-js').forEach(mt => {
                    let flag = false;
                    const waitMT = setInterval(() => {
                        if (!flag && mt.aplayer) {
                            flag = true;
                            window.aplayers.push(mt.aplayer);
                            console.log('replaced unloaded aplayer.')
                            clearInterval(waitMT);
                        }
                    }, 300);
                });
            }
        );
    }
</script>

<script>
    // PJAX 相关 BUG
    document.addEventListener('DOMContentLoaded', function () {
        let flag = false;
        window.needReloadUrls = window.needReloadUrls || new Set();
        const jqueryWaitor = setInterval(() => {
            if (!flag && jQuery) {
                flag = true;
                $(document).on('pjax:start', function () {
                    if (!window.refreshing || !window.pjaxStarted) {
                        window.pjaxStarted = true;
                        console.log('pjax:start');
                        window.aplayers.forEach(ap => {
                            ap.list.index = undefined;
                            ap.destroy();
                        });
                        window.aplayers = [];
                        setTimeout(() => window.pjaxStarted = false, 2000);
                    }
                });
                $(document).on('pjax:end', function () {
                    if (document.querySelector('meting-js')
                        || document.querySelector('.collapse-block')
                        || document.querySelector('#toggle-menu-tree')
                        || document.querySelectorAll('.content-tab-title').length > 1
                    ) {
                        if (!window.needReloadUrls.has(location.href)) {
                            window.needReloadUrls.add(location.href);
                            console.log('captured a neededReloadUrl.');
                        }
                    }
                });
                $(document).on('pjax:popstate', function (event) {
                    if (event.state && window.needReloadUrls.has(event.state.url) && !window.refreshing) {
                        window.refreshing = true;
                        console.log('back-forward handler.');
                        $.pjax.reload({
                            url: location.href,
                            container: '#body',
                            fragment: '#body',
                            scrollTo: false,
                            timeout: 8000
                        });
                        setTimeout(() => window.refreshing = false, 2000);
                    }
                });
                clearInterval(jqueryWaitor);
            }
        }, 500);
    });
</script>

如果你开启了 PJAX,可能需要单独加入回调函数。对于本主题,依次进入 控制台 - 外观 - 设置外观 - PJAX(BETA) - PJAX RELOAD,将 initAplayer(); 添加进入即可。

演示效果

在文章所需位置以 HTML 形式插入代码,即可添加播放器。

!!!
<!-- 引入方式 -->
<meting-js auto="https://music.163.com/#/playlist?id=110459831"></meting-js>
!!!
!!!
<!-- 引入方式 -->
<meting-js auto="https://y.qq.com/n/yqq/playlist/7355087593.html"></meting-js>
!!!
!!!
<!-- 标签引入 -->
<ap>
<s
    name="rainymood"
    artist="rainymood"
    url="https://rainymood.com/audio1110/0.m4a"
    cover="https://rainymood.com/i/badge.jpg">
</s>
</ap>
!!!

!!!
<!-- 或编程引入 -->
<div id="ap"></div>
<script>
    initAplayer('manual').then(() => {
        window.aplayers.push(new APlayer({
            container: document.querySelector('#ap'), preload: 'none', autoplay: false, audio: [
                {
                    name="rainymood",
                    artist="rainymood",
                    url="https://rainymood.com/audio1110/0.m4a",
                    cover="https://rainymood.com/i/badge.jpg"
                }
            ]
        }));
    });
</script>
!!!

TG 大佬群 QQ 大佬群

最后编辑于: 2020 年 02 月 21 日
返回文章列表 文章二维码
本页链接的二维码
打赏二维码
添加新评论

Loading captcha...

已有 26 条评论
  1. 房东的喵 房东的喵   Windows 10 x64 Edition  Google Chrome 86.0.4240.183


    设置的歌单,但是实际只显示一首!什么情况呀!

  2. 小明同学 小明同学   Windows 10 x64 Edition  Google Chrome 75.0.3770.80

    大佬,网易云和QQ咋都挂了,显示不了了!!!~

    1. LOGI LOGI   Windows 10 x64 Edition  Google Chrome 81.0.4044.92

      @小明同学自建下API吧,可能官方用的人太多了
      https://github.com/metowolf/MetingJS#advanced

    2. 小明同学 小明同学   Windows 10 x64 Edition  Google Chrome 75.0.3770.80

      @LOGI小白表示不会,请问有没有详细步骤可以学习

    3. LOGI LOGI   Windows 10 x64 Edition  Google Chrome 81.0.4044.92

      @小明同学可以加群

  3. 月下读心 月下读心   iOS 13.3.1  Safari 13.0.5

    大佬,网易和QQ都失效了

    1. LOGI LOGI   Windows 10 x64 Edition  Google Chrome 80.0.3987.163

      @月下读心示例正常@(呵呵)

    2. 月下读心 月下读心   iOS 13.3.1  Safari 13.0.5

      @LOGI现在看正常了,尴尬

  4. 初夏阳光 初夏阳光   Windows 10 x64 Edition  Google Chrome 80.0.3987.122

    我吐了,我写了一大篇,然后超出200字符限制了,删了又删才发出去了。。
    链接:https://github.com/MoePlayer/hexo-tag-aplayer/blob/master/docs/README-zh_cn.md#pjax-%E5%85%BC%E5%AE%B9

    1. LOGI LOGI   Windows 10 x64 Edition  Google Chrome 80.0.3987.132

      @初夏阳光后台看到我感动哭了,这个方法我看了,后来发现本题本身也有 bug,所以等待主题作者进度了

    2. LOGI LOGI   Windows 10 x64 Edition  Google Chrome 80.0.3987.132

      @初夏阳光当初写这段代码原因之一是 Aplayer 插件和我写的 Dplayer 冲突,其次是想着检测到 meting-js 标签再加载 js css,大多数页面就可以少发几个请求了

  5. 初夏阳光 初夏阳光   Windows 10 x64 Edition  Google Chrome 80.0.3987.122

    关于Pjax我今天找到了一个解决方案,Pjax开始时清理APlayer全局实例。虽然我看你那个 135 行好像也是清除全局实例。但你的 Pjax 回退到 Aplayer 的时候 Meting.js 报错 Cannot read property 'destroy' of undefined

    1. LOGI LOGI   Windows 10 x64 Edition  Google Chrome 80.0.3987.132

      @初夏阳光看你评论好多遍,我都心疼@(笑尿),是触发了哪些规则呢

    2. 初夏阳光 初夏阳光   Windows 10 x64 Edition  Google Chrome 80.0.3987.122

      @LOGI一直都是超过了200个字符限制。还说我不认真评论找不到女朋友。www

    3. LOGI LOGI   Windows 10 x64 Edition  Google Chrome 80.0.3987.132

      @初夏阳光之前被刷评搞得很烦,所以不得已

    4. 初夏阳光 初夏阳光   Windows 10 x64 Edition  Google Chrome 80.0.3987.122

      @LOGI我的垃圾评论也有一些,开了不包含中文的全拦截。现在偶尔有几条我都是手动清的,毕竟有的时候冷冷清清看一看垃圾评论也可消遣一下

  6. 小童 小童   Windows 10 x64 Edition  Google Chrome 79.0.3945.130

    发现了一个关于播放器显示的bug,不知道是主题问题还是啥问题,而且大佬你和我博客都存在。
    在有加载播放器的页面的时候,点击任意按钮或者离开当前页面进入下一页面之后,使用浏览器的返回,返回到有加载播放器的页面的时候,会出现播放器重叠情况,手机端电脑端谷歌qq浏览器经过尝试都会出现。是和hran的主题存在冲突嘛#(期待)

    1. LOGI LOGI   Windows 10 x64 Edition  Google Chrome 80.0.3987.116

      @小童是 meting-js 的 bug,稍后解决

    2. LOGI LOGI   Windows 10 x64 Edition  Google Chrome 80.0.3987.116

      @LOGI我更新了,有问题再反馈,pjax 会产生很多错误,不仅仅是播放器,主题本身也有 bug,比如折叠框和多标签按钮在返回前进后都无法点击,该问题我已经告诉主题作者了

    3. 小童 小童   Windows 10 x64 Edition  Google Chrome 79.0.3945.130

      @LOGI咋整的呀@(小乖)我看你已经好了

    4. LOGI LOGI   Windows 10 x64 Edition  Google Chrome 80.0.3987.116

      @小童替换下代码

    5. 小童 小童   Windows 10 x64 Edition  Google Chrome 79.0.3945.130

      @LOGI谢谢大佬@(乖)

  7. 于长野 于长野   Windows 10 x64 Edition  Google Chrome 78.0.3904.108

    #(献花)

  8. 初夏阳光 初夏阳光   Windows 10 x64 Edition  Google Chrome 79.0.3945.130

    诶,整的好!@(真棒)

  9. Xin Xin   Windows 10 x64 Edition  Google Chrome 80.0.3987.87

    很赞,连插件都省了@(呵呵)

    1. LOGI LOGI   Windows 10 x64 Edition  Google Chrome 80.0.3987.100

      @Xin之前的有点问题,如果在用就更新下代码@(哈哈)