UNPKG

vue3-aplayer-2

Version:
1 lines 97.2 kB
{"version":3,"file":"vue-aplayer.cjs","sources":["../node_modules/.pnpm/smoothscroll@0.4.0/node_modules/smoothscroll/smoothscroll.js","../src/components/vue-aplayer/utils/utils.js","../src/components/vue-aplayer/assets/play.svg?component","../src/components/vue-aplayer/assets/pause.svg?component","../src/components/vue-aplayer/assets/volume-up.svg?component","../src/components/vue-aplayer/assets/volume-down.svg?component","../src/components/vue-aplayer/assets/volume-off.svg?component","../src/components/vue-aplayer/assets/order-random.svg?component","../src/components/vue-aplayer/assets/order-list.svg?component","../src/components/vue-aplayer/assets/menu.svg?component","../src/components/vue-aplayer/assets/loop-all.svg?component","../src/components/vue-aplayer/assets/loop-one.svg?component","../src/components/vue-aplayer/assets/loop-none.svg?component","../src/components/vue-aplayer/assets/loading.svg?component","../src/components/vue-aplayer/assets/right.svg?component","../src/components/vue-aplayer/assets/skip.svg?component","../src/components/vue-aplayer/assets/lrc.svg?component","../src/components/vue-aplayer/components/Icon.vue","../src/components/vue-aplayer/components/List.vue","../src/components/vue-aplayer/components/Lyric.vue","../src/components/vue-aplayer/components/Controller.vue","../src/components/vue-aplayer/APlayer.vue","../src/components/vue-aplayer/index.js"],"sourcesContent":["(function (root, smoothScroll) {\n 'use strict';\n\n // Support RequireJS and CommonJS/NodeJS module formats.\n // Attach smoothScroll to the `window` when executed as a <script>.\n\n // RequireJS\n if (typeof define === 'function' && define.amd) {\n define(smoothScroll);\n\n // CommonJS\n } else if (typeof exports === 'object' && typeof module === 'object') {\n module.exports = smoothScroll();\n\n } else {\n root.smoothScroll = smoothScroll();\n }\n\n})(this, function(){\n'use strict';\n\n// Do not initialize smoothScroll when running server side, handle it in client:\nif (typeof window !== 'object') return;\n\n// We do not want this script to be applied in browsers that do not support those\n// That means no smoothscroll on IE9 and below.\nif(document.querySelectorAll === void 0 || window.pageYOffset === void 0 || history.pushState === void 0) { return; }\n\n// Get the top position of an element in the document\nvar getTop = function(element, start) {\n // return value of html.getBoundingClientRect().top ... IE : 0, other browsers : -pageYOffset\n if(element.nodeName === 'HTML') return -start\n return element.getBoundingClientRect().top + start\n}\n// ease in out function thanks to:\n// http://blog.greweb.fr/2012/02/bezier-curve-based-easing-functions-from-concept-to-implementation/\nvar easeInOutCubic = function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1 }\n\n// calculate the scroll position we should be in\n// given the start and end point of the scroll\n// the time elapsed from the beginning of the scroll\n// and the total duration of the scroll (default 500ms)\nvar position = function(start, end, elapsed, duration) {\n if (elapsed > duration) return end;\n return start + (end - start) * easeInOutCubic(elapsed / duration); // <-- you can change the easing funtion there\n // return start + (end - start) * (elapsed / duration); // <-- this would give a linear scroll\n}\n\n// we use requestAnimationFrame to be called by the browser before every repaint\n// if the first argument is an element then scroll to the top of this element\n// if the first argument is numeric then scroll to this location\n// if the callback exist, it is called when the scrolling is finished\n// if context is set then scroll that element, else scroll window\nvar smoothScroll = function(el, duration, callback, context){\n duration = duration || 500;\n context = context || window;\n var start = context.scrollTop || window.pageYOffset;\n\n if (typeof el === 'number') {\n var end = parseInt(el);\n } else {\n var end = getTop(el, start);\n }\n\n var clock = Date.now();\n var requestAnimationFrame = window.requestAnimationFrame ||\n window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||\n function(fn){window.setTimeout(fn, 15);};\n\n var step = function(){\n var elapsed = Date.now() - clock;\n if (context !== window) {\n context.scrollTop = position(start, end, elapsed, duration);\n }\n else {\n window.scroll(0, position(start, end, elapsed, duration));\n }\n\n if (elapsed > duration) {\n if (typeof callback === 'function') {\n callback(el);\n }\n } else {\n requestAnimationFrame(step);\n }\n }\n step();\n}\n\nvar linkHandler = function(ev) {\n if (!ev.defaultPrevented) {\n ev.preventDefault();\n\n if (location.hash !== this.hash) window.history.pushState(null, null, this.hash)\n // using the history api to solve issue #1 - back doesn't work\n // most browser don't update :target when the history api is used:\n // THIS IS A BUG FROM THE BROWSERS.\n // change the scrolling duration in this call\n var node = document.getElementById(this.hash.substring(1))\n if (!node) return; // Do not scroll to non-existing node\n\n smoothScroll(node, 500, function (el) {\n location.replace('#' + el.id)\n // this will cause the :target to be activated.\n });\n }\n}\n\n// We look for all the internal links in the documents and attach the smoothscroll function\ndocument.addEventListener(\"DOMContentLoaded\", function () {\n var internal = document.querySelectorAll('a[href^=\"#\"]:not([href=\"#\"])'), a;\n for(var i=internal.length; a=internal[--i];){\n a.addEventListener(\"click\", linkHandler, false);\n }\n});\n\n// return smoothscroll API\nreturn smoothScroll;\n\n});\n","const isMobile = /mobile/i.test(window.navigator.userAgent);\n\nconst utils = {\n isMobile: isMobile,\n eventsName: {\n moveStart: isMobile ? 'touchstart' : 'mousedown',\n moving: isMobile ? 'touchmove' : 'mousemove',\n moveEnd: isMobile ? 'touchend' : 'mouseup',\n },\n storage: {\n set: (key, value) => {\n localStorage.setItem(key, value);\n },\n get: (key) => {\n localStorage.getItem(key);\n }\n },\n /**\n * Parse Second to Time String\n *\n * @param {Number} second\n * @return {String} 00:00 or 00:00:00\n */\n secondToTime: (second) => {\n const strMap = (num) => (num < 10 ? '0' + num : '' + num);\n const hour = Math.floor(second / 3600);\n const min = Math.floor((second - hour * 3600) / 60);\n const sec = Math.floor(second - hour * 3600 - min * 60);\n return (hour > 0 ? [hour, min, sec] : [min, sec]).map(strMap).join(':');\n },\n randomOrder: (length) => {\n function shuffle(arr) {\n for (let i = arr.length - 1; i >= 0; i--) {\n const randomIndex = Math.floor(Math.random() * (i + 1));\n const itemAtIndex = arr[randomIndex];\n arr[randomIndex] = arr[i];\n arr[i] = itemAtIndex;\n }\n return arr;\n }\n return shuffle(\n [...Array(length)].map(function(item, i) {\n return i;\n })\n );\n },\n /**\n * Parse Lyric String to Array\n * \n * @param {String} lyricStr \n * @return {Array} [[0, \"APlayer\"], [1.2, \"is\"], [34.56, \"Amazing\"]]\n */\n parse (lyricStr) {\n if (lyricStr) {\n lyricStr = lyricStr.replace(/([^\\]^\\n])\\[/g, (match, p) => p + '\\n[');\n let lyricArr = lyricStr.split('\\n');\n let lyricParseArr = [];\n for (let i = 0; i < lyricArr.length; i++) {\n // match lrc time\n const lrcTimes = lyricArr[i].match(/\\[(\\d{2}):(\\d{2})(\\.(\\d{2,3}))?]/g);\n // match lrc text\n const lrcText = lyricArr[i]\n .replace(/.*\\[(\\d{2}):(\\d{2})(\\.(\\d{2,3}))?]/g, '')\n .replace(/<(\\d{2}):(\\d{2})(\\.(\\d{2,3}))?>/g, '')\n .replace(/^\\s+|\\s+$/g, '');\n\n if (lrcTimes) {\n // handle multiple time tag\n for (let j = 0; j < lrcTimes.length; j++) {\n const oneTime = /\\[(\\d{2}):(\\d{2})(\\.(\\d{2,3}))?]/.exec(lrcTimes[j]);\n const min2sec = oneTime[1] * 60;\n const sec2sec = parseInt(oneTime[2]);\n const msec2sec = oneTime[4] ? parseInt(oneTime[4]) / ((oneTime[4] + '').length === 2 ? 100 : 1000) : 0;\n const lrcTime = min2sec + sec2sec + msec2sec;\n lyricParseArr.push([lrcTime, lrcText]);\n }\n }\n }\n // sort by time\n lyricParseArr = lyricParseArr.filter((item) => item[1]);\n lyricParseArr.sort((a, b) => a[0] - b[0]);\n\n return lyricParseArr;\n } else {\n return [];\n }\n },\n};\n\nexport default utils;","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 16 31\"\n}\nconst _hoisted_2 = /*#__PURE__*/_createElementVNode(\"path\", { d: \"M15.552 15.168q.448.32.448.832 0 .448-.448.768L1.856 25.28q-.768.512-1.312.192T0 24.192V7.744q0-.96.544-1.28t1.312.192z\" }, null, -1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, [..._hoisted_3]))\n}\nexport default { render: render }","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 17 32\"\n}\nconst _hoisted_2 = /*#__PURE__*/_createElementVNode(\"path\", { d: \"M14.08 4.8q2.88 0 2.88 2.048v18.24q0 2.112-2.88 2.112t-2.88-2.112V6.848q0-2.048 2.88-2.048m-11.2 0q2.88 0 2.88 2.048v18.24q0 2.112-2.88 2.112T0 25.088V6.848Q0 4.8 2.88 4.8\" }, null, -1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, [..._hoisted_3]))\n}\nexport default { render: render }","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 28 32\"\n}\nconst _hoisted_2 = /*#__PURE__*/_createElementVNode(\"path\", { d: \"M13.728 6.272v19.456q0 .448-.352.8t-.8.32-.8-.32l-5.952-5.952H1.152q-.48 0-.8-.352t-.352-.8v-6.848q0-.48.352-.8t.8-.352h4.672l5.952-5.952q.32-.32.8-.32t.8.32.352.8M20.576 16q0 1.344-.768 2.528t-2.016 1.664q-.16.096-.448.096-.448 0-.8-.32t-.32-.832q0-.384.192-.64t.544-.448.608-.384.512-.64.192-1.024-.192-1.024-.512-.64-.608-.384-.544-.448-.192-.64q0-.48.32-.832t.8-.32q.288 0 .448.096 1.248.48 2.016 1.664T20.576 16m4.576 0q0 2.72-1.536 5.056t-4 3.36q-.256.096-.448.096-.48 0-.832-.352t-.32-.8q0-.704.672-1.056 1.024-.512 1.376-.8 1.312-.96 2.048-2.4T22.848 16t-.736-3.104-2.048-2.4q-.352-.288-1.376-.8-.672-.352-.672-1.056 0-.448.32-.8t.8-.352q.224 0 .48.096 2.496 1.056 4 3.36T25.152 16m4.576 0q0 4.096-2.272 7.552t-6.048 5.056q-.224.096-.448.096-.48 0-.832-.352t-.32-.8q0-.64.704-1.056l.384-.192q.256-.128.416-.192.8-.448 1.44-.896 2.208-1.632 3.456-4.064T27.424 16t-1.216-5.152-3.456-4.064q-.64-.448-1.44-.896-.128-.096-.416-.192t-.384-.192q-.704-.416-.704-1.056 0-.448.32-.8t.832-.352q.224 0 .448.096 3.776 1.632 6.048 5.056T29.728 16\" }, null, -1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, [..._hoisted_3]))\n}\nexport default { render: render }","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 28 32\"\n}\nconst _hoisted_2 = /*#__PURE__*/_createElementVNode(\"path\", { d: \"M13.728 6.272v19.456q0 .448-.352.8t-.8.32-.8-.32l-5.952-5.952H1.152q-.48 0-.8-.352t-.352-.8v-6.848q0-.48.352-.8t.8-.352h4.672l5.952-5.952q.32-.32.8-.32t.8.32.352.8M20.576 16q0 1.344-.768 2.528t-2.016 1.664q-.16.096-.448.096-.448 0-.8-.32t-.32-.832q0-.384.192-.64t.544-.448.608-.384.512-.64.192-1.024-.192-1.024-.512-.64-.608-.384-.544-.448-.192-.64q0-.48.32-.832t.8-.32q.288 0 .448.096 1.248.48 2.016 1.664T20.576 16\" }, null, -1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, [..._hoisted_3]))\n}\nexport default { render: render }","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 28 32\"\n}\nconst _hoisted_2 = /*#__PURE__*/_createElementVNode(\"path\", { d: \"M13.728 6.272v19.456q0 .448-.352.8t-.8.32-.8-.32l-5.952-5.952H1.152q-.48 0-.8-.352t-.352-.8v-6.848q0-.48.352-.8t.8-.352h4.672l5.952-5.952q.32-.32.8-.32t.8.32.352.8\" }, null, -1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, [..._hoisted_3]))\n}\nexport default { render: render }","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 32 32\"\n}\nconst _hoisted_2 = /*#__PURE__*/_createElementVNode(\"path\", { d: \"m22.667 4 7 6-7 6 7 6-7 6v-4h-3.653l-3.76-3.76 2.827-2.827L20.668 20h2v-8h-2l-12 12h-6v-4h4.347l12-12h3.653V4zm-20 4h6l3.76 3.76L9.6 14.587 7.013 12H2.666z\" }, null, -1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, [..._hoisted_3]))\n}\nexport default { render: render }","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 32 32\"\n}\nconst _hoisted_2 = /*#__PURE__*/_createElementVNode(\"path\", { d: \"M.622 18.334h19.54v7.55l11.052-9.412-11.052-9.413v7.549H.622z\" }, null, -1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, [..._hoisted_3]))\n}\nexport default { render: render }","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 22 32\"\n}\nconst _hoisted_2 = /*#__PURE__*/_createElementVNode(\"path\", { d: \"M20.8 14.4q.704 0 1.152.48T22.4 16t-.48 1.12-1.12.48H1.6q-.64 0-1.12-.48T0 16t.448-1.12T1.6 14.4zM1.6 11.2q-.64 0-1.12-.48T0 9.6t.448-1.12T1.6 8h19.2q.704 0 1.152.48T22.4 9.6t-.48 1.12-1.12.48zm19.2 9.6q.704 0 1.152.48t.448 1.12-.48 1.12-1.12.48H1.6q-.64 0-1.12-.48T0 22.4t.448-1.12T1.6 20.8z\" }, null, -1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, [..._hoisted_3]))\n}\nexport default { render: render }","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 29 32\"\n}\nconst _hoisted_2 = /*#__PURE__*/_createElementVNode(\"path\", { d: \"M9.333 9.333h13.333v4L27.999 8l-5.333-5.333v4h-16v8h2.667zm13.334 13.334H9.334v-4L4.001 24l5.333 5.333v-4h16v-8h-2.667v5.333z\" }, null, -1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, [..._hoisted_3]))\n}\nexport default { render: render }","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 33 32\"\n}\nconst _hoisted_2 = /*#__PURE__*/_createElementVNode(\"path\", { d: \"M9.333 9.333h13.333v4L27.999 8l-5.333-5.333v4h-16v8h2.667zm13.334 13.334H9.334v-4L4.001 24l5.333 5.333v-4h16v-8h-2.667v5.333zM17.333 20v-8H16l-2.667 1.333v1.333h2v5.333z\" }, null, -1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, [..._hoisted_3]))\n}\nexport default { render: render }","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 29 32\"\n}\nconst _hoisted_2 = /*#__PURE__*/_createElementVNode(\"path\", { d: \"m2.667 7.027 1.707-1.693 22.293 22.293-1.693 1.707-4-4H9.334v4l-5.333-5.333 5.333-5.333v4h8.973l-8.973-8.973v.973H6.667v-3.64zm20 10.306h2.667v5.573l-2.667-2.667v-2.907zm0-10.666v-4L28 8l-5.333 5.333v-4H11.76L9.093 6.666z\" }, null, -1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, [..._hoisted_3]))\n}\nexport default { render: render }","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 32 32\"\n}\nconst _hoisted_2 = /*#__PURE__*/_createElementVNode(\"path\", { d: \"M4 16C4 9.4 9.4 4 16 4s12 5.4 12 12c0 1.2-.8 2-2 2s-2-.8-2-2c0-4.4-3.6-8-8-8s-8 3.6-8 8 3.6 8 8 8c1.2 0 2 .8 2 2s-.8 2-2 2C9.4 28 4 22.6 4 16\" }, null, -1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, [..._hoisted_3]))\n}\nexport default { render: render }","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 32 32\"\n}\nconst _hoisted_2 = /*#__PURE__*/_createElementVNode(\"path\", { d: \"M22 16 11.895 5.4 10 7.387 18.211 16 10 24.612l1.895 1.988 8.211-8.613z\" }, null, -1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, [..._hoisted_3]))\n}\nexport default { render: render }","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 32 32\"\n}\nconst _hoisted_2 = /*#__PURE__*/_createElementVNode(\"path\", { d: \"M25.468 6.947a1 1 0 0 0-1.03.057L18 11.384V7.831a1.001 1.001 0 0 0-1.562-.827l-12 8.164a1 1 0 0 0 0 1.654l12 8.168A.999.999 0 0 0 18 24.164v-3.556l6.438 4.382A.999.999 0 0 0 26 24.164V7.831c0-.371-.205-.71-.532-.884\" }, null, -1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, [..._hoisted_3]))\n}\nexport default { render: render }","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 32 32\"\n}\nconst _hoisted_2 = /*#__PURE__*/_createElementVNode(\"path\", { d: \"M26.667 5.333H5.333a2.667 2.667 0 0 0-2.666 2.666v16.002a2.667 2.667 0 0 0 2.666 2.666h21.335a2.667 2.667 0 0 0 2.666-2.666V7.999a2.667 2.667 0 0 0-2.666-2.666zM5.333 16h5.333v2.667H5.333zm13.334 8H5.334v-2.667h13.333zm8 0h-5.333v-2.667h5.333zm0-5.333H13.334V16h13.333z\" }, null, -1)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nexport function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, [..._hoisted_3]))\n}\nexport default { render: render }","<template>\n <component :is=\"icons[type]\"></component>\n</template>\n<script setup>\n import Play from \"../assets/play.svg?component\";\n import Pause from \"../assets/pause.svg?component\";\n import VolumeUp from \"../assets/volume-up.svg?component\";\n import VolumeDown from \"../assets/volume-down.svg?component\";\n import VolumeOff from \"../assets/volume-off.svg?component\";\n import OrderRandom from \"../assets/order-random.svg?component\";\n import OrderList from \"../assets/order-list.svg?component\";\n import Menu from \"../assets/menu.svg?component\";\n import LoopAll from \"../assets/loop-all.svg?component\";\n import LoopOne from \"../assets/loop-one.svg?component\";\n import LoopNone from \"../assets/loop-none.svg?component\";\n import Loading from \"../assets/loading.svg?component\";\n import Right from \"../assets/right.svg?component\";\n import Skip from \"../assets/skip.svg?component\";\n import Lrc from \"../assets/lrc.svg?component\";\n\n const props = defineProps({\n type: {\n type: String\n }\n });\n\n const icons = {\n \"play\" : Play,\n \"pause\" : Pause,\n \"volumeUp\" : VolumeUp,\n \"volumeDown\" : VolumeDown,\n \"volumeOff\" : VolumeOff,\n \"orderRandom\" : OrderRandom,\n \"orderList\" : OrderList,\n \"menu\" : Menu,\n \"loopAll\" : LoopAll,\n \"loopOne\" : LoopOne,\n \"loopNone\" : LoopNone,\n \"loading\" : Loading,\n \"right\" : Right,\n \"skip\" : Skip,\n \"lrc\" : Lrc,\n };\n</script>","<template>\n <div class=\"aplayer-list\" :class=\"{ 'aplayer-list-hide': !aplayer.listFolded }\" :style=\"{ 'max-height': `${aplayer.listMaxHeight}px` }\">\n <ol :style=\"{ 'max-height': `${aplayer.listMaxHeight}px` }\" ref=\"ol\">\n <li v-for=\"(audio, index) in aplayer.audio\" :class=\"{ 'aplayer-list-light': (index === aplayer.index) }\" @click=\"switchList(index)\">\n <span class=\"aplayer-list-cur\" :style=\"{ background: `${aplayer.coverColor[aplayer.index] || audio.theme || aplayer.theme}` }\"></span>\n <span class=\"aplayer-list-index\">{{ index + 1 }}</span>\n <span class=\"aplayer-list-title\">{{ audio.name }}</span>\n <span class=\"aplayer-list-author\">{{ audio.artist ? audio.artist : \"\" }}</span>\n </li>\n </ol>\n </div>\n</template>\n<script>\n export default {\n props: [\"aplayer\"],\n computed: {\n ol () {\n return this.$refs.ol;\n }\n },\n methods: {\n showList () {\n setTimeout(() => {\n this.ol.scrollTop = this.aplayer.index * 33;\n }, 0);\n },\n switchList (index) {\n if (index !== this.aplayer.index) {\n this.$emit(\"switchList\", index);\n this.$emit(\"play\");\n } else {\n this.$emit(\"toggle\");\n }\n }\n },\n }\n</script>","<template>\n <div class=\"aplayer-lrc\">\n <div class=\"aplayer-lrc-contents\" :style=\"transformStyle\">\n <p :class=\"{ 'aplayer-lrc-current': index === aplayer.lyricIndex }\" v-for=\"(lyric, index) in aplayer.lyrics[aplayer.index]\">{{ lyric[1] }}</p>\n </div>\n </div>\n</template>\n<script>\n export default {\n props: [\"aplayer\"],\n computed: {\n transformStyle () {\n //console.log('Lyric Offset:', this.aplayer.lyricOffset);\n return {\n transform: `translateY(-${this.aplayer.lyricIndex * this.aplayer.lyricOffset}px)`,\n webkitTransform: `translateY(-${this.aplayer.lyricIndex * this.aplayer.lyricOffset}px)`,\n }\n }\n }\n }\n</script>","<template>\n <div class=\"aplayer-controller\">\n <div class=\"aplayer-bar-wrap\" @mouseover=\"aplayerThumbShowStatus = true\" @mouseout=\"aplayerThumbShowStatus = false\">\n <div class=\"aplayer-bar\" ref=\"aplayerBar\">\n <div class=\"aplayer-loaded\" :style=\"{ width: `${audioStatus.duration ? audioStatus.loadedTime / audioStatus.duration * 100 : 0}%` }\"></div>\n <div class=\"aplayer-played\" :style=\"{ width: `${audioStatus.duration ? audioStatus.playedTime / audioStatus.duration * 100 : 0}%`, background: `${aplayer.coverColor[aplayer.index] || audio?.theme || aplayer.theme}` }\">\n <span class=\"aplayer-thumb\" :style=\"{ background: `${aplayer.coverColor[aplayer.index] || audio?.theme || aplayer.theme}` }\" v-show=\"aplayerThumbShowStatus\">\n <span class=\"aplayer-loading-icon\"><Icon type=\"loading\"></Icon></span>\n </span>\n </div>\n </div>\n </div>\n <div :class=\"{ 'aplayer-time': true, 'aplayer-time-narrow': styleStatus.timeNarrow }\">\n <span class=\"aplayer-time-inner\">\n <span class=\"aplayer-ptime\">{{ playedTime }}</span> / <span class=\"aplayer-dtime\">{{ duration }}</span>\n </span>\n <span class=\"aplayer-icon aplayer-icon-back\" @click=\"$emit('skipBack')\">\n <Icon type=\"skip\"></Icon>\n </span>\n <span class=\"aplayer-icon aplayer-icon-play\" @click=\"$emit('toggle')\">\n <Icon type=\"play\" v-show=\"!audioStatus.playStatus\"></Icon>\n <Icon type=\"pause\" v-show=\"audioStatus.playStatus\"></Icon>\n </span>\n <span class=\"aplayer-icon aplayer-icon-forward\" @click=\"$emit('skipForward')\">\n <Icon type=\"skip\"></Icon>\n </span>\n <div class=\"aplayer-volume-wrap\" :class=\"{ 'aplayer-volume-bar-wrap-active': volumeBarShowStatus }\">\n <button type=\"button\" class=\"aplayer-icon aplayer-icon-volume-down\" @click=\"$emit('mute')\">\n <Icon :type=\"switchVolumeIcon\"></Icon>\n </button>\n <div class=\"aplayer-volume-bar-wrap\">\n <div class=\"aplayer-volume-bar\" ref=\"volumeBar\">\n <div class=\"aplayer-volume\" :style=\"{ height: `${aplayer.muted ? 0 : aplayer.volume * 100}%`, background: `${aplayer.coverColor[aplayer.index] || audio?.theme || aplayer.theme}` }\"></div>\n </div>\n </div>\n </div>\n <button type=\"button\" class=\"aplayer-icon aplayer-icon-order\" @click=\"orderButtonClick\">\n <Icon type=\"orderList\" v-show=\"aplayer.order === 'list'\"></Icon>\n <Icon type=\"orderRandom\" v-show=\"aplayer.order === 'random'\"></Icon>\n </button>\n <button type=\"button\" class=\"aplayer-icon aplayer-icon-loop\" @click=\"loopButtonClick\">\n <Icon type=\"loopOne\" v-show=\"aplayer.loop === 'one'\"></Icon>\n <Icon type=\"loopAll\" v-show=\"aplayer.loop === 'all'\"></Icon>\n <Icon type=\"loopNone\" v-show=\"aplayer.loop === 'none'\"></Icon>\n </button>\n <button type=\"button\" class=\"aplayer-icon aplayer-icon-menu\" @click=\"$emit('toggleList')\">\n <Icon type=\"menu\"></Icon>\n </button>\n <button type=\"button\" :class=\"{ 'aplayer-icon': true, 'aplayer-icon-lrc': true, 'aplayer-icon-lrc-inactivity': !aplayer.lyricShow }\" @click=\"$emit('toggleLrc')\">\n <Icon type=\"lrc\"></Icon>\n </button>\n </div>\n </div>\n</template>\n<script>\n import utils from \"../utils/utils.js\";\n import Icon from \"./Icon.vue\";\n\n const loopArr = [\"one\", \"all\", \"none\"];\n const orderArr = [\"list\", \"random\"];\n\n export default {\n components: {\n utils,\n Icon,\n },\n props: [\"aplayer\", \"audioStatus\", \"styleStatus\"],\n data () {\n return {\n aplayerThumbShowStatus: false,\n volumeBarShowStatus: false,\n }\n },\n computed: {\n aplayerBar () {\n return this.$refs.aplayerBar;\n },\n volumeBar () {\n return this.$refs.volumeBar;\n },\n switchVolumeIcon () {\n if (this.aplayer.muted || this.aplayer.volume <= 0) return \"volumeOff\";\n if (this.aplayer.volume >= 0.95) return \"volumeUp\";\n return \"volumeDown\";\n },\n audio () {\n return this.aplayer.audio[this.aplayer.index];\n },\n duration () {\n return utils.secondToTime(this.audioStatus.duration);\n },\n playedTime: {\n get () {\n return utils.secondToTime(this.audioStatus.playedTime);\n },\n set (time) {\n this.$emit(\"playedTime\", time);\n }\n },\n disableTimeUpdate: {\n get () {\n return this.audioStatus.disableTimeUpdate;\n },\n set (status) {\n this.$emit(\"disableTimeUpdate\", status);\n },\n }\n },\n methods: {\n loopButtonClick () {\n let index = loopArr.indexOf(this.aplayer.loop);\n index = (index + 1) % loopArr.length;\n this.$emit(\"setLoop\", loopArr[index]);\n },\n orderButtonClick () {\n let index = orderArr.indexOf(this.aplayer.order);\n index = (index + 1) % orderArr.length;\n this.$emit(\"setOrder\", orderArr[index]);\n },\n\n aplayerBarMoving (e) {\n let percentage = ((e.clientX || e.changedTouches[0].clientX) - this.aplayerBar.getBoundingClientRect().left) / this.aplayerBar.clientWidth;\n percentage = Math.max(percentage, 0);\n percentage = Math.min(percentage, 1);\n this.playedTime = percentage * this.audioStatus.duration;\n this.$emit(\"updateLyric\");\n },\n aplayerBarMoveEnd (e) {\n document.removeEventListener(utils.eventsName.moveEnd, this.aplayerBarMoveEnd);\n document.removeEventListener(utils.eventsName.moving, this.aplayerBarMoving);\n let percentage = ((e.clientX || e.changedTouches[0].clientX) - this.aplayerBar.getBoundingClientRect().left) / this.aplayerBar.clientWidth;\n percentage = Math.max(percentage, 0);\n percentage = Math.min(percentage, 1);\n this.$emit(\"seek\", percentage * this.audioStatus.duration);\n this.disableTimeUpdate = false;\n },\n aplayerBarMoveStart () {\n this.disableTimeUpdate = true;\n document.addEventListener(utils.eventsName.moving, this.aplayerBarMoving);\n document.addEventListener(utils.eventsName.moveEnd, this.aplayerBarMoveEnd);\n },\n\n volumeBarMoving (e) {\n let percentage = 1 - ((e.clientY || e.changedTouches[0].clientY) - this.volumeBar.getBoundingClientRect().top) / this.volumeBar.clientHeight;\n percentage = Math.max(percentage, 0);\n percentage = Math.min(percentage, 1);\n this.$emit(\"setVolume\", percentage);\n },\n volumeBarMoveEnd (e) {\n this.volumeBarShowStatus = false;\n document.removeEventListener(utils.eventsName.moveEnd, this.volumeBarMoveEnd);\n document.removeEventListener(utils.eventsName.moving, this.volumeBarMoving);\n let percentage = 1 - ((e.clientY || e.changedTouches[0].clientY) - this.volumeBar.getBoundingClientRect().top) / this.volumeBar.clientHeight;\n percentage = Math.max(percentage, 0);\n percentage = Math.min(percentage, 1);\n this.$emit(\"setVolume\", percentage, true);\n },\n volumeBarMoveStart () {\n this.volumeBarShowStatus = true;\n document.addEventListener(utils.eventsName.moving, this.volumeBarMoving);\n document.addEventListener(utils.eventsName.moveEnd, this.volumeBarMoveEnd);\n },\n },\n mounted () {\n this.aplayerBar.parentNode.addEventListener(utils.eventsName.moveStart, this.aplayerBarMoveStart);\n this.volumeBar.parentNode.addEventListener(utils.eventsName.moveStart, this.volumeBarMoveStart);\n },\n beforeUnmount () {\n this.aplayerBar.parentNode.removeEventListener(utils.eventsName.moveStart, this.aplayerBarMoveStart);\n this.volumeBar.parentNode.removeEventListener(utils.eventsName.moveStart, this.volumeBarMoveStart);\n }\n }\n</script>","<template>\n <div class=\"aplayer\" v-if=\"!destroyComponent\" :class=\"{ 'aplayer-narrow': styleStatus.narrow, 'aplayer-fixed': aplayer.mode === 'fixed', 'aplayer-mini': (aplayer.mode === 'mini' || (aplayer.mode === 'fixed' && styleStatus.mini)), 'aplayer-loading': (audioStatus.playStatus && audioStatus.waitingStatus), 'aplayer-withlist': (aplayer.audio.length > 1), 'aplayer-withlrc': (aplayer.mode === 'normal' && aplayer.lyricShow), 'aplayer-mobile': styleStatus.isMobile }\" ref=\"aplayer\">\n <List v-if=\"aplayer.mode === 'fixed'\" :aplayer=\"aplayer\" @play=\"play\" @toggle=\"toggle\" @switchList=\"switchList\" ref=\"list\" />\n <div class=\"aplayer-body\" :style=\"{ width: `${aplayer.mode === 'fixed' ? 'calc(100% - 18px)' : '100%'}` }\">\n <div class=\"aplayer-pic\" :style=\"coverStyle\" @click=\"toggle\">\n <div class=\"aplayer-button\" :class=\"{ 'aplayer-play': !audioStatus.playStatus, 'aplayer-pause': audioStatus.playStatus }\">\n <div ref=\"switch\">\n <Icon type=\"play\" v-show=\"!audioStatus.playStatus\"></Icon>\n <Icon type=\"pause\" v-show=\"audioStatus.playStatus\"></Icon>\n </div>\n </div>\n </div>\n <div class=\"aplayer-info\" ref=\"info\">\n <div class=\"aplayer-music\">\n <span class=\"aplayer-title\">{{ aplayer.audio[aplayer.index] ? aplayer.audio[aplayer.index].name : \"No Audio\" }}</span>\n <span class=\"aplayer-author\">{{ aplayer.audio[aplayer.index] ? \" - \" + aplayer.audio[aplayer.index].artist : \"\" }}</span>\n </div>\n <Lyric v-if=\"aplayer.mode === 'normal'\" v-show=\"aplayer.lyricShow\" :aplayer=\"aplayer\" ref=\"lyric\" />\n <Controller :aplayer=\"aplayer\" :audioStatus=\"audioStatus\" :styleStatus=\"styleStatus\" @playedTime=\"playedTime\" @disableTimeUpdate=\"disableTimeUpdate\" @toggle=\"toggle\" @skipBack=\"skipBack\" @skipForward=\"skipForward\" @seek=\"seek\" @mute=\"mute\" @setLoop=\"setLoop\" @setOrder=\"setOrder\" @toggleList=\"toggleList\" @toggleLrc=\"toggleLrc\" @setVolume=\"setVolume\" />\n </div>\n <div class=\"aplayer-notice\" :style=\"{ opacity: aplayer.noticeOpacity }\">{{ aplayer.noticeText }}</div>\n <div class=\"aplayer-miniswitcher\" @click=\"styleStatus.mini = !styleStatus.mini\">\n <button class=\"aplayer-icon\">\n <Icon type=\"right\"></Icon>\n </button>\n </div>\n </div>\n <List v-if=\"aplayer.mode === 'normal'\" :aplayer=\"aplayer\" @play=\"play\" @toggle=\"toggle\" @switchList=\"switchList\" ref=\"list\" />\n <Lyric v-if=\"aplayer.mode === 'fixed'\" v-show=\"aplayer.lyricShow\" :aplayer=\"aplayer\" ref=\"lyric\" />\n <audio ref=\"audio\"></audio>\n </div>\n</template>\n<script>\n import smoothScroll from \"smoothScroll\";\n import utils from \"./utils/utils.js\";\n import Icon from \"./components/Icon.vue\";\n import List from \"./components/List.vue\";\n import Lyric from \"./components/Lyric.vue\";\n import Controller from \"./components/Controller.vue\";\n\n let activeMutexInstance = null;\n\n const mediaEvents = [\n \"abort\",\n \"canplay\", \"canplaythrough\",\n \"durationchange\",\n \"emptied\", \"encrypted\", \"ended\", \"error\",\n \"interruptbegin\", \"interruptend\",\n \"loadeddata\", \"loadedmetadata\", \"loadstart\",\n \"mozaudioavailable\",\n \"pause\", \"play\", \"playing\", \"progress\",\n \"ratechange\",\n \"seeked\", \"seeking\", \"stalled\", \"suspend\",\n \"timeupdate\",\n \"volumechange\",\n \"waiting\",\n ];\n\n const aplayer = {\n name: \"APlayer\",\n components: {\n smoothScroll,\n utils,\n Icon,\n List,\n Lyric,\n Controller,\n },\n props: {\n audio: {\n type: Array,\n default: [],\n },\n mode: {\n type: String,\n default: \"normal\", // \"normal\", \"fixed\", \"mini\"\n },\n autoplay: {\n type: Boolean,\n default: false,\n },\n mutex: {\n type: Boolean,\n default: true,\n },\n preload: {\n type: String,\n default: \"metadata\", // \"auto\", \"metadata\", \"none\"\n },\n theme: {\n type: String,\n default: \"#B7DAFF\",\n },\n autoSwitch: {\n type: Boolean,\n default: true,\n },\n loop: {\n type: String,\n default: \"all\", // \"one\", \"all\", \"none\" \n },\n order: {\n type: String,\n default: \"list\", // \"list\", \"random\"\n },\n muted: {\n type: Boolean,\n default: false,\n },\n volume: {\n type: Number,\n default: 0.7,\n validator (value) {\n return value >= 0 && value <= 1;\n },\n },\n lrcType: {\n type: Number,\n default: 1,\n },\n lrcShow: {\n type: Boolean,\n default: true,\n },\n lyricOffset: {\n type: Number,\n default: 16,\n },\n listFolded: {\n type: Boolean,\n default: false,\n },\n listMaxHeight: {\n type: Number,\n default: 250,\n },\n noticeSwitch: {\n type: Boolean,\n default: true,\n },\n storageName: {\n type: String,\n default: \"aplayer-setting\",\n }\n },\n data () {\n return {\n aplayer: {\n index: 0,\n audio: [],\n randomOrder: [],\n mode: this.mode,\n autoplay: this.autoplay,\n mutex: this.mutex,\n preload: this.preload,\n theme: this.theme,\n autoSwitch: this.autoSwitch,\n coverColor: [],\n loop: this.loop,\n order: this.order,\n muted: this.muted,\n volume: this.volume,\n lyricType: this.lrcType,\n lyricShow: this.lrcShow,\n lyricIndex: 0,\n lyrics: [],\n lyricOffset: this.lyricOffset,\n listFolded: this.listFolded,\n listMaxHeight: this.listMaxHeight,\n noticeSwitch: this.noticeSwitch,\n noticeText: \"\",\n noticeOpacity: 0,\n storageName: this.storageName,\n storage: {},\n },\n audioStatus: {\n duration: 0,\n loadedTime: 0,\n playedTime: 0,\n playStatus: false,\n waitingStatus: false,\n disableTimeUpdate: false,\n },\n styleStatus: {\n isMobile: /mobile/i.test(window.navigator.userAgent),\n narrow: false,\n timeNarrow: false,\n mini: true,\n },\n destroyComponent: false,\n }\n },\n computed: {\n audioRef () {\n return this.$refs.audio;\n },\n coverStyle () {\n let audio = this.aplayer.audio[this.aplayer.index];\n if (!audio?.cover) {\n return {\n \"background-color\": `${this.aplayer.coverColor[this.aplayer.index] || audio?.theme || this.aplayer.theme}`\n }\n }\n return {\n \"background-image\": `url(${audio.cover})`,\n \"background-color\": `${this.aplayer.coverColor[this.aplayer.index] || audio?.theme || this.aplayer.theme}`\n }\n },\n },\n methods: {\n // internal methods\n getStorage (key) {\n return this.aplayer.storage[key];\n },\n setStorage (key, value) {\n this.aplayer.storage[key] = value;\n localStorage.setItem(this.aplayer.storageName, JSON.stringify(this.aplayer.storage));\n },\n setAudio (audio) {\n if (this.hls) {\n this.hls.destroy();\n this.hls = null;\n }\n let type = audio.type;\n if (!type || type === \"auto\") {\n type = (/m3u8(#|\\?|$)/i.exec(audio.url)) ? \"hls\" : \"normal\";\n }\n if (type === \"hls\") {\n if (Hls.isSupported()) {\n this.hls = new Hls();\n this.hls.loadSource(audio.url);\n this.hls.attachMedia(this.audioRef);\n } else if (this.audioRef.canPlayType(\"application/x-mpegURL\") || this.audioRef.canPlayType(\"application/vnd.apple.mpegURL\")) {\n this.audioRef.src = audio.url;\n } else {\n this.setNotice(\"Error: HLS is not supported.\");\n }\n } else if (type === \"normal\") {\n this.audioRef.src = audio.url;\n }\n },\n prevIndex () {\n let index = this.aplayer.index;\n if (this.aplayer.audio.length > 1) {\n if (this.aplayer.order === \"list\") {\n return index - 1 < 0 ? this.aplayer.audio.length - 1 : index - 1;\n } else if (this.aplayer.order === \"random\") {\n let randomIndex = this.aplayer.randomOrder.indexOf(index);\n if (randomIndex === 0) {\n return this.aplayer.randomOrder[this.aplayer.randomOrder.length - 1];\n } else {\n return this.aplayer.randomOrder[randomIndex - 1];\n }\n }\n } else {\n return 0;\n }\n },\n nextIndex () {\n let index = this.aplayer.index;\n if (this.aplayer.audio.length > 1) {\n if (this.aplayer.order === \"list\") {\n return (index + 1) % this.aplayer.audio.length;\n } else if (this.aplayer.order === \"random\") {\n let randomIndex = this.aplayer.randomOrder.indexOf(index);\n if (randomIndex === this.aplayer.randomOrder.length - 1) {\n return this.aplayer.randomOrder[0];\n } else {\n return this.aplayer.randomOrder[randomIndex + 1];\n }\n }\n } else {\n return 0;\n }\n },\n coverColor () {\n let isEmpty = !this.aplayer.coverColor[this.aplayer.index];\n if (this.aplayer.autoSwitch && isEmpty) {\n try {\n if (!this.colorThief) {\n this.colorThief = new ColorThief();\n }\n this.colorThief.getColorAsync(this.aplayer.audio[this.aplayer.index]?.cover, ([red, green, blue]) => this.aplayer.coverColor[this.aplayer.index] = `rgb(${red}, ${green}, ${blue})`);\n } catch (e) {\n this.aplayer.autoSwitch = false;\n this.setNotice(\"The color-thief is required to support self-adapting theme.\");\n }\n }\n },\n switchStyle () {\n if (this.$refs.switch) {\n this.$refs.switch.style.display = \"none\";\n setTimeout(() => {\n if (this.$refs.switch) {\n this.$refs.switch.style.display = \"block\";\n }\n }, 100);\n }\n },\n loadedTime () {\n return this.audioRef.buffered.length ? this.audioRef.buffered.end(this.audioRef.buffered.length - 1) : 0;\n },\n playedTime (time) {\n this.audioStatus.playedTime = time;\n },\n disableTimeUpdate (status) {\n this.audioStatus.disableTimeUpdate = status;\n },\n async loadLyric (lrc, index) {\n try {\n let response = await fetch(this.aplayer.audio[index].lrc);\n if (response.ok || response.status === 304) {\n lrc = utils.parse(await response.text());\n } else {\n this.setNotice(\"LRC file request fails: status \" + response.status);\n } \n } catch (e) {\n console.warn(e);\n } finally {\n this.aplayer.lyrics[index] = lrc;\n this.updateLyric();\n }\n },\n switchLyric (index) {\n if (this.aplayer.lyrics[index]) {\n return ;\n }\n let lrc = [[0, \"Not available\"]];\n if (this.aplayer.lyricType === 1) {\n // async\n this.aplayer.lyrics[index] = [[0, \"Loading\"]];\n this.loadLyric(lrc, index);\n } else if (this.aplayer.lyricType === 2) {\n // sync\n if (this.aplayer.audio[index].lrc) {\n lrc = utils.parse(this.aplayer.audio[index].lrc);\n }\n this.aplayer.lyrics[index] = lrc;\n this.updateLyric();\n }\n },\n updateLyric () {\n let lyric = this.aplayer.lyrics[this.aplayer.index];\n if (lyric) {\n for (let i = 0; i < lyric.length; i++) {\n const current = lyric[i];\n const next = lyric[i + 1];\n if (this.audioStatus.playedTime >= current[0] && (!next || this.audioStatus.playedTime < next[0])) {\n this.aplayer.lyricIndex = i;\n }\n }\n }\n },\n // expose methods\n init () {\n this.destroyComponent = false;\n\n // load localstorage data\n this.aplayer.storage = JSON.parse(localStorage.getItem(this.aplayer.storageName)) || {};\n this.aplayer.volume = this.getStorage(\"volume\") || this.aplayer.volume;\n\n // set audio\n this.audioRef.preload = this.aplayer.preload;\n this.audioRef.muted = this.aplayer.muted;\n this.audioRef.volume = this.aplayer.volume;\n\n //