chore: update workflow
This commit is contained in:
parent
6f4cece562
commit
8ff2095ff6
|
|
@ -0,0 +1,3 @@
|
|||
dist
|
||||
demo
|
||||
docs
|
||||
30
.eslintrc
30
.eslintrc
|
|
@ -1,15 +1,16 @@
|
|||
{
|
||||
"extends": "eslint:recommended",
|
||||
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
|
||||
"plugins": ["prettier"],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"ecmaVersion": 2018,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"env": {
|
||||
"browser": true
|
||||
"es6": true,
|
||||
"browser": true,
|
||||
"node": true,
|
||||
},
|
||||
"rules": {
|
||||
"no-console": 0,
|
||||
"no-extra-parens": 1,
|
||||
"block-scoped-var": 1,
|
||||
"curly": 1,
|
||||
"eqeqeq": 1,
|
||||
|
|
@ -20,10 +21,8 @@
|
|||
"comma-spacing": 1,
|
||||
"comma-style": 1,
|
||||
"func-call-spacing": 1,
|
||||
"indent": 1,
|
||||
"keyword-spacing": 1,
|
||||
"linebreak-style": 1,
|
||||
"lines-around-comment": 1,
|
||||
"no-multiple-empty-lines": 1,
|
||||
"space-infix-ops": 1,
|
||||
"arrow-spacing": 1,
|
||||
|
|
@ -31,14 +30,12 @@
|
|||
"prefer-const": 1,
|
||||
"no-unsafe-negation": 1,
|
||||
"array-callback-return": 1,
|
||||
"dot-location": 1,
|
||||
"dot-notation": 1,
|
||||
"no-eval": 1,
|
||||
"no-extend-native": 1,
|
||||
"no-extra-label": 1,
|
||||
"semi": 1,
|
||||
"space-before-blocks": 1,
|
||||
"space-before-function-paren": 1,
|
||||
"space-in-parens": 1,
|
||||
"space-unary-ops": 1,
|
||||
"spaced-comment": 1,
|
||||
|
|
@ -50,13 +47,10 @@
|
|||
"no-useless-rename": 1,
|
||||
"rest-spread-spacing": 1,
|
||||
"no-trailing-spaces": 1,
|
||||
"quotes": [1, "single"]
|
||||
},
|
||||
"globals": {
|
||||
"require": false,
|
||||
"module": false,
|
||||
"Hls": false,
|
||||
"flvjs": false,
|
||||
"dashjs": false
|
||||
"no-control-regex": 0,
|
||||
"prettier/prettier": 0,
|
||||
"no-await-in-loop": 1,
|
||||
"require-atomic-updates": 0,
|
||||
"no-prototype-builtins": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
If you want to report a bug, please provide the following information:
|
||||
|
||||
- The steps to reproduce.
|
||||
- A minimal demo of the problem via https://jsfiddle.net or http://codepen.io/pen if possible.
|
||||
- Which versions of APlayer, and which browser / OS are affected by this issue?
|
||||
- The steps to reproduce.
|
||||
- A minimal demo of the problem via https://jsfiddle.net or http://codepen.io/pen if possible.
|
||||
- Which versions of APlayer, and which browser / OS are affected by this issue?
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
dist
|
||||
demo
|
||||
docs
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"printWidth": 233,
|
||||
"tabWidth": 4,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "always"
|
||||
}
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
language: node_js
|
||||
|
||||
node_js:
|
||||
- "node"
|
||||
- lts/*
|
||||
|
||||
script:
|
||||
- npm run build
|
||||
|
||||
cache:
|
||||
yarn: true
|
||||
|
|
|
|||
75
README.md
75
README.md
|
|
@ -21,13 +21,8 @@ APlayer is a lovely HTML5 music player.
|
|||
|
||||
**APlayer supports:**
|
||||
|
||||
- Media formats
|
||||
- MP4 H.264 (AAC or MP3)
|
||||
- WAVE PCM
|
||||
- Ogg Theora Vorbis
|
||||
- Features
|
||||
- Playlist
|
||||
- Lyrics
|
||||
- Media formats - MP4 H.264 (AAC or MP3) - WAVE PCM - Ogg Theora Vorbis
|
||||
- Features - Playlist - Lyrics
|
||||
|
||||
Using APlayer on your project? [Let me know!](https://github.com/MoePlayer/APlayer/issues/79)
|
||||
|
||||
|
|
@ -37,44 +32,44 @@ Using APlayer on your project? [Let me know!](https://github.com/MoePlayer/APlay
|
|||
|
||||
## Join the Discussion
|
||||
|
||||
- [Telegram Group](https://t.me/adplayer)
|
||||
- [QQ Group](https://shang.qq.com/wpa/qunwpa?idkey=bf22213ae0028a82e5adf3f286dfd4f01e0997dc9f1dcd8e831a0a85e799be17): 415835947
|
||||
- [Telegram Group](https://t.me/adplayer)
|
||||
- [QQ Group](https://shang.qq.com/wpa/qunwpa?idkey=bf22213ae0028a82e5adf3f286dfd4f01e0997dc9f1dcd8e831a0a85e799be17): 415835947
|
||||
|
||||
## Related Projects
|
||||
|
||||
### Plugins
|
||||
|
||||
- [APlayer-Typecho-Plugin](https://github.com/zgq354/APlayer-Typecho-Plugin): Typecho
|
||||
- [hexo-tag-aplayer](https://github.com/grzhan/hexo-tag-aplayer): Hexo
|
||||
- [Hermit-X(APlayer for WordPress)](https://github.com/liwanglin12/Hermit-X): WordPress
|
||||
- [APlayerHandle](https://github.com/kn007/APlayerHandle): WordPress
|
||||
- [APlayer_for_Z-BlogPHP](https://github.com/fghrsh/APlayer_for_Z-BlogPHP): Z-BlogPHP
|
||||
- [react-aplayer](https://github.com/sabrinaluo/react-aplayer): React
|
||||
- [Vue-APlayer](https://github.com/SevenOutman/vue-aplayer): Vue
|
||||
- [vue-aplayer](https://github.com/MoeFE/vue-aplayer): Vue
|
||||
- [php-aplayer](https://github.com/Daryl-L/php-aplayer): PHP
|
||||
- [APlayer-Typecho-Plugin](https://github.com/zgq354/APlayer-Typecho-Plugin): Typecho
|
||||
- [hexo-tag-aplayer](https://github.com/grzhan/hexo-tag-aplayer): Hexo
|
||||
- [Hermit-X(APlayer for WordPress)](https://github.com/liwanglin12/Hermit-X): WordPress
|
||||
- [APlayerHandle](https://github.com/kn007/APlayerHandle): WordPress
|
||||
- [APlayer_for_Z-BlogPHP](https://github.com/fghrsh/APlayer_for_Z-BlogPHP): Z-BlogPHP
|
||||
- [react-aplayer](https://github.com/sabrinaluo/react-aplayer): React
|
||||
- [Vue-APlayer](https://github.com/SevenOutman/vue-aplayer): Vue
|
||||
- [vue-aplayer](https://github.com/MoeFE/vue-aplayer): Vue
|
||||
- [php-aplayer](https://github.com/Daryl-L/php-aplayer): PHP
|
||||
|
||||
### Tooling
|
||||
|
||||
- [APlayer-Controler](https://github.com/Mashiro-Sorata/APlayer-Controler): controling tool
|
||||
- [MetingJS](https://github.com/metowolf/MetingJS): work with Meting music API
|
||||
- Feel free to submit yours in [`Let me know!`](https://github.com/MoePlayer/APlayer/issues/79)
|
||||
- [APlayer-Controler](https://github.com/Mashiro-Sorata/APlayer-Controler): controling tool
|
||||
- [MetingJS](https://github.com/metowolf/MetingJS): work with Meting music API
|
||||
- Feel free to submit yours in [`Let me know!`](https://github.com/MoePlayer/APlayer/issues/79)
|
||||
|
||||
## Who use APlayer?
|
||||
|
||||
- [bilibili](https://www.bilibili.com/): 国内知名的视频弹幕网站
|
||||
- [黑客派](https://hacpai.com/): 程序员和设计师的聚集地,一个活跃的小众社区
|
||||
- [浙江大学CC98论坛](https://zh.wikipedia.org/wiki/CC98%E8%AE%BA%E5%9D%9B): 浙江大学校网内规模最大的论坛,中国各大学中较活跃的BBS之一
|
||||
- [Jelly Rue](http://jellyrue.com/): Jelly Rue, an indie pop-rock band from Tartu.
|
||||
- [Opus](http://www.opusopus.co/): An artist-exploration data visualization application
|
||||
- [站长之家](http://www.chinaz.com/15year/index.html): 针对中文站点提供资讯、技术、资源、服务
|
||||
- [LLSupport](https://www.lovelivesupport.com/): This site provides a lot of information about LoveLive
|
||||
- [歌词千寻](https://www.lrcgc.com/diy): 每日更新的LRC歌词网站
|
||||
- [iSearch](http://i.oppsu.cn): 一个提供 iTunes 搜索,试听,高清专辑封面获取,查看最新音乐动态等综合性平台
|
||||
- [LRC歌词编辑器](https://github.com/MoeFE/Lyric): 一款非常实用的在线LRC歌词编辑器
|
||||
- [Аэростатика](https://aerostatica.ru/)
|
||||
- [HealthDig](https://healthdig.co): 每天只需两分钟的重点新闻资讯
|
||||
- Feel free to submit yours in [`Let me know!`](https://github.com/MoePlayer/APlayer/issues/79)
|
||||
- [bilibili](https://www.bilibili.com/): 国内知名的视频弹幕网站
|
||||
- [黑客派](https://hacpai.com/): 程序员和设计师的聚集地,一个活跃的小众社区
|
||||
- [浙江大学 CC98 论坛](https://zh.wikipedia.org/wiki/CC98%E8%AE%BA%E5%9D%9B): 浙江大学校网内规模最大的论坛,中国各大学中较活跃的 BBS 之一
|
||||
- [Jelly Rue](http://jellyrue.com/): Jelly Rue, an indie pop-rock band from Tartu.
|
||||
- [Opus](http://www.opusopus.co/): An artist-exploration data visualization application
|
||||
- [站长之家](http://www.chinaz.com/15year/index.html): 针对中文站点提供资讯、技术、资源、服务
|
||||
- [LLSupport](https://www.lovelivesupport.com/): This site provides a lot of information about LoveLive
|
||||
- [歌词千寻](https://www.lrcgc.com/diy): 每日更新的 LRC 歌词网站
|
||||
- [iSearch](http://i.oppsu.cn): 一个提供 iTunes 搜索,试听,高清专辑封面获取,查看最新音乐动态等综合性平台
|
||||
- [LRC 歌词编辑器](https://github.com/MoeFE/Lyric): 一款非常实用的在线 LRC 歌词编辑器
|
||||
- [Аэростатика](https://aerostatica.ru/)
|
||||
- [HealthDig](https://healthdig.co): 每天只需两分钟的重点新闻资讯
|
||||
- Feel free to submit yours in [`Let me know!`](https://github.com/MoePlayer/APlayer/issues/79)
|
||||
|
||||
## Current Premium Sponsors
|
||||
|
||||
|
|
@ -105,17 +100,17 @@ APlayer is an MIT licensed open source project and completely free to use. Howev
|
|||
|
||||
We accept donations through these channels:
|
||||
|
||||
- [Paypal](https://www.paypal.me/DIYgod)
|
||||
- [WeChat Pay](https://i.imgur.com/aq6PtWa.png)
|
||||
- [Alipay](https://i.imgur.com/wv1Pj2k.png)
|
||||
- Bitcoin: 13CwQLHzPYm2tewNMSJBeArbbRM5NSmCD1
|
||||
- [Paypal](https://www.paypal.me/DIYgod)
|
||||
- [WeChat Pay](https://i.imgur.com/aq6PtWa.png)
|
||||
- [Alipay](https://i.imgur.com/wv1Pj2k.png)
|
||||
- Bitcoin: 13CwQLHzPYm2tewNMSJBeArbbRM5NSmCD1
|
||||
|
||||
## Recurring Pledges
|
||||
|
||||
Recurring pledges come with exclusive perks, e.g. having your name or your company logo listed in the APlayer GitHub repository and this website.
|
||||
|
||||
- Become a backer or sponsor via [OpenCollective](https://opencollective.com/aplayer)
|
||||
- E-mail us: i#html.love
|
||||
- Become a backer or sponsor via [OpenCollective](https://opencollective.com/aplayer)
|
||||
- E-mail us: i#html.love
|
||||
|
||||
## Author
|
||||
|
||||
|
|
|
|||
136
package.json
136
package.json
|
|
@ -1,60 +1,80 @@
|
|||
{
|
||||
"name": "aplayer",
|
||||
"version": "1.10.1",
|
||||
"description": "Wow, such a beautiful html5 music player",
|
||||
"main": "dist/APlayer.min.js",
|
||||
"style": "dist/APlayer.min.css",
|
||||
"scripts": {
|
||||
"start": "npm run dev",
|
||||
"build": "cross-env NODE_ENV=production webpack --config webpack/prod.config.js --progress --display-error-details --colors",
|
||||
"dev": "cross-env NODE_ENV=development webpack-dev-server --config webpack/dev.config.js --watch --colors",
|
||||
"test": "eslint src webpack"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"repository": {
|
||||
"url": "git+https://github.com/DIYgod/APlayer.git",
|
||||
"type": "git"
|
||||
},
|
||||
"keywords": [
|
||||
"player",
|
||||
"music",
|
||||
"html5"
|
||||
],
|
||||
"author": "DIYgod",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/DIYgod/APlayer/issues"
|
||||
},
|
||||
"homepage": "https://github.com/DIYgod/APlayer#readme",
|
||||
"devDependencies": {
|
||||
"art-template": "4.12.2",
|
||||
"art-template-loader": "1.4.3",
|
||||
"autoprefixer": "^8.6.2",
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-loader": "^7.1.4",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"cross-env": "^5.2.0",
|
||||
"css-loader": "^0.28.11",
|
||||
"eslint": "^4.19.1",
|
||||
"eslint-loader": "^2.0.0",
|
||||
"git-revision-webpack-plugin": "^3.0.3",
|
||||
"mini-css-extract-plugin": "0.4.0",
|
||||
"node-sass": "^4.9.0",
|
||||
"postcss-loader": "^2.1.5",
|
||||
"sass-loader": "^7.0.3",
|
||||
"style-loader": "^0.21.0",
|
||||
"svg-inline-loader": "0.8.0",
|
||||
"template-string-optimize-loader": "^2.2.3",
|
||||
"url-loader": "^1.0.1",
|
||||
"webpack": "^4.12.0",
|
||||
"webpack-cli": "3.0.6",
|
||||
"webpack-dev-server": "^3.1.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"balloon-css": "^0.5.0",
|
||||
"promise-polyfill": "8.0.0",
|
||||
"smoothscroll": "0.4.0"
|
||||
}
|
||||
"name": "aplayer",
|
||||
"version": "1.10.1",
|
||||
"description": "Wow, such a beautiful html5 music player",
|
||||
"main": "dist/APlayer.min.js",
|
||||
"style": "dist/APlayer.min.css",
|
||||
"scripts": {
|
||||
"start": "npm run dev",
|
||||
"build": "cross-env NODE_ENV=production webpack --config webpack/prod.config.js --progress --display-error-details --colors",
|
||||
"dev": "cross-env NODE_ENV=development webpack-dev-server --config webpack/dev.config.js --watch --colors",
|
||||
"test": "eslint src webpack",
|
||||
"format": "eslint \"**/*.js\" --fix && prettier \"**/*.{js,json,md}\" --write",
|
||||
"format:staged": "eslint \"**/*.js\" --fix && pretty-quick --staged --verbose --pattern \"**/*.{js,json,md}\"",
|
||||
"format:check": "eslint \"**/*.js\" && prettier-check \"**/*.{js,json,md}\""
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"repository": {
|
||||
"url": "git+https://github.com/DIYgod/APlayer.git",
|
||||
"type": "git"
|
||||
},
|
||||
"keywords": [
|
||||
"player",
|
||||
"music",
|
||||
"html5"
|
||||
],
|
||||
"gitHooks": {
|
||||
"pre-commit": "npm run format:staged"
|
||||
},
|
||||
"author": "DIYgod",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/DIYgod/APlayer/issues"
|
||||
},
|
||||
"homepage": "https://github.com/DIYgod/APlayer#readme",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.6.0",
|
||||
"@babel/preset-env": "^7.4.5",
|
||||
"@vuepress/plugin-back-to-top": "1.1.0",
|
||||
"@vuepress/plugin-google-analytics": "1.1.0",
|
||||
"@vuepress/plugin-pwa": "1.1.0",
|
||||
"art-template": "4.13.2",
|
||||
"art-template-loader": "1.4.3",
|
||||
"autoprefixer": "^9.6.1",
|
||||
"babel-loader": "^8.0.6",
|
||||
"cross-env": "^6.0.0",
|
||||
"css-loader": "^3.2.0",
|
||||
"cssnano": "^4.1.10",
|
||||
"eslint": "^6.4.0",
|
||||
"eslint-config-prettier": "^6.3.0",
|
||||
"eslint-loader": "^3.0.0",
|
||||
"eslint-plugin-prettier": "^3.1.1",
|
||||
"exports-loader": "^0.7.0",
|
||||
"file-loader": "^4.0.0",
|
||||
"git-revision-webpack-plugin": "^3.0.3",
|
||||
"mini-css-extract-plugin": "0.8.0",
|
||||
"node-sass": "^4.12.0",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"prettier": "^1.18.2",
|
||||
"prettier-check": "^2.0.0",
|
||||
"pretty-quick": "^1.11.1",
|
||||
"sass-loader": "^8.0.0",
|
||||
"strip-loader": "^0.1.2",
|
||||
"style-loader": "^1.0.0",
|
||||
"svg-inline-loader": "0.8.0",
|
||||
"template-string-optimize-loader": "^3.0.0",
|
||||
"url-loader": "^2.1.0",
|
||||
"vuepress": "1.1.0",
|
||||
"webpack": "^4.40.2",
|
||||
"webpack-cli": "3.3.9",
|
||||
"webpack-dev-server": "^3.8.1",
|
||||
"yorkie": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"balloon-css": "^1.0.3",
|
||||
"promise-polyfill": "8.1.3",
|
||||
"smoothscroll": "0.4.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
class Bar {
|
||||
constructor (template) {
|
||||
constructor(template) {
|
||||
this.elements = {};
|
||||
this.elements.volume = template.volume;
|
||||
this.elements.played = template.played;
|
||||
|
|
@ -13,15 +13,15 @@ class Bar {
|
|||
* @param {Number} percentage
|
||||
* @param {String} direction - Point out the direction of this bar, Should be height or width
|
||||
*/
|
||||
set (type, percentage, direction) {
|
||||
set(type, percentage, direction) {
|
||||
percentage = Math.max(percentage, 0);
|
||||
percentage = Math.min(percentage, 1);
|
||||
this.elements[type].style[direction] = percentage * 100 + '%';
|
||||
}
|
||||
|
||||
get (type, direction) {
|
||||
get(type, direction) {
|
||||
return parseFloat(this.elements[type].style[direction]) / 100;
|
||||
}
|
||||
}
|
||||
|
||||
export default Bar;
|
||||
export default Bar;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import utils from './utils';
|
|||
import Icons from './icons';
|
||||
|
||||
class Controller {
|
||||
constructor (player) {
|
||||
constructor(player) {
|
||||
this.player = player;
|
||||
|
||||
this.initPlayButton();
|
||||
|
|
@ -18,13 +18,13 @@ class Controller {
|
|||
this.initLrcButton();
|
||||
}
|
||||
|
||||
initPlayButton () {
|
||||
initPlayButton() {
|
||||
this.player.template.pic.addEventListener('click', () => {
|
||||
this.player.toggle();
|
||||
});
|
||||
}
|
||||
|
||||
initPlayBar () {
|
||||
initPlayBar() {
|
||||
const thumbMove = (e) => {
|
||||
let percentage = ((e.clientX || e.changedTouches[0].clientX) - this.player.template.barWrap.getBoundingClientRect().left) / this.player.template.barWrap.clientWidth;
|
||||
percentage = Math.max(percentage, 0);
|
||||
|
|
@ -52,12 +52,11 @@ class Controller {
|
|||
});
|
||||
}
|
||||
|
||||
initVolumeButton () {
|
||||
initVolumeButton() {
|
||||
this.player.template.volumeButton.addEventListener('click', () => {
|
||||
if (this.player.audio.muted) {
|
||||
this.player.volume(this.player.audio.volume, true);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.player.audio.muted = true;
|
||||
this.player.switchVolumeIcon();
|
||||
this.player.bar.set('volume', 0, 'height');
|
||||
|
|
@ -88,41 +87,36 @@ class Controller {
|
|||
});
|
||||
}
|
||||
|
||||
initOrderButton () {
|
||||
initOrderButton() {
|
||||
this.player.template.order.addEventListener('click', () => {
|
||||
if (this.player.options.order === 'list') {
|
||||
this.player.options.order = 'random';
|
||||
this.player.template.order.innerHTML = Icons.orderRandom;
|
||||
}
|
||||
else if (this.player.options.order === 'random') {
|
||||
} else if (this.player.options.order === 'random') {
|
||||
this.player.options.order = 'list';
|
||||
this.player.template.order.innerHTML = Icons.orderList;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
initLoopButton () {
|
||||
initLoopButton() {
|
||||
this.player.template.loop.addEventListener('click', () => {
|
||||
if (this.player.list.audios.length > 1) {
|
||||
if (this.player.options.loop === 'one') {
|
||||
this.player.options.loop = 'none';
|
||||
this.player.template.loop.innerHTML = Icons.loopNone;
|
||||
}
|
||||
else if (this.player.options.loop === 'none') {
|
||||
} else if (this.player.options.loop === 'none') {
|
||||
this.player.options.loop = 'all';
|
||||
this.player.template.loop.innerHTML = Icons.loopAll;
|
||||
}
|
||||
else if (this.player.options.loop === 'all') {
|
||||
} else if (this.player.options.loop === 'all') {
|
||||
this.player.options.loop = 'one';
|
||||
this.player.template.loop.innerHTML = Icons.loopOne;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (this.player.options.loop === 'one' || this.player.options.loop === 'all') {
|
||||
this.player.options.loop = 'none';
|
||||
this.player.template.loop.innerHTML = Icons.loopNone;
|
||||
}
|
||||
else if (this.player.options.loop === 'none') {
|
||||
} else if (this.player.options.loop === 'none') {
|
||||
this.player.options.loop = 'all';
|
||||
this.player.template.loop.innerHTML = Icons.loopAll;
|
||||
}
|
||||
|
|
@ -130,19 +124,19 @@ class Controller {
|
|||
});
|
||||
}
|
||||
|
||||
initMenuButton () {
|
||||
initMenuButton() {
|
||||
this.player.template.menu.addEventListener('click', () => {
|
||||
this.player.list.toggle();
|
||||
});
|
||||
}
|
||||
|
||||
initMiniSwitcher () {
|
||||
initMiniSwitcher() {
|
||||
this.player.template.miniSwitcher.addEventListener('click', () => {
|
||||
this.player.setMode(this.player.mode === 'mini' ? 'normal' : 'mini');
|
||||
});
|
||||
}
|
||||
|
||||
initSkipButton () {
|
||||
initSkipButton() {
|
||||
this.player.template.skipBackButton.addEventListener('click', () => {
|
||||
this.player.skipBack();
|
||||
});
|
||||
|
|
@ -154,13 +148,12 @@ class Controller {
|
|||
});
|
||||
}
|
||||
|
||||
initLrcButton () {
|
||||
initLrcButton() {
|
||||
this.player.template.lrcButton.addEventListener('click', () => {
|
||||
if (this.player.template.lrcButton.classList.contains('aplayer-icon-lrc-inactivity')) {
|
||||
this.player.template.lrcButton.classList.remove('aplayer-icon-lrc-inactivity');
|
||||
this.player.lrc && this.player.lrc.show();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.player.template.lrcButton.classList.add('aplayer-icon-lrc-inactivity');
|
||||
this.player.lrc && this.player.lrc.hide();
|
||||
}
|
||||
|
|
@ -168,4 +161,4 @@ class Controller {
|
|||
}
|
||||
}
|
||||
|
||||
export default Controller;
|
||||
export default Controller;
|
||||
|
|
|
|||
|
|
@ -1,22 +1,36 @@
|
|||
class Events {
|
||||
constructor () {
|
||||
constructor() {
|
||||
this.events = {};
|
||||
|
||||
this.audioEvents = [
|
||||
'abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied', 'ended', 'error',
|
||||
'loadeddata', 'loadedmetadata', 'loadstart', 'mozaudioavailable', 'pause', 'play',
|
||||
'playing', 'progress', 'ratechange', 'seeked', 'seeking', 'stalled', 'suspend',
|
||||
'timeupdate', 'volumechange', 'waiting'
|
||||
];
|
||||
this.playerEvents = [
|
||||
'destroy',
|
||||
'listshow', 'listhide', 'listadd', 'listremove', 'listswitch', 'listclear',
|
||||
'noticeshow', 'noticehide',
|
||||
'lrcshow', 'lrchide',
|
||||
'abort',
|
||||
'canplay',
|
||||
'canplaythrough',
|
||||
'durationchange',
|
||||
'emptied',
|
||||
'ended',
|
||||
'error',
|
||||
'loadeddata',
|
||||
'loadedmetadata',
|
||||
'loadstart',
|
||||
'mozaudioavailable',
|
||||
'pause',
|
||||
'play',
|
||||
'playing',
|
||||
'progress',
|
||||
'ratechange',
|
||||
'seeked',
|
||||
'seeking',
|
||||
'stalled',
|
||||
'suspend',
|
||||
'timeupdate',
|
||||
'volumechange',
|
||||
'waiting',
|
||||
];
|
||||
this.playerEvents = ['destroy', 'listshow', 'listhide', 'listadd', 'listremove', 'listswitch', 'listclear', 'noticeshow', 'noticehide', 'lrcshow', 'lrchide'];
|
||||
}
|
||||
|
||||
on (name, callback) {
|
||||
on(name, callback) {
|
||||
if (this.type(name) && typeof callback === 'function') {
|
||||
if (!this.events[name]) {
|
||||
this.events[name] = [];
|
||||
|
|
@ -25,7 +39,7 @@ class Events {
|
|||
}
|
||||
}
|
||||
|
||||
trigger (name, data) {
|
||||
trigger(name, data) {
|
||||
if (this.events[name] && this.events[name].length) {
|
||||
for (let i = 0; i < this.events[name].length; i++) {
|
||||
this.events[name][i](data);
|
||||
|
|
@ -33,11 +47,10 @@ class Events {
|
|||
}
|
||||
}
|
||||
|
||||
type (name) {
|
||||
type(name) {
|
||||
if (this.playerEvents.indexOf(name) !== -1) {
|
||||
return 'player';
|
||||
}
|
||||
else if (this.audioEvents.indexOf(name) !== -1) {
|
||||
} else if (this.audioEvents.indexOf(name) !== -1) {
|
||||
return 'audio';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ import APlayer from './player';
|
|||
/* global APLAYER_VERSION GIT_HASH */
|
||||
console.log(`${'\n'} %c APlayer v${APLAYER_VERSION} ${GIT_HASH} %c http://aplayer.js.org ${'\n'}`, 'color: #fadfa3; background: #030307; padding:5px 0;', 'background: #fadfa3; padding:5px 0;');
|
||||
|
||||
export default APlayer;
|
||||
export default APlayer;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import utils from './utils';
|
|||
import smoothScroll from 'smoothscroll';
|
||||
|
||||
class List {
|
||||
constructor (player) {
|
||||
constructor(player) {
|
||||
this.player = player;
|
||||
this.index = 0;
|
||||
this.audios = this.player.options.audio;
|
||||
|
|
@ -13,34 +13,32 @@ class List {
|
|||
this.bindEvents();
|
||||
}
|
||||
|
||||
bindEvents () {
|
||||
bindEvents() {
|
||||
this.player.template.list.addEventListener('click', (e) => {
|
||||
let target;
|
||||
if (e.target.tagName.toUpperCase() === 'LI') {
|
||||
target = e.target;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
target = e.target.parentElement;
|
||||
}
|
||||
const audioIndex = parseInt(target.getElementsByClassName('aplayer-list-index')[0].innerHTML) - 1;
|
||||
if (audioIndex !== this.index) {
|
||||
this.switch(audioIndex);
|
||||
this.player.play();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.player.toggle();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
show () {
|
||||
show() {
|
||||
this.showing = true;
|
||||
this.player.template.list.scrollTop = this.index * 33;
|
||||
this.player.template.list.style.height = `${Math.min(this.player.template.list.scrollHeight, this.player.options.listMaxHeight)}px`;
|
||||
this.player.events.trigger('listshow');
|
||||
}
|
||||
|
||||
hide () {
|
||||
hide() {
|
||||
this.showing = false;
|
||||
this.player.template.list.style.height = `${Math.min(this.player.template.list.scrollHeight, this.player.options.listMaxHeight)}px`;
|
||||
setTimeout(() => {
|
||||
|
|
@ -49,16 +47,15 @@ class List {
|
|||
}, 0);
|
||||
}
|
||||
|
||||
toggle () {
|
||||
toggle() {
|
||||
if (this.showing) {
|
||||
this.hide();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.show();
|
||||
}
|
||||
}
|
||||
|
||||
add (audios) {
|
||||
add(audios) {
|
||||
this.player.events.trigger('listadd', {
|
||||
audios: audios,
|
||||
});
|
||||
|
|
@ -80,7 +77,7 @@ class List {
|
|||
this.player.template.list.innerHTML += tplListItem({
|
||||
theme: this.player.options.theme,
|
||||
audio: audios,
|
||||
index: this.audios.length + 1
|
||||
index: this.audios.length + 1,
|
||||
});
|
||||
|
||||
this.audios = this.audios.concat(audios);
|
||||
|
|
@ -97,14 +94,13 @@ class List {
|
|||
if (wasEmpty) {
|
||||
if (this.player.options.order === 'random') {
|
||||
this.switch(this.player.randomOrder[0]);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.switch(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
remove (index) {
|
||||
remove(index) {
|
||||
this.player.events.trigger('listremove', {
|
||||
index: index,
|
||||
});
|
||||
|
|
@ -119,8 +115,7 @@ class List {
|
|||
if (index === this.index) {
|
||||
if (this.audios[index]) {
|
||||
this.switch(index);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.switch(index - 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -136,14 +131,13 @@ class List {
|
|||
}
|
||||
|
||||
this.player.template.listCurs = this.player.container.querySelectorAll('.aplayer-list-cur');
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (index) {
|
||||
switch(index) {
|
||||
this.player.events.trigger('listswitch', {
|
||||
index: index,
|
||||
});
|
||||
|
|
@ -173,13 +167,14 @@ class List {
|
|||
this.player.lrc && this.player.lrc.update(0);
|
||||
|
||||
// set duration time
|
||||
if (this.player.duration !== 1) { // compatibility: Android browsers will output 1 at first
|
||||
if (this.player.duration !== 1) {
|
||||
// compatibility: Android browsers will output 1 at first
|
||||
this.player.template.dtime.innerHTML = utils.secondToTime(this.player.duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clear () {
|
||||
clear() {
|
||||
this.player.events.trigger('listclear');
|
||||
this.index = 0;
|
||||
this.player.container.classList.remove('aplayer-withlist');
|
||||
|
|
@ -197,4 +192,4 @@ class List {
|
|||
}
|
||||
}
|
||||
|
||||
export default List;
|
||||
export default List;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import tplLrc from '../template/lrc.art';
|
||||
|
||||
class Lrc {
|
||||
constructor (options) {
|
||||
constructor(options) {
|
||||
this.container = options.container;
|
||||
this.async = options.async;
|
||||
this.player = options.player;
|
||||
|
|
@ -10,26 +10,25 @@ class Lrc {
|
|||
this.current = [];
|
||||
}
|
||||
|
||||
show () {
|
||||
show() {
|
||||
this.player.events.trigger('lrcshow');
|
||||
this.player.template.lrcWrap.classList.remove('aplayer-lrc-hide');
|
||||
}
|
||||
|
||||
hide () {
|
||||
hide() {
|
||||
this.player.events.trigger('lrchide');
|
||||
this.player.template.lrcWrap.classList.add('aplayer-lrc-hide');
|
||||
}
|
||||
|
||||
toggle () {
|
||||
toggle() {
|
||||
if (this.player.template.lrcWrap.classList.contains('aplayer-lrc-hide')) {
|
||||
this.show();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
|
||||
update (currentTime = this.player.audio.currentTime) {
|
||||
update(currentTime = this.player.audio.currentTime) {
|
||||
if (this.index > this.current.length - 1 || currentTime < this.current[this.index][0] || (!this.current[this.index + 1] || currentTime >= this.current[this.index + 1][0])) {
|
||||
for (let i = 0; i < this.current.length; i++) {
|
||||
if (currentTime >= this.current[i][0] && (!this.current[i + 1] || currentTime < this.current[i + 1][0])) {
|
||||
|
|
@ -43,30 +42,27 @@ class Lrc {
|
|||
}
|
||||
}
|
||||
|
||||
switch (index) {
|
||||
switch(index) {
|
||||
if (!this.parsed[index]) {
|
||||
if (!this.async) {
|
||||
if (this.player.list.audios[index].lrc) {
|
||||
this.parsed[index] = this.parse(this.player.list.audios[index].lrc);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.parsed[index] = [['00:00', 'Not available']];
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.parsed[index] = [['00:00', 'Loading']];
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = () => {
|
||||
if (index === this.player.list.index && xhr.readyState === 4) {
|
||||
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
|
||||
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
|
||||
this.parsed[index] = this.parse(xhr.responseText);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.player.notice(`LRC file request fails: status ${xhr.status}`);
|
||||
this.parsed[index] = [['00:00', 'Not available']];
|
||||
}
|
||||
this.container.innerHTML = tplLrc({
|
||||
lyrics: this.parsed[index]
|
||||
lyrics: this.parsed[index],
|
||||
});
|
||||
this.update(0);
|
||||
this.current = this.parsed[index];
|
||||
|
|
@ -79,7 +75,7 @@ class Lrc {
|
|||
}
|
||||
|
||||
this.container.innerHTML = tplLrc({
|
||||
lyrics: this.parsed[index]
|
||||
lyrics: this.parsed[index],
|
||||
});
|
||||
this.update(0);
|
||||
this.current = this.parsed[index];
|
||||
|
|
@ -97,7 +93,7 @@ class Lrc {
|
|||
*
|
||||
* @return {String} [[time, text], [time, text], [time, text], ...]
|
||||
*/
|
||||
parse (lrc_s) {
|
||||
parse(lrc_s) {
|
||||
if (lrc_s) {
|
||||
lrc_s = lrc_s.replace(/([^\]^\n])\[/g, (match, p1) => p1 + '\n[');
|
||||
const lyric = lrc_s.split('\n');
|
||||
|
|
@ -107,7 +103,10 @@ class Lrc {
|
|||
// match lrc time
|
||||
const lrcTimes = lyric[i].match(/\[(\d{2}):(\d{2})(\.(\d{2,3}))?]/g);
|
||||
// match lrc text
|
||||
const lrcText = lyric[i].replace(/.*\[(\d{2}):(\d{2})(\.(\d{2,3}))?]/g, '').replace(/<(\d{2}):(\d{2})(\.(\d{2,3}))?>/g, '').replace(/^\s+|\s+$/g, '');
|
||||
const lrcText = lyric[i]
|
||||
.replace(/.*\[(\d{2}):(\d{2})(\.(\d{2,3}))?]/g, '')
|
||||
.replace(/<(\d{2}):(\d{2})(\.(\d{2,3}))?>/g, '')
|
||||
.replace(/^\s+|\s+$/g, '');
|
||||
|
||||
if (lrcTimes) {
|
||||
// handle multiple time tag
|
||||
|
|
@ -126,20 +125,19 @@ class Lrc {
|
|||
lrc = lrc.filter((item) => item[1]);
|
||||
lrc.sort((a, b) => a[0] - b[0]);
|
||||
return lrc;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
remove (index) {
|
||||
remove(index) {
|
||||
this.parsed.splice(index, 1);
|
||||
}
|
||||
|
||||
clear () {
|
||||
clear() {
|
||||
this.parsed = [];
|
||||
this.container.innerHTML = '';
|
||||
}
|
||||
}
|
||||
|
||||
export default Lrc;
|
||||
export default Lrc;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
export default (options) => {
|
||||
|
||||
// default options
|
||||
const defaultOption = {
|
||||
container: options.element || document.getElementsByClassName('aplayer')[0],
|
||||
|
|
@ -16,7 +15,7 @@ export default (options) => {
|
|||
listFolded: options.fixed,
|
||||
listMaxHeight: options.listmaxheight || 250,
|
||||
audio: options.music || [],
|
||||
storageName: 'aplayer-setting'
|
||||
storageName: 'aplayer-setting',
|
||||
};
|
||||
for (const defaultKey in defaultOption) {
|
||||
if (defaultOption.hasOwnProperty(defaultKey) && !options.hasOwnProperty(defaultKey)) {
|
||||
|
|
|
|||
129
src/js/player.js
129
src/js/player.js
|
|
@ -15,14 +15,13 @@ import List from './list';
|
|||
const instances = [];
|
||||
|
||||
class APlayer {
|
||||
|
||||
/**
|
||||
* APlayer constructor function
|
||||
*
|
||||
* @param {Object} options - See README
|
||||
* @constructor
|
||||
*/
|
||||
constructor (options) {
|
||||
constructor(options) {
|
||||
this.options = handleOption(options);
|
||||
this.container = this.options.container;
|
||||
this.paused = true;
|
||||
|
|
@ -93,8 +92,7 @@ class APlayer {
|
|||
this.bindEvents();
|
||||
if (this.options.order === 'random') {
|
||||
this.list.switch(this.randomOrder[0]);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.list.switch(0);
|
||||
}
|
||||
|
||||
|
|
@ -106,7 +104,7 @@ class APlayer {
|
|||
instances.push(this);
|
||||
}
|
||||
|
||||
initAudio () {
|
||||
initAudio() {
|
||||
this.audio = document.createElement('audio');
|
||||
this.audio.preload = this.options.preload;
|
||||
|
||||
|
|
@ -119,7 +117,7 @@ class APlayer {
|
|||
this.volume(this.storage.get('volume'), true);
|
||||
}
|
||||
|
||||
bindEvents () {
|
||||
bindEvents() {
|
||||
this.on('play', () => {
|
||||
if (this.paused) {
|
||||
this.setUIPlaying();
|
||||
|
|
@ -145,7 +143,8 @@ class APlayer {
|
|||
|
||||
// show audio time: the metadata has loaded or changed
|
||||
this.on('durationchange', () => {
|
||||
if (this.duration !== 1) { // compatibility: Android browsers will output 1 at first
|
||||
if (this.duration !== 1) {
|
||||
// compatibility: Android browsers will output 1 at first
|
||||
this.template.dtime.innerHTML = utils.secondToTime(this.duration);
|
||||
}
|
||||
});
|
||||
|
|
@ -167,8 +166,7 @@ class APlayer {
|
|||
this.play();
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
else if (this.list.audios.length === 1) {
|
||||
} else if (this.list.audios.length === 1) {
|
||||
this.notice('An audio error has occurred.');
|
||||
}
|
||||
});
|
||||
|
|
@ -183,35 +181,30 @@ class APlayer {
|
|||
if (this.list.index < this.list.audios.length - 1) {
|
||||
this.list.switch((this.list.index + 1) % this.list.audios.length);
|
||||
this.play();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.list.switch((this.list.index + 1) % this.list.audios.length);
|
||||
this.pause();
|
||||
}
|
||||
}
|
||||
else if (this.options.order === 'random') {
|
||||
} else if (this.options.order === 'random') {
|
||||
if (this.randomOrder.indexOf(this.list.index) < this.randomOrder.length - 1) {
|
||||
this.list.switch(this.nextIndex());
|
||||
this.play();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.list.switch(this.nextIndex());
|
||||
this.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.options.loop === 'one') {
|
||||
} else if (this.options.loop === 'one') {
|
||||
this.list.switch(this.list.index);
|
||||
this.play();
|
||||
}
|
||||
else if (this.options.loop === 'all') {
|
||||
} else if (this.options.loop === 'all') {
|
||||
this.skipForward();
|
||||
this.play();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setAudio (audio) {
|
||||
setAudio(audio) {
|
||||
if (this.hls) {
|
||||
this.hls.destroy();
|
||||
this.hls = null;
|
||||
|
|
@ -220,34 +213,28 @@ class APlayer {
|
|||
if (this.options.customAudioType && this.options.customAudioType[type]) {
|
||||
if (Object.prototype.toString.call(this.options.customAudioType[type]) === '[object Function]') {
|
||||
this.options.customAudioType[type](this.audio, audio, this);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
console.error(`Illegal customType: ${type}`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (!type || type === 'auto') {
|
||||
if (/m3u8(#|\?|$)/i.exec(audio.url)) {
|
||||
type = 'hls';
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
type = 'normal';
|
||||
}
|
||||
}
|
||||
if (type === 'hls') {
|
||||
if (Hls.isSupported()) {
|
||||
this.hls = new Hls();
|
||||
if (window.Hls.isSupported()) {
|
||||
this.hls = new window.Hls();
|
||||
this.hls.loadSource(audio.url);
|
||||
this.hls.attachMedia(this.audio);
|
||||
}
|
||||
else if (this.audio.canPlayType('application/x-mpegURL') || this.audio.canPlayType('application/vnd.apple.mpegURL')) {
|
||||
} else if (this.audio.canPlayType('application/x-mpegURL') || this.audio.canPlayType('application/vnd.apple.mpegURL')) {
|
||||
this.audio.src = audio.url;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.notice('Error: HLS is not supported.');
|
||||
}
|
||||
}
|
||||
else if (type === 'normal') {
|
||||
} else if (type === 'normal') {
|
||||
this.audio.src = audio.url;
|
||||
}
|
||||
}
|
||||
|
|
@ -258,7 +245,7 @@ class APlayer {
|
|||
}
|
||||
}
|
||||
|
||||
theme (color = this.list.audios[this.list.index].theme || this.options.theme, index = this.list.index, isReset = true) {
|
||||
theme(color = this.list.audios[this.list.index].theme || this.options.theme, index = this.list.index, isReset = true) {
|
||||
if (isReset) {
|
||||
this.list.audios[index] && (this.list.audios[index].theme = color);
|
||||
}
|
||||
|
|
@ -271,7 +258,7 @@ class APlayer {
|
|||
}
|
||||
}
|
||||
|
||||
seek (time) {
|
||||
seek(time) {
|
||||
time = Math.max(time, 0);
|
||||
time = Math.min(time, this.duration);
|
||||
this.audio.currentTime = time;
|
||||
|
|
@ -279,11 +266,11 @@ class APlayer {
|
|||
this.template.ptime.innerHTML = utils.secondToTime(time);
|
||||
}
|
||||
|
||||
get duration () {
|
||||
get duration() {
|
||||
return isNaN(this.audio.duration) ? 0 : this.audio.duration;
|
||||
}
|
||||
|
||||
setUIPlaying () {
|
||||
setUIPlaying() {
|
||||
if (this.paused) {
|
||||
this.paused = false;
|
||||
this.template.button.classList.remove('aplayer-play');
|
||||
|
|
@ -306,7 +293,7 @@ class APlayer {
|
|||
}
|
||||
}
|
||||
|
||||
play () {
|
||||
play() {
|
||||
this.setUIPlaying();
|
||||
|
||||
const playPromise = this.audio.play();
|
||||
|
|
@ -320,7 +307,7 @@ class APlayer {
|
|||
}
|
||||
}
|
||||
|
||||
setUIPaused () {
|
||||
setUIPaused() {
|
||||
if (!this.paused) {
|
||||
this.paused = true;
|
||||
|
||||
|
|
@ -337,19 +324,17 @@ class APlayer {
|
|||
this.timer.disable('loading');
|
||||
}
|
||||
|
||||
pause () {
|
||||
pause() {
|
||||
this.setUIPaused();
|
||||
this.audio.pause();
|
||||
}
|
||||
|
||||
switchVolumeIcon () {
|
||||
switchVolumeIcon() {
|
||||
if (this.volume() >= 0.95) {
|
||||
this.template.volumeButton.innerHTML = Icons.volumeUp;
|
||||
}
|
||||
else if (this.volume() > 0) {
|
||||
} else if (this.volume() > 0) {
|
||||
this.template.volumeButton.innerHTML = Icons.volumeDown;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.template.volumeButton.innerHTML = Icons.volumeOff;
|
||||
}
|
||||
}
|
||||
|
|
@ -357,7 +342,7 @@ class APlayer {
|
|||
/**
|
||||
* Set volume
|
||||
*/
|
||||
volume (percentage, nostorage) {
|
||||
volume(percentage, nostorage) {
|
||||
percentage = parseFloat(percentage);
|
||||
if (!isNaN(percentage)) {
|
||||
percentage = Math.max(percentage, 0);
|
||||
|
|
@ -381,41 +366,40 @@ class APlayer {
|
|||
/**
|
||||
* bind events
|
||||
*/
|
||||
on (name, callback) {
|
||||
on(name, callback) {
|
||||
this.events.on(name, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* toggle between play and pause
|
||||
*/
|
||||
toggle () {
|
||||
toggle() {
|
||||
if (this.template.button.classList.contains('aplayer-play')) {
|
||||
this.play();
|
||||
}
|
||||
else if (this.template.button.classList.contains('aplayer-pause')) {
|
||||
} else if (this.template.button.classList.contains('aplayer-pause')) {
|
||||
this.pause();
|
||||
}
|
||||
}
|
||||
|
||||
// abandoned
|
||||
switchAudio (index) {
|
||||
switchAudio(index) {
|
||||
this.list.switch(index);
|
||||
}
|
||||
|
||||
// abandoned
|
||||
addAudio (audios) {
|
||||
addAudio(audios) {
|
||||
this.list.add(audios);
|
||||
}
|
||||
|
||||
// abandoned
|
||||
removeAudio (index) {
|
||||
removeAudio(index) {
|
||||
this.list.remove(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* destroy this player
|
||||
*/
|
||||
destroy () {
|
||||
destroy() {
|
||||
instances.splice(instances.indexOf(this), 1);
|
||||
this.pause();
|
||||
this.container.innerHTML = '';
|
||||
|
|
@ -424,17 +408,16 @@ class APlayer {
|
|||
this.events.trigger('destroy');
|
||||
}
|
||||
|
||||
setMode (mode = 'normal') {
|
||||
setMode(mode = 'normal') {
|
||||
this.mode = mode;
|
||||
if (mode === 'mini') {
|
||||
this.container.classList.add('aplayer-narrow');
|
||||
}
|
||||
else if (mode === 'normal') {
|
||||
} else if (mode === 'normal') {
|
||||
this.container.classList.remove('aplayer-narrow');
|
||||
}
|
||||
}
|
||||
|
||||
notice (text, time = 2000, opacity = 0.8) {
|
||||
notice(text, time = 2000, opacity = 0.8) {
|
||||
this.template.notice.innerHTML = text;
|
||||
this.template.notice.style.opacity = opacity;
|
||||
if (this.noticeTime) {
|
||||
|
|
@ -451,55 +434,49 @@ class APlayer {
|
|||
}
|
||||
}
|
||||
|
||||
prevIndex () {
|
||||
prevIndex() {
|
||||
if (this.list.audios.length > 1) {
|
||||
if (this.options.order === 'list') {
|
||||
return this.list.index - 1 < 0 ? this.list.audios.length - 1 : this.list.index - 1;
|
||||
}
|
||||
else if (this.options.order === 'random') {
|
||||
} else if (this.options.order === 'random') {
|
||||
const index = this.randomOrder.indexOf(this.list.index);
|
||||
if (index === 0) {
|
||||
return this.randomOrder[this.randomOrder.length - 1];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return this.randomOrder[index - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
nextIndex () {
|
||||
nextIndex() {
|
||||
if (this.list.audios.length > 1) {
|
||||
if (this.options.order === 'list') {
|
||||
return (this.list.index + 1) % this.list.audios.length;
|
||||
}
|
||||
else if (this.options.order === 'random') {
|
||||
} else if (this.options.order === 'random') {
|
||||
const index = this.randomOrder.indexOf(this.list.index);
|
||||
if (index === this.randomOrder.length - 1) {
|
||||
return this.randomOrder[0];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return this.randomOrder[index + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
skipBack () {
|
||||
skipBack() {
|
||||
this.list.switch(this.prevIndex());
|
||||
}
|
||||
|
||||
skipForward () {
|
||||
skipForward() {
|
||||
this.list.switch(this.nextIndex());
|
||||
}
|
||||
|
||||
static get version () {
|
||||
static get version() {
|
||||
/* global APLAYER_VERSION */
|
||||
return APLAYER_VERSION;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import utils from './utils';
|
||||
|
||||
class Storage {
|
||||
constructor (player) {
|
||||
constructor(player) {
|
||||
this.storageName = player.options.storageName;
|
||||
|
||||
this.data = JSON.parse(utils.storage.get(this.storageName));
|
||||
|
|
@ -11,14 +11,14 @@ class Storage {
|
|||
this.data.volume = this.data.volume || player.options.volume;
|
||||
}
|
||||
|
||||
get (key) {
|
||||
get(key) {
|
||||
return this.data[key];
|
||||
}
|
||||
|
||||
set (key, value) {
|
||||
set(key, value) {
|
||||
this.data[key] = value;
|
||||
utils.storage.set(this.storageName, JSON.stringify(this.data));
|
||||
}
|
||||
}
|
||||
|
||||
export default Storage;
|
||||
export default Storage;
|
||||
|
|
|
|||
|
|
@ -2,20 +2,19 @@ import Icons from './icons';
|
|||
import tplPlayer from '../template/player.art';
|
||||
|
||||
class Template {
|
||||
constructor (options) {
|
||||
constructor(options) {
|
||||
this.container = options.container;
|
||||
this.options = options.options;
|
||||
this.randomOrder = options.randomOrder;
|
||||
this.init();
|
||||
}
|
||||
|
||||
init () {
|
||||
init() {
|
||||
let cover = '';
|
||||
if (this.options.audio.length) {
|
||||
if (this.options.order === 'random') {
|
||||
cover = this.options.audio[this.randomOrder[0]].cover;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
cover = this.options.audio[0].cover;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
class Timer {
|
||||
constructor (player) {
|
||||
constructor(player) {
|
||||
this.player = player;
|
||||
|
||||
window.requestAnimationFrame = (() =>
|
||||
|
|
@ -9,23 +8,22 @@ class Timer {
|
|||
window.mozRequestAnimationFrame ||
|
||||
window.oRequestAnimationFrame ||
|
||||
window.msRequestAnimationFrame ||
|
||||
function (callback) {
|
||||
function(callback) {
|
||||
window.setTimeout(callback, 1000 / 60);
|
||||
}
|
||||
)();
|
||||
})();
|
||||
|
||||
this.types = ['loading'];
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
init () {
|
||||
init() {
|
||||
this.types.forEach((item) => {
|
||||
this[`init${item}Checker`]();
|
||||
});
|
||||
}
|
||||
|
||||
initloadingChecker () {
|
||||
initloadingChecker() {
|
||||
let lastPlayPos = 0;
|
||||
let currentPlayPos = 0;
|
||||
let bufferingDetected = false;
|
||||
|
|
@ -33,15 +31,11 @@ class Timer {
|
|||
if (this.enableloadingChecker) {
|
||||
// whether the audio is buffering
|
||||
currentPlayPos = this.player.audio.currentTime;
|
||||
if (!bufferingDetected
|
||||
&& currentPlayPos === lastPlayPos
|
||||
&& !this.player.audio.paused) {
|
||||
if (!bufferingDetected && currentPlayPos === lastPlayPos && !this.player.audio.paused) {
|
||||
this.player.container.classList.add('aplayer-loading');
|
||||
bufferingDetected = true;
|
||||
}
|
||||
if (bufferingDetected
|
||||
&& currentPlayPos > lastPlayPos
|
||||
&& !this.player.audio.paused) {
|
||||
if (bufferingDetected && currentPlayPos > lastPlayPos && !this.player.audio.paused) {
|
||||
this.player.container.classList.remove('aplayer-loading');
|
||||
bufferingDetected = false;
|
||||
}
|
||||
|
|
@ -50,7 +44,7 @@ class Timer {
|
|||
}, 100);
|
||||
}
|
||||
|
||||
enable (type) {
|
||||
enable(type) {
|
||||
this[`enable${type}Checker`] = true;
|
||||
|
||||
if (type === 'fps') {
|
||||
|
|
@ -58,11 +52,11 @@ class Timer {
|
|||
}
|
||||
}
|
||||
|
||||
disable (type) {
|
||||
disable(type) {
|
||||
this[`enable${type}Checker`] = false;
|
||||
}
|
||||
|
||||
destroy () {
|
||||
destroy() {
|
||||
this.types.forEach((item) => {
|
||||
this[`enable${item}Checker`] = false;
|
||||
this[`${item}Checker`] && clearInterval(this[`${item}Checker`]);
|
||||
|
|
@ -70,4 +64,4 @@ class Timer {
|
|||
}
|
||||
}
|
||||
|
||||
export default Timer;
|
||||
export default Timer;
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
const isMobile = /mobile/i.test(window.navigator.userAgent);
|
||||
|
||||
const utils = {
|
||||
|
||||
/**
|
||||
* Parse second to time string
|
||||
*
|
||||
* @param {Number} second
|
||||
* @return {String} 00:00 or 00:00:00
|
||||
*/
|
||||
* Parse second to time string
|
||||
*
|
||||
* @param {Number} second
|
||||
* @return {String} 00:00 or 00:00:00
|
||||
*/
|
||||
secondToTime: (second) => {
|
||||
const add0 = (num) => num < 10 ? '0' + num : '' + num;
|
||||
const add0 = (num) => (num < 10 ? '0' + num : '' + num);
|
||||
const hour = Math.floor(second / 3600);
|
||||
const min = Math.floor((second - hour * 3600) / 60);
|
||||
const sec = Math.floor(second - hour * 3600 - min * 60);
|
||||
|
|
@ -23,20 +22,20 @@ const utils = {
|
|||
localStorage.setItem(key, value);
|
||||
},
|
||||
|
||||
get: (key) => localStorage.getItem(key)
|
||||
get: (key) => localStorage.getItem(key),
|
||||
},
|
||||
|
||||
nameMap: {
|
||||
dragStart: isMobile ? 'touchstart' : 'mousedown',
|
||||
dragMove: isMobile ? 'touchmove' : 'mousemove',
|
||||
dragEnd: isMobile ? 'touchend' : 'mouseup'
|
||||
dragEnd: isMobile ? 'touchend' : 'mouseup',
|
||||
},
|
||||
|
||||
/**
|
||||
* get random order, using Fisher–Yates shuffle
|
||||
*/
|
||||
randomOrder: (length) => {
|
||||
function shuffle (arr) {
|
||||
function shuffle(arr) {
|
||||
for (let i = arr.length - 1; i >= 0; i--) {
|
||||
const randomIndex = Math.floor(Math.random() * (i + 1));
|
||||
const itemAtIndex = arr[randomIndex];
|
||||
|
|
@ -45,10 +44,12 @@ const utils = {
|
|||
}
|
||||
return arr;
|
||||
}
|
||||
return shuffle([...Array(length)].map(function (item, i) {
|
||||
return i;
|
||||
}));
|
||||
}
|
||||
return shuffle(
|
||||
[...Array(length)].map(function(item, i) {
|
||||
return i;
|
||||
})
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export default utils;
|
||||
export default utils;
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
/* eslint-disable no-undef */
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const GitRevisionPlugin = require('git-revision-webpack-plugin');
|
||||
const gitRevisionPlugin = new GitRevisionPlugin();
|
||||
const autoprefixer = require('autoprefixer');
|
||||
const cssnano = require('cssnano');
|
||||
|
||||
module.exports = {
|
||||
|
||||
mode: 'development',
|
||||
|
||||
devtool: 'cheap-module-source-map',
|
||||
|
||||
entry: {
|
||||
'APlayer': './src/js/index.js'
|
||||
APlayer: './src/js/index.js',
|
||||
},
|
||||
|
||||
output: {
|
||||
|
|
@ -21,23 +21,17 @@ module.exports = {
|
|||
libraryTarget: 'umd',
|
||||
libraryExport: 'default',
|
||||
umdNamedDefine: true,
|
||||
publicPath: '/'
|
||||
publicPath: '/',
|
||||
},
|
||||
|
||||
resolve: {
|
||||
modules: ['node_modules'],
|
||||
extensions: ['.js', '.scss']
|
||||
extensions: ['.js', '.scss'],
|
||||
},
|
||||
|
||||
module: {
|
||||
strictExportPresence: true,
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
enforce: 'pre',
|
||||
loader: 'eslint-loader',
|
||||
include: path.resolve(__dirname, '../src/js'),
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
use: [
|
||||
|
|
@ -45,10 +39,10 @@ module.exports = {
|
|||
loader: 'babel-loader',
|
||||
options: {
|
||||
cacheDirectory: true,
|
||||
presets: ['env']
|
||||
}
|
||||
}
|
||||
]
|
||||
presets: ['@babel/preset-env'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
|
|
@ -57,36 +51,34 @@ module.exports = {
|
|||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
importLoaders: 1
|
||||
}
|
||||
importLoaders: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
config: {
|
||||
path: path.join(__dirname, 'postcss.config.js')
|
||||
}
|
||||
}
|
||||
plugins: [autoprefixer, cssnano],
|
||||
},
|
||||
},
|
||||
'sass-loader'
|
||||
]
|
||||
'sass-loader',
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg)$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
'limit': 40000
|
||||
}
|
||||
limit: 40000,
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.svg$/,
|
||||
loader: 'svg-inline-loader'
|
||||
loader: 'svg-inline-loader',
|
||||
},
|
||||
{
|
||||
test: /\.art$/,
|
||||
loader: 'art-template-loader'
|
||||
}
|
||||
]
|
||||
loader: 'art-template-loader',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
devServer: {
|
||||
|
|
@ -96,29 +88,28 @@ module.exports = {
|
|||
quiet: false,
|
||||
open: true,
|
||||
historyApiFallback: {
|
||||
disableDotRule: true
|
||||
disableDotRule: true,
|
||||
},
|
||||
watchOptions: {
|
||||
ignored: /node_modules/
|
||||
}
|
||||
ignored: /node_modules/,
|
||||
},
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
APLAYER_VERSION: `"${require('../package.json').version}"`,
|
||||
GIT_HASH: JSON.stringify(gitRevisionPlugin.version())
|
||||
})
|
||||
GIT_HASH: JSON.stringify(gitRevisionPlugin.version()),
|
||||
}),
|
||||
],
|
||||
|
||||
node: {
|
||||
dgram: 'empty',
|
||||
fs: 'empty',
|
||||
net: 'empty',
|
||||
tls: 'empty'
|
||||
tls: 'empty',
|
||||
},
|
||||
|
||||
performance: {
|
||||
hints: false
|
||||
}
|
||||
|
||||
hints: false,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
module.exports = {
|
||||
plugins: {
|
||||
'autoprefixer': {}
|
||||
}
|
||||
};
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
/* eslint-disable no-undef */
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const GitRevisionPlugin = require('git-revision-webpack-plugin');
|
||||
const gitRevisionPlugin = new GitRevisionPlugin();
|
||||
const autoprefixer = require('autoprefixer');
|
||||
const cssnano = require('cssnano');
|
||||
|
||||
module.exports = {
|
||||
|
||||
mode: 'production',
|
||||
|
||||
bail: true,
|
||||
|
|
@ -14,7 +13,7 @@ module.exports = {
|
|||
devtool: 'source-map',
|
||||
|
||||
entry: {
|
||||
'APlayer': './src/js/index.js'
|
||||
APlayer: './src/js/index.js',
|
||||
},
|
||||
|
||||
output: {
|
||||
|
|
@ -24,23 +23,17 @@ module.exports = {
|
|||
libraryTarget: 'umd',
|
||||
libraryExport: 'default',
|
||||
umdNamedDefine: true,
|
||||
publicPath: '/'
|
||||
publicPath: '/',
|
||||
},
|
||||
|
||||
resolve: {
|
||||
modules: ['node_modules'],
|
||||
extensions: ['.js', '.scss']
|
||||
extensions: ['.js', '.scss'],
|
||||
},
|
||||
|
||||
module: {
|
||||
strictExportPresence: true,
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
enforce: 'pre',
|
||||
loader: 'eslint-loader',
|
||||
include: path.resolve(__dirname, '../src/js'),
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
use: [
|
||||
|
|
@ -48,61 +41,54 @@ module.exports = {
|
|||
{
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
compact: true,
|
||||
presets: ['env']
|
||||
}
|
||||
}
|
||||
]
|
||||
cacheDirectory: true,
|
||||
presets: ['@babel/preset-env'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
'style-loader',
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
importLoaders: 1,
|
||||
minimize: true,
|
||||
sourceMap: true
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
config: {
|
||||
path: path.join(__dirname, 'postcss.config.js')
|
||||
}
|
||||
}
|
||||
plugins: [autoprefixer, cssnano],
|
||||
},
|
||||
},
|
||||
'sass-loader',
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg)$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
'limit': 40000
|
||||
}
|
||||
limit: 40000,
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.svg$/,
|
||||
loader: 'svg-inline-loader'
|
||||
loader: 'svg-inline-loader',
|
||||
},
|
||||
{
|
||||
test: /\.art$/,
|
||||
loader: 'art-template-loader'
|
||||
}
|
||||
]
|
||||
loader: 'art-template-loader',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
APLAYER_VERSION: `"${require('../package.json').version}"`,
|
||||
GIT_HASH: JSON.stringify(gitRevisionPlugin.version())
|
||||
GIT_HASH: JSON.stringify(gitRevisionPlugin.version()),
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: '[name].min.css'
|
||||
})
|
||||
],
|
||||
|
||||
node: {
|
||||
|
|
@ -110,6 +96,5 @@ module.exports = {
|
|||
fs: 'empty',
|
||||
net: 'empty',
|
||||
tls: 'empty',
|
||||
}
|
||||
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue