为你的网站引入APlayer和Meting,播放网易云、QQ等各平台音乐

  • 📝教程
  • 5814 阅读
  • 2021年09月29日
  • 0 条评论
  • 全文共224字, 阅读大约需要1分钟
  • 搜索引擎已收录

首页 / 📝教程 / 正文

AI摘要
Gemini 1.5 Pro
|
此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结
反馈

之前本站的音乐播放器使用的是APlayer插件,今天无意中发现一个只需加载JS,即可调用 APlayerMeting,不依赖插件和服务器计算存储,任意站点都可使用的来播放 网易云QQ 音乐酷狗虾米百度 以及 自定义的 单曲和歌单的方法,在此记录并分享给大家。

引入 JS

将代码加入到主题对应的 header.php 中的 </head> 标签前即可

  1. <script>
  2. // APlayer API
  3. document.addEventListener('DOMContentLoaded', initAplayer);
  4. window.aplayers = window.aplayers || [];
  5. function initAplayer(option) {
  6. const common = {
  7. loadResource: function (id, resource, type) {
  8. return new Promise(function (resolve, reject) {
  9. let loaded = document.head.querySelector('#' + id);
  10. if (loaded) {
  11. resolve('success: ' + resource);
  12. return;
  13. }
  14. const element = document.createElement(type);
  15. element.onload = element.onreadystatechange = () => {
  16. if (!loaded && (!element.readyState || /loaded|complete/.test(element.readyState))) {
  17. element.onload = element.onreadystatechange = null;
  18. loaded = true;
  19. resolve('success: ' + resource);
  20. }
  21. }
  22. element.onerror = function () {
  23. reject(Error(resource + ' load error!'));
  24. };
  25. if (type === 'link') {
  26. element.rel = 'stylesheet';
  27. element.href = resource;
  28. } else {
  29. element.src = resource;
  30. }
  31. element.id = id;
  32. document.getElementsByTagName('head')[0].appendChild(element);
  33. });
  34. },
  35. loadResources: function (callback) {
  36. const loadResource = this.loadResource;
  37. const pt = '//s0.pstatp.com/cdn/expire-1-M/';
  38. const jd = '//gcore.jsdelivr.net/npm/';
  39. const resources = [
  40. pt + 'aplayer/1.10.1/APlayer.min.css',
  41. pt + 'aplayer/1.10.1/APlayer.min.js',
  42. jd + 'meting@2/dist/Meting.min.js'
  43. ];
  44. const loadPromises = [];
  45. resources.forEach(resource => {
  46. loadPromises.push(loadResource(btoa(resource).replace(/[=+\/]/g, ''), resource,
  47. ({
  48. 'css': 'link',
  49. 'js': 'script'
  50. })[resource.split('.').pop()]
  51. ));
  52. });
  53. Promise.all(loadPromises).then(
  54. function () {
  55. if (typeof callback !== 'function') return;
  56. let flag = false;
  57. const waitAM = setInterval(() => {
  58. if (!flag
  59. && typeof APlayer === 'function'
  60. && typeof MetingJSElement === 'function') {
  61. flag = true;
  62. callback();
  63. clearInterval(waitAM);
  64. }
  65. }, 100);
  66. }
  67. );
  68. },
  69. createAplayers: function (sources) {
  70. for (let i = 0; i < sources.length; i++) {
  71. const child = document.createElement('div');
  72. sources[i].parentNode.insertBefore(child, sources[i]);
  73. sources[i].style.display = 'none';
  74. const songsTag = sources[i].querySelectorAll('s');
  75. const songs = [];
  76. songsTag.forEach(songTag => {
  77. const song = {};
  78. for (let i = 0; i < songTag.attributes.length; i++) {
  79. song[songTag.attributes[i].name] = songTag.attributes[i].value;
  80. }
  81. songs.push(song);
  82. });
  83. const options = { container: child, preload: 'none', autoplay: false, audio: songs };
  84. const optionMap = sources[i].attributes;
  85. for (let i = 0; i < optionMap.length; i++) {
  86. options[optionMap[i].name] = optionMap[i].value;
  87. }
  88. this.loadResources(() => window.aplayers.push(new APlayer(options)));
  89. }
  90. }
  91. };
  92. if (option == 'manual') return new Promise((resolve, reject) => {
  93. common.loadResources(() => resolve('success'));
  94. });
  95. const aps = document.querySelectorAll('ap');
  96. if (aps.length !== 0) common.createAplayers(aps);
  97. const mts = document.querySelectorAll('meting-js');
  98. if (!window.refreshing && mts.length !== 0) common.loadResources(
  99. function () {
  100. mts.forEach(mt => {
  101. if (!mt.aplayer) {
  102. const html = mt.outerHTML;
  103. mt.aplayer = { destroy: new Function(), list: { index: undefined } };
  104. mt.outerHTML = '\n' + html;
  105. }
  106. });
  107. document.querySelectorAll('meting-js').forEach(mt => {
  108. let flag = false;
  109. const waitMT = setInterval(() => {
  110. if (!flag && mt.aplayer) {
  111. flag = true;
  112. window.aplayers.push(mt.aplayer);
  113. console.log('replaced unloaded aplayer.')
  114. clearInterval(waitMT);
  115. }
  116. }, 300);
  117. });
  118. }
  119. );
  120. }
  121. </script>
  122. <script>
  123. // PJAX 相关 BUG
  124. document.addEventListener('DOMContentLoaded', function () {
  125. let flag = false;
  126. window.needReloadUrls = window.needReloadUrls || new Set();
  127. const jqueryWaitor = setInterval(() => {
  128. if (!flag && jQuery) {
  129. flag = true;
  130. $(document).on('pjax:start', function () {
  131. if (!window.refreshing || !window.pjaxStarted) {
  132. window.pjaxStarted = true;
  133. console.log('pjax:start');
  134. window.aplayers.forEach(ap => {
  135. ap.list.index = undefined;
  136. ap.destroy();
  137. });
  138. window.aplayers = [];
  139. setTimeout(() => window.pjaxStarted = false, 2000);
  140. }
  141. });
  142. $(document).on('pjax:end', function () {
  143. if (document.querySelector('meting-js')
  144. || document.querySelector('.collapse-block')
  145. || document.querySelector('#toggle-menu-tree')
  146. || document.querySelectorAll('.content-tab-title').length > 1
  147. ) {
  148. if (!window.needReloadUrls.has(location.href)) {
  149. window.needReloadUrls.add(location.href);
  150. console.log('captured a neededReloadUrl.');
  151. }
  152. }
  153. });
  154. $(document).on('pjax:popstate', function (event) {
  155. if (event.state && window.needReloadUrls.has(event.state.url) && !window.refreshing) {
  156. window.refreshing = true;
  157. console.log('back-forward handler.');
  158. $.pjax.reload({
  159. url: location.href,
  160. container: '#body',
  161. fragment: '#body',
  162. scrollTo: false,
  163. timeout: 8000
  164. });
  165. setTimeout(() => window.refreshing = false, 2000);
  166. }
  167. });
  168. clearInterval(jqueryWaitor);
  169. }
  170. }, 500);
  171. });
  172. </script>
复制代码

如果你开启了 PJAX,可能需要单独加入回调函数。将 initAplayer(); 添加进回调函数即可。

演示效果

网易云歌单

  1. !!!
  2. <!-- 引入方式 -->
  3. <meting-js auto="https://music.163.com/#/playlist?id=110459831"></meting-js>
  4. !!!
复制代码

QQ音乐歌单

  1. !!!
  2. <!-- 引入方式 -->
  3. <meting-js auto="https://y.qq.com/n/yqq/playlist/7355087593.html"></meting-js>
  4. !!!
复制代码

自定义歌单

  1. !!!
  2. <!-- 标签引入 -->
  3. <ap>
  4. <s
  5. name="rainymood"
  6. artist="rainymood"
  7. url="https://rainymood.com/audio1110/0.m4a"
  8. cover="https://rainymood.com/i/badge.jpg">
  9. </s>
  10. </ap>
  11. !!!
  12. !!!
  13. <!-- 或编程引入 -->
  14. <div id="ap"></div>
  15. <script>
  16. initAplayer('manual').then(() => {
  17. window.aplayers.push(new APlayer({
  18. container: document.querySelector('#ap'), preload: 'none', autoplay: false, audio: [
  19. {
  20. name="rainymood",
  21. artist="rainymood",
  22. url="https://rainymood.com/audio1110/0.m4a",
  23. cover="https://rainymood.com/i/badge.jpg"
  24. }
  25. ]
  26. }));
  27. });
  28. </script>
  29. !!!
复制代码

怎么样,效果还算不错吧,赶紧也给你添加一下啊。本文转载自任意站点引入 APlayer 和 Meting 的简单方法

 赞  赏

如果觉得我的文章对你有用,请随意打赏

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开  或者  扫一扫,即可进行扫码赞赏哦

本文经授权后发布,本文观点不代表立场,转载请联系原作者。
本文最后更新于2022年10月08日16时45分55秒,已超过953天没有更新,若内容或图片失效,请留言反馈
本文链接:https://niepan.org/archives/2206.html(转载时请注明本文出处及文章链接)
作品采用:《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权

发表评论

博主 - <?php $this->author->screenName(); ?>

love2wind

记录生活,分享世界