Browse Source

refactor: format

DIYgod 5 years ago
parent
commit
1ff15c8d5f

+ 4 - 4
.github/ISSUE_TEMPLATE.md

@@ -2,9 +2,9 @@
 
 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 DPlayer, 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 DPlayer, and which browser / OS are affected by this issue?
 
 <!-- Love DPlayer? Please consider supporting our project:
-👉  https://github.com/MoePlayer/DPlayer#donate -->
+👉  https://github.com/MoePlayer/DPlayer#donate -->

+ 53 - 52
README.md

@@ -20,23 +20,23 @@ DPlayer is a lovely HTML5 danmaku video player to help people build video and da
 
 **DPlayer supports:**
 
-- Streaming formats
-    - [HLS](https://github.com/video-dev/hls.js)
-    - [FLV](https://github.com/Bilibili/flv.js)
-    - [MPEG DASH](https://github.com/Dash-Industry-Forum/dash.js)
-    - [WebTorrent](https://github.com/webtorrent/webtorrent)
-    - Any other custom streaming formats
-- Media formats
-    - MP4 H.264
-    - WebM
-    - Ogg Theora Vorbis
-- Features
-    - Danmaku
-    - Screenshot
-    - Hotkeys
-    - Quality switching
-    - Thumbnails
-    - Subtitle
+-   Streaming formats
+    -   [HLS](https://github.com/video-dev/hls.js)
+    -   [FLV](https://github.com/Bilibili/flv.js)
+    -   [MPEG DASH](https://github.com/Dash-Industry-Forum/dash.js)
+    -   [WebTorrent](https://github.com/webtorrent/webtorrent)
+    -   Any other custom streaming formats
+-   Media formats
+    -   MP4 H.264
+    -   WebM
+    -   Ogg Theora Vorbis
+-   Features
+    -   Danmaku
+    -   Screenshot
+    -   Hotkeys
+    -   Quality switching
+    -   Thumbnails
+    -   Subtitle
 
 Using DPlayer on your project? [Let me know!](https://github.com/DIYgod/DPlayer/issues/31)
 
@@ -69,7 +69,8 @@ Using DPlayer on your project? [Let me know!](https://github.com/DIYgod/DPlayer/
 ### Sponsors
 
 | [极酷社](https://www.acg.app) |
-| :--------------------------: |
+| :---------------------------: |
+
 
 ### Contributors
 
@@ -77,7 +78,7 @@ Using DPlayer on your project? [Let me know!](https://github.com/DIYgod/DPlayer/
 
 ## Join the Discussion
 
-- [Telegram Group](https://t.me/adplayer)
+-   [Telegram Group](https://t.me/adplayer)
 
 ## Related Projects
 
@@ -85,46 +86,46 @@ Feel free to submit yours in [`Let me know!`](https://github.com/MoePlayer/DPlay
 
 ### Tooling
 
-- [DPlayer-thumbnails](https://github.com/MoePlayer/DPlayer-thumbnails): generate video thumbnails
+-   [DPlayer-thumbnails](https://github.com/MoePlayer/DPlayer-thumbnails): generate video thumbnails
 
 ### Danmaku api
 
-- [DPlayer-node](https://github.com/MoePlayer/DPlayer-node): Node.js
-- [laravel-danmaku](https://github.com/MoePlayer/laravel-danmaku): PHP
-- [dplayer-live-backend](https://github.com/Izumi-kun/dplayer-live-backend): Node.js, WebSocket live backend
-- [RailsGun](https://github.com/MoePlayer/RailsGun): Ruby
+-   [DPlayer-node](https://github.com/MoePlayer/DPlayer-node): Node.js
+-   [laravel-danmaku](https://github.com/MoePlayer/laravel-danmaku): PHP
+-   [dplayer-live-backend](https://github.com/Izumi-kun/dplayer-live-backend): Node.js, WebSocket live backend
+-   [RailsGun](https://github.com/MoePlayer/RailsGun): Ruby
 
 ### Plugins
 
-- [DPlayer-for-typecho](https://github.com/volio/DPlayer-for-typecho): Typecho
-- [Hexo-tag-dplayer](https://github.com/NextMoe/hexo-tag-dplayer): Hexo
-- [DPlayer_for_Z-BlogPHP](https://github.com/fghrsh/DPlayer_for_Z-BlogPHP): Z-BlogPHP
-- [DPlayer for Discuz!](https://coding.net/u/Click_04/p/video/git): Discuz!
-- [DPlayer for WordPress](https://github.com/BlueCocoa/DPlayer-WordPress): WordPress
-- [DPlayerHandle](https://github.com/kn007/DPlayerHandle): WordPress
-- [Selection](https://github.com/GreatSatan79/Selection): WordPress
-- [Vue-DPlayer](https://github.com/sinchang/vue-dplayer): Vue
-- [react-dplayer](https://github.com/hnsylitao/react-dplayer): React
+-   [DPlayer-for-typecho](https://github.com/volio/DPlayer-for-typecho): Typecho
+-   [Hexo-tag-dplayer](https://github.com/NextMoe/hexo-tag-dplayer): Hexo
+-   [DPlayer_for_Z-BlogPHP](https://github.com/fghrsh/DPlayer_for_Z-BlogPHP): Z-BlogPHP
+-   [DPlayer for Discuz!](https://coding.net/u/Click_04/p/video/git): Discuz!
+-   [DPlayer for WordPress](https://github.com/BlueCocoa/DPlayer-WordPress): WordPress
+-   [DPlayerHandle](https://github.com/kn007/DPlayerHandle): WordPress
+-   [Selection](https://github.com/GreatSatan79/Selection): WordPress
+-   [Vue-DPlayer](https://github.com/sinchang/vue-dplayer): Vue
+-   [react-dplayer](https://github.com/hnsylitao/react-dplayer): React
 
 ### Other
 
-- [DPlayer-Lite](https://github.com/kn007/DPlayer-Lite): lite version
-- [hlsjs-p2p-engine](https://github.com/cdnbye/hlsjs-p2p-engine)
-- Feel free to submit yours in [`Let me know!`](https://github.com/MoePlayer/DPlayer/issues/31)
+-   [DPlayer-Lite](https://github.com/kn007/DPlayer-Lite): lite version
+-   [hlsjs-p2p-engine](https://github.com/cdnbye/hlsjs-p2p-engine)
+-   Feel free to submit yours in [`Let me know!`](https://github.com/MoePlayer/DPlayer/issues/31)
 
 ## Who use DPlayer?
 
-- [学习强国](https://itunes.apple.com/cn/app/%E5%AD%A6%E4%B9%A0%E5%BC%BA%E5%9B%BD/id1426355645?mt=8): “学习强国”学习平台精心打造的手机客户端
-- [小红书](https://www.xiaohongshu.com/): 中国最大的生活社区分享平台,同时也是发现全球好物的电商平台
-- [极客时间](https://time.geekbang.org/): 极客邦科技出品的一款 IT 内容知识服务 App
-- [嘀哩嘀哩](http://www.dilidili.wang/): 兴趣使然的无名小站(D站)
-- [银色子弹](https://www.sbsub.com/): 银色子弹,简称银弹,由多数柯南热爱者聚集在一起的组织
-- [浙江大学CC98论坛](https://zh.wikipedia.org/wiki/CC98%E8%AE%BA%E5%9D%9B): 浙江大学校网内规模最大的论坛,中国各大学中较活跃的BBS之一
-- [纸飞机南航青年网络社区](http://my.nuaa.edu.cn/video-video.html): 南京航空航天大学门户网站
-- [otomads](https://otomads.com/): 专注于音MAD的视频弹幕网站
-- [Cloudreve](https://github.com/HFO4/Cloudreve): 基于ThinkPHP构建的网盘系统
-- [oneindex](https://github.com/donwa/oneindex): Onedrive Directory Index
-- Feel free to submit yours in [`Let me know!`](https://github.com/MoePlayer/DPlayer/issues/31)
+-   [学习强国](https://itunes.apple.com/cn/app/%E5%AD%A6%E4%B9%A0%E5%BC%BA%E5%9B%BD/id1426355645?mt=8): “学习强国”学习平台精心打造的手机客户端
+-   [小红书](https://www.xiaohongshu.com/): 中国最大的生活社区分享平台,同时也是发现全球好物的电商平台
+-   [极客时间](https://time.geekbang.org/): 极客邦科技出品的一款 IT 内容知识服务 App
+-   [嘀哩嘀哩](http://www.dilidili.wang/): 兴趣使然的无名小站(D 站)
+-   [银色子弹](https://www.sbsub.com/): 银色子弹,简称银弹,由多数柯南热爱者聚集在一起的组织
+-   [浙江大学 CC98 论坛](https://zh.wikipedia.org/wiki/CC98%E8%AE%BA%E5%9D%9B): 浙江大学校网内规模最大的论坛,中国各大学中较活跃的 BBS 之一
+-   [纸飞机南航青年网络社区](http://my.nuaa.edu.cn/video-video.html): 南京航空航天大学门户网站
+-   [otomads](https://otomads.com/): 专注于音 MAD 的视频弹幕网站
+-   [Cloudreve](https://github.com/HFO4/Cloudreve): 基于 ThinkPHP 构建的网盘系统
+-   [oneindex](https://github.com/donwa/oneindex): Onedrive Directory Index
+-   Feel free to submit yours in [`Let me know!`](https://github.com/MoePlayer/DPlayer/issues/31)
 
 ## Donate
 
@@ -134,16 +135,16 @@ DPlayer 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)
+-   [Paypal](https://www.paypal.me/DIYgod)
+-   [WeChat Pay](https://i.imgur.com/aq6PtWa.png)
+-   [Alipay](https://i.imgur.com/wv1Pj2k.png)
 
 ## Recurring Pledges
 
 Recurring pledges come with exclusive perks, e.g. enabling faster GitHub response, having your name or your company logo listed in the DPlayer GitHub repository and this website.
 
-- Become a backer or sponsor via [Patreon](https://www.patreon.com/DIYgod)
-- E-mail us: i#html.love
+-   Become a backer or sponsor via [Patreon](https://www.patreon.com/DIYgod)
+-   E-mail us: i#html.love
 
 ## Author
 

+ 1 - 1
docs/README.md

@@ -12,4 +12,4 @@ footer: MIT Licensed | Made with love by DIYgod
   <DPlayer :immediate="true"></DPlayer>
 </div>
 
-<div class="hero custom"><p class="action"><router-link to="/guide/" class="nav-link action-button">Get Started →</router-link></p></div>
+<div class="hero custom"><p class="action"><router-link to="/guide/" class="nav-link action-button">Get Started →</router-link></p></div>

+ 28 - 28
docs/ecosystem.md

@@ -10,56 +10,56 @@ Let's make DPlayer better, feel free to submit yours in [`Let me know!`](https:/
 
 ### Joining the Discussion
 
-- [Telegram Group](https://t.me/adplayer)
+-   [Telegram Group](https://t.me/adplayer)
 
 ### Creating issue
 
-- [MoePlayer/DPlayer/issues](https://github.com/MoePlayer/DPlayer/issues)
+-   [MoePlayer/DPlayer/issues](https://github.com/MoePlayer/DPlayer/issues)
 
 ## Related Projects
 
 ### Tooling
 
-- [DPlayer-thumbnails](https://github.com/MoePlayer/DPlayer-thumbnails): generate video thumbnails
+-   [DPlayer-thumbnails](https://github.com/MoePlayer/DPlayer-thumbnails): generate video thumbnails
 
 ### Danamku api
 
-- [DPlayer-node](https://github.com/MoePlayer/DPlayer-node): Node.js
-- [laravel-danmaku](https://github.com/MoePlayer/laravel-danmaku): PHP
-- [dplayer-live-backend](https://github.com/Izumi-kun/dplayer-live-backend): Node.js, WebSocket live backend
-- [RailsGun](https://github.com/MoePlayer/RailsGun): Ruby
+-   [DPlayer-node](https://github.com/MoePlayer/DPlayer-node): Node.js
+-   [laravel-danmaku](https://github.com/MoePlayer/laravel-danmaku): PHP
+-   [dplayer-live-backend](https://github.com/Izumi-kun/dplayer-live-backend): Node.js, WebSocket live backend
+-   [RailsGun](https://github.com/MoePlayer/RailsGun): Ruby
 
 ### Plugins
 
-- [DPlayer-for-typecho](https://github.com/volio/DPlayer-for-typecho): Typecho
-- [Hexo-tag-dplayer](https://github.com/NextMoe/hexo-tag-dplayer): Hexo
-- [DPlayer_for_Z-BlogPHP](https://github.com/fghrsh/DPlayer_for_Z-BlogPHP): Z-BlogPHP
-- [DPlayer for Discuz!](https://coding.net/u/Click_04/p/video/git): Discuz!
-- [DPlayer for WordPress](https://github.com/BlueCocoa/DPlayer-WordPress): WordPress
-- [DPlayerHandle](https://github.com/kn007/DPlayerHandle): WordPress
-- [Selection](https://github.com/GreatSatan79/Selection): WordPress
-- [Vue-DPlayer](https://github.com/sinchang/vue-dplayer): Vue
-- [react-dplayer](https://github.com/hnsylitao/react-dplayer): React
+-   [DPlayer-for-typecho](https://github.com/volio/DPlayer-for-typecho): Typecho
+-   [Hexo-tag-dplayer](https://github.com/NextMoe/hexo-tag-dplayer): Hexo
+-   [DPlayer_for_Z-BlogPHP](https://github.com/fghrsh/DPlayer_for_Z-BlogPHP): Z-BlogPHP
+-   [DPlayer for Discuz!](https://coding.net/u/Click_04/p/video/git): Discuz!
+-   [DPlayer for WordPress](https://github.com/BlueCocoa/DPlayer-WordPress): WordPress
+-   [DPlayerHandle](https://github.com/kn007/DPlayerHandle): WordPress
+-   [Selection](https://github.com/GreatSatan79/Selection): WordPress
+-   [Vue-DPlayer](https://github.com/sinchang/vue-dplayer): Vue
+-   [react-dplayer](https://github.com/hnsylitao/react-dplayer): React
 
 ### Other
 
-- [DPlayer-Lite](https://github.com/kn007/DPlayer-Lite): lite version
-- [hlsjs-p2p-engine](https://github.com/cdnbye/hlsjs-p2p-engine)
+-   [DPlayer-Lite](https://github.com/kn007/DPlayer-Lite): lite version
+-   [hlsjs-p2p-engine](https://github.com/cdnbye/hlsjs-p2p-engine)
 
 ## Who use DPlayer?
 
-- [学习强国](https://itunes.apple.com/cn/app/%E5%AD%A6%E4%B9%A0%E5%BC%BA%E5%9B%BD/id1426355645?mt=8): “学习强国”学习平台精心打造的手机客户端
-- [小红书](https://www.xiaohongshu.com/): 中国最大的生活社区分享平台,同时也是发现全球好物的电商平台
-- [极客时间](https://time.geekbang.org/): 极客邦科技出品的一款 IT 内容知识服务 App
-- [嘀哩嘀哩](http://www.dilidili.wang/): 兴趣使然的无名小站(D站)
-- [银色子弹](https://www.sbsub.com/): 银色子弹,简称银弹,由多数柯南热爱者聚集在一起的组织
-- [浙江大学CC98论坛](https://zh.wikipedia.org/wiki/CC98%E8%AE%BA%E5%9D%9B): 浙江大学校网内规模最大的论坛,中国各大学中较活跃的BBS之一
-- [纸飞机南航青年网络社区](http://my.nuaa.edu.cn/video-video.html): 南京航空航天大学门户网站
-- [otomads](https://otomads.com/): 专注于音MAD的视频弹幕网站
-- [Cloudreve](https://github.com/HFO4/Cloudreve): 基于ThinkPHP构建的网盘系统
+-   [学习强国](https://itunes.apple.com/cn/app/%E5%AD%A6%E4%B9%A0%E5%BC%BA%E5%9B%BD/id1426355645?mt=8): “学习强国”学习平台精心打造的手机客户端
+-   [小红书](https://www.xiaohongshu.com/): 中国最大的生活社区分享平台,同时也是发现全球好物的电商平台
+-   [极客时间](https://time.geekbang.org/): 极客邦科技出品的一款 IT 内容知识服务 App
+-   [嘀哩嘀哩](http://www.dilidili.wang/): 兴趣使然的无名小站(D 站)
+-   [银色子弹](https://www.sbsub.com/): 银色子弹,简称银弹,由多数柯南热爱者聚集在一起的组织
+-   [浙江大学 CC98 论坛](https://zh.wikipedia.org/wiki/CC98%E8%AE%BA%E5%9D%9B): 浙江大学校网内规模最大的论坛,中国各大学中较活跃的 BBS 之一
+-   [纸飞机南航青年网络社区](http://my.nuaa.edu.cn/video-video.html): 南京航空航天大学门户网站
+-   [otomads](https://otomads.com/): 专注于音 MAD 的视频弹幕网站
+-   [Cloudreve](https://github.com/HFO4/Cloudreve): 基于 ThinkPHP 构建的网盘系统
 
 ## Contributors
 
 This project exists thanks to all the people who contribute.
 
-<a href="https://github.com/MoePlayer/DPlayer/graphs/contributors"><img src="https://opencollective.com/DPlayer/contributors.svg?width=890" /></a>
+<a href="https://github.com/MoePlayer/DPlayer/graphs/contributors"><img src="https://opencollective.com/DPlayer/contributors.svg?width=890" /></a>

+ 259 - 247
docs/guide.md

@@ -44,7 +44,8 @@ sidebar: auto
 ### Sponsors
 
 | [极酷社](https://www.acg.app) |
-| :--------------------------: |
+| :---------------------------: |
+
 
 ## Installation
 
@@ -67,7 +68,7 @@ At first, let's initialize a simplest DPlayer
 Load DPlayer files
 
 ```html
-<link rel="stylesheet" href="DPlayer.min.css">
+<link rel="stylesheet" href="DPlayer.min.css" />
 <div id="dplayer"></div>
 <script src="DPlayer.min.js"></script>
 ```
@@ -90,15 +91,15 @@ const dp = new DPlayer({
     video: {
         url: 'demo.mp4',
         pic: 'demo.jpg',
-        thumbnails: 'thumbnails.jpg'
+        thumbnails: 'thumbnails.jpg',
     },
     subtitle: {
-        url: 'webvtt.vtt'
+        url: 'webvtt.vtt',
     },
     danmaku: {
         id: 'demo',
-        api: 'https://api.prprpr.me/dplayer/'
-    }
+        api: 'https://api.prprpr.me/dplayer/',
+    },
 });
 ```
 
@@ -106,46 +107,46 @@ const dp = new DPlayer({
 
 You can custom your player instance by those options
 
-Name | Default | Description
-----|-------|----
-container | document.querySelector('.dplayer') | player container
-live | false | enable live mode, see [#live](#live)
-autoplay | false | video autoplay
-theme | '#b7daff' | main color
-loop | false | video loop
-lang | navigator.language.toLowerCase() | values: 'en', 'zh-cn', 'zh-tw'
-screenshot | false | enable screenshot, if true, video and video poster must enable Cross-Origin
-hotkey | true | enable hotkey, support FF, FR, volume control, play & pause
-preload | 'auto' | values: 'none', 'metadata', 'auto'
-volume | 0.7 | default volume, notice that player will remember user setting, default volume will not work after user set volume themselves
-logo | - | showing logo in the top left corner, you can adjust its size and position by CSS
-apiBackend | - | getting and sending danmaku in your way, see [#live](#live)
-video | - | video info
-video.quality | - | see [#Quality switching](#quality-switching)
-video.defaultQuality | - | see [#Quality switching](#quality-switching)
-video.url | - | video url
-video.pic | - | video poster
-video.thumbnails | - | video thumbnails, generated by [DPlayer-thumbnails](https://github.com/MoePlayer/DPlayer-thumbnails)
-video.type | 'auto' | values: 'auto', 'hls', 'flv', 'dash', 'webtorrent', 'normal' or other custom type, see [#MSE support](#mse-support)
-video.customType | - | custom video type, see [#MSE support](#mse-support)
-subtitle | - | external subtitle
-subtitle.url | `required` | subtitle url
-subtitle.type | 'webvtt' | subtitle type, values: 'webvtt', 'ass', but only webvtt is supported for now
-subtitle.fontSize | '20px' | subtitle font size
-subtitle.bottom | '40px' | the distance between the subtitle and player bottom, values like: '10px' '10%'
-subtitle.color | '#fff' | subtitle color
-danmaku | - | showing danmaku
-danmaku.id | `required` | danamku pool id, it must be unique
-danmaku.api | `required` | see [#Danmaku API](#danmaku-api)
-danmaku.token | - | back end verification token
-danmaku.maximum | - | danmaku maximum quantity
-danmaku.addition | - | additional danmaku, see [#bilibili danmaku](#bilibili-danmaku)
-danmaku.user | 'DIYgod' | danmaku user name
-danmaku.bottom | - | values like: '10px' '10%', the distance between the danmaku bottom and player bottom, in order to prevent warding off subtitle
-danmaku.unlimited | false | display all danmaku even though danmaku overlap, notice that player will remember user setting, default setting will not work after user set it themselves
-contextmenu | [] | custom contextmenu
-highlight | [] | custom time markers upon progress bar
-mutex | true | prevent to play multiple player at the same time, pause other players when this player start play
+| Name                 | Default                            | Description                                                                                                                                                |
+| -------------------- | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| container            | document.querySelector('.dplayer') | player container                                                                                                                                           |
+| live                 | false                              | enable live mode, see [#live](#live)                                                                                                                       |
+| autoplay             | false                              | video autoplay                                                                                                                                             |
+| theme                | '#b7daff'                          | main color                                                                                                                                                 |
+| loop                 | false                              | video loop                                                                                                                                                 |
+| lang                 | navigator.language.toLowerCase()   | values: 'en', 'zh-cn', 'zh-tw'                                                                                                                             |
+| screenshot           | false                              | enable screenshot, if true, video and video poster must enable Cross-Origin                                                                                |
+| hotkey               | true                               | enable hotkey, support FF, FR, volume control, play & pause                                                                                                |
+| preload              | 'auto'                             | values: 'none', 'metadata', 'auto'                                                                                                                         |
+| volume               | 0.7                                | default volume, notice that player will remember user setting, default volume will not work after user set volume themselves                               |
+| logo                 | -                                  | showing logo in the top left corner, you can adjust its size and position by CSS                                                                           |
+| apiBackend           | -                                  | getting and sending danmaku in your way, see [#live](#live)                                                                                                |
+| video                | -                                  | video info                                                                                                                                                 |
+| video.quality        | -                                  | see [#Quality switching](#quality-switching)                                                                                                               |
+| video.defaultQuality | -                                  | see [#Quality switching](#quality-switching)                                                                                                               |
+| video.url            | -                                  | video url                                                                                                                                                  |
+| video.pic            | -                                  | video poster                                                                                                                                               |
+| video.thumbnails     | -                                  | video thumbnails, generated by [DPlayer-thumbnails](https://github.com/MoePlayer/DPlayer-thumbnails)                                                       |
+| video.type           | 'auto'                             | values: 'auto', 'hls', 'flv', 'dash', 'webtorrent', 'normal' or other custom type, see [#MSE support](#mse-support)                                        |
+| video.customType     | -                                  | custom video type, see [#MSE support](#mse-support)                                                                                                        |
+| subtitle             | -                                  | external subtitle                                                                                                                                          |
+| subtitle.url         | `required`                         | subtitle url                                                                                                                                               |
+| subtitle.type        | 'webvtt'                           | subtitle type, values: 'webvtt', 'ass', but only webvtt is supported for now                                                                               |
+| subtitle.fontSize    | '20px'                             | subtitle font size                                                                                                                                         |
+| subtitle.bottom      | '40px'                             | the distance between the subtitle and player bottom, values like: '10px' '10%'                                                                             |
+| subtitle.color       | '#fff'                             | subtitle color                                                                                                                                             |
+| danmaku              | -                                  | showing danmaku                                                                                                                                            |
+| danmaku.id           | `required`                         | danamku pool id, it must be unique                                                                                                                         |
+| danmaku.api          | `required`                         | see [#Danmaku API](#danmaku-api)                                                                                                                           |
+| danmaku.token        | -                                  | back end verification token                                                                                                                                |
+| danmaku.maximum      | -                                  | danmaku maximum quantity                                                                                                                                   |
+| danmaku.addition     | -                                  | additional danmaku, see [#bilibili danmaku](#bilibili-danmaku)                                                                                             |
+| danmaku.user         | 'DIYgod'                           | danmaku user name                                                                                                                                          |
+| danmaku.bottom       | -                                  | values like: '10px' '10%', the distance between the danmaku bottom and player bottom, in order to prevent warding off subtitle                             |
+| danmaku.unlimited    | false                              | display all danmaku even though danmaku overlap, notice that player will remember user setting, default setting will not work after user set it themselves |
+| contextmenu          | []                                 | custom contextmenu                                                                                                                                         |
+| highlight            | []                                 | custom time markers upon progress bar                                                                                                                      |
+| mutex                | true                               | prevent to play multiple player at the same time, pause other players when this player start play                                                          |
 
 ```js
 const dp = new DPlayer({
@@ -164,14 +165,14 @@ const dp = new DPlayer({
         url: 'dplayer.mp4',
         pic: 'dplayer.png',
         thumbnails: 'thumbnails.jpg',
-        type: 'auto'
+        type: 'auto',
     },
     subtitle: {
         url: 'dplayer.vtt',
         type: 'webvtt',
         fontSize: '25px',
         bottom: '10%',
-        color: '#b7daff'
+        color: '#b7daff',
     },
     danmaku: {
         id: '9E2E3368B56CDBB4',
@@ -181,204 +182,210 @@ const dp = new DPlayer({
         addition: ['https://api.prprpr.me/dplayer/v3/bilibili?aid=4157142'],
         user: 'DIYgod',
         bottom: '15%',
-        unlimited: true
+        unlimited: true,
     },
     contextmenu: [
         {
             text: 'custom1',
-            link: 'https://github.com/DIYgod/DPlayer'
+            link: 'https://github.com/DIYgod/DPlayer',
         },
         {
             text: 'custom2',
             click: (player) => {
                 console.log(player);
-            }
-        }
+            },
+        },
     ],
     highlight: [
         {
             text: 'marker for 20s',
-            time: 20
+            time: 20,
         },
         {
             text: 'marker for 2mins',
-            time: 120
-        }
-    ]
+            time: 120,
+        },
+    ],
 });
 ```
 
 ## API
 
-+ `dp.play()`: play video
+-   `dp.play()`: play video
 
-+ `dp.pause()`: pause video
+-   `dp.pause()`: pause video
 
-+ `dp.seek(time: number)`: seek to specified time
+-   `dp.seek(time: number)`: seek to specified time
 
-  ```js
-  dp.seek(100);
-  ```
+    ```js
+    dp.seek(100);
+    ```
 
-+ `dp.toggle()`: toggle between play and pause
+-   `dp.toggle()`: toggle between play and pause
 
-+ `dp.on(event: string, handler: function)`: bind video and player events, [see more details](http://dplayer.js.org/#/home?id=event-binding)
+-   `dp.on(event: string, handler: function)`: bind video and player events, [see more details](http://dplayer.js.org/#/home?id=event-binding)
 
-+ `dp.switchVideo(video, danmaku)`: switch to a new video
+-   `dp.switchVideo(video, danmaku)`: switch to a new video
 
-  ```js
-  dp.switchVideo({
-      url: 'second.mp4',
-      pic: 'second.png',
-      thumbnails: 'second.jpg'
-  }, {
-      id: 'test',
-      api: 'https://api.prprpr.me/dplayer/',
-      maximum: 3000,
-      user: 'DIYgod'
-  });
-  ```
+    ```js
+    dp.switchVideo(
+        {
+            url: 'second.mp4',
+            pic: 'second.png',
+            thumbnails: 'second.jpg',
+        },
+        {
+            id: 'test',
+            api: 'https://api.prprpr.me/dplayer/',
+            maximum: 3000,
+            user: 'DIYgod',
+        }
+    );
+    ```
 
-+ `dp.notice(text: string, time: number, opacity: number)`: show message, the unit of time is millisecond, the default of time is 2000, the default of opacity is 0.8
+-   `dp.notice(text: string, time: number, opacity: number)`: show message, the unit of time is millisecond, the default of time is 2000, the default of opacity is 0.8
 
-  ```js
-  dp.notice('Amazing player', 2000, 0.8);
-  ```
+    ```js
+    dp.notice('Amazing player', 2000, 0.8);
+    ```
 
-+ `dp.switchQuality(index: number)`: switch quality
+-   `dp.switchQuality(index: number)`: switch quality
 
-+ `dp.destroy()`: destroy player
+-   `dp.destroy()`: destroy player
 
-+ `dp.speed(rate: number)`: set video speed
+-   `dp.speed(rate: number)`: set video speed
 
-+ `dp.volume(percentage: number, nostorage: boolean, nonotice: boolean)`: set video volume
+-   `dp.volume(percentage: number, nostorage: boolean, nonotice: boolean)`: set video volume
 
-  ```js
-  dp.volume(0.1, true, false);
-  ```
+    ```js
+    dp.volume(0.1, true, false);
+    ```
 
-+ `dp.video`: native video
+-   `dp.video`: native video
 
- + `dp.video.currentTime`: returns the current playback position
+-   `dp.video.currentTime`: returns the current playback position
 
- + `dp.video.duration`: returns video total time
+-   `dp.video.duration`: returns video total time
 
- + `dp.video.paused`: returns whether the video paused
+-   `dp.video.paused`: returns whether the video paused
 
- + most [native api](http://www.w3schools.com/tags/ref_av_dom.asp) are supported
+-   most [native api](http://www.w3schools.com/tags/ref_av_dom.asp) are supported
 
-+ `dp.danmaku`
+-   `dp.danmaku`
 
- + `dp.danmaku.send(danmaku, callback: function)`: submit a new danmaku to back end
+-   `dp.danmaku.send(danmaku, callback: function)`: submit a new danmaku to back end
 
-   ```js
-   dp.danmaku.send({
-       text: 'dplayer is amazing',
-       color: '#b7daff',
-       type: 'right'   // should be `top` `bottom` or `right`
-   }, function () {
-       console.log('success');
-   });
-   ```
+    ```js
+    dp.danmaku.send(
+        {
+            text: 'dplayer is amazing',
+            color: '#b7daff',
+            type: 'right', // should be `top` `bottom` or `right`
+        },
+        function() {
+            console.log('success');
+        }
+    );
+    ```
 
- + `dp.danmaku.draw(danmaku)`: draw a new danmaku to player in real time
+-   `dp.danmaku.draw(danmaku)`: draw a new danmaku to player in real time
 
-   ```js
-   dp.danmaku.draw({
-       text: 'DIYgod is amazing',
-       color: '#fff',
-       type: 'top'
-   });
-   ```
+    ```js
+    dp.danmaku.draw({
+        text: 'DIYgod is amazing',
+        color: '#fff',
+        type: 'top',
+    });
+    ```
 
- + `dp.danmaku.opacity(percentage: number)`: set danmaku opacity, opacity should between 0 and 1
+-   `dp.danmaku.opacity(percentage: number)`: set danmaku opacity, opacity should between 0 and 1
 
-   ```js
-   dp.danmaku.opacity(0.5);
-   ```
+    ```js
+    dp.danmaku.opacity(0.5);
+    ```
 
- + `dp.danmaku.clear()`: clear all danmakus
+-   `dp.danmaku.clear()`: clear all danmakus
 
- + `dp.danmaku.hide()`: hide danmaku
+-   `dp.danmaku.hide()`: hide danmaku
 
- + `dp.danmaku.show()`: show danmaku
+-   `dp.danmaku.show()`: show danmaku
 
-+ `dp.fullScreen`: two type: `web` or `browser`, the default one is `browser`
+-   `dp.fullScreen`: two type: `web` or `browser`, the default one is `browser`
 
- + `dp.fullScreen.request(type: string)`: request fullscreen
+-   `dp.fullScreen.request(type: string)`: request fullscreen
 
-   ```js
-   dp.fullScreen.request('web');
-   ```
+    ```js
+    dp.fullScreen.request('web');
+    ```
 
- + `dp.fullScreen.cancel(type: string)`: cancel fullscreen
+-   `dp.fullScreen.cancel(type: string)`: cancel fullscreen
 
-   ```js
-   dp.fullScreen.cancel('web');
-   ```
+    ```js
+    dp.fullScreen.cancel('web');
+    ```
 
 ## Event binding
 
 `dp.on(event, handler)`
 
 ```js
-dp.on('ended', function () {
+dp.on('ended', function() {
     console.log('player ended');
 });
 ```
 
 Video events
 
-- abort
-- canplay
-- canplaythrough
-- durationchange
-- emptied
-- ended
-- error
-- loadeddata
-- loadedmetadata
-- loadstart
-- mozaudioavailable
-- pause
-- play
-- playing
-- progress
-- ratechange
-- seeked
-- seeking
-- stalled
-- suspend
-- timeupdate
-- volumechange
-- waiting
+-   abort
+-   canplay
+-   canplaythrough
+-   durationchange
+-   emptied
+-   ended
+-   error
+-   loadeddata
+-   loadedmetadata
+-   loadstart
+-   mozaudioavailable
+-   pause
+-   play
+-   playing
+-   progress
+-   ratechange
+-   seeked
+-   seeking
+-   stalled
+-   suspend
+-   timeupdate
+-   volumechange
+-   waiting
 
 Player events
 
-- screenshot
-- thumbnails_show
-- thumbnails_hide
-- danmaku_show
-- danmaku_hide
-- danmaku_clear
-- danmaku_loaded
-- danmaku_send
-- danmaku_opacity
-- contextmenu_show
-- contextmenu_hide
-- notice_show
-- notice_hide
-- quality_start
-- quality_end
-- destroy
-- resize
-- fullscreen
-- fullscreen_cancel
-- webfullscreen
-- webfullscreen_cancel
-- subtitle_show
-- subtitle_hide
-- subtitle_change
+-   screenshot
+-   thumbnails_show
+-   thumbnails_hide
+-   danmaku_show
+-   danmaku_hide
+-   danmaku_clear
+-   danmaku_loaded
+-   danmaku_send
+-   danmaku_opacity
+-   contextmenu_show
+-   contextmenu_hide
+-   notice_show
+-   notice_hide
+-   quality_start
+-   quality_end
+-   destroy
+-   resize
+-   fullscreen
+-   fullscreen_cancel
+-   webfullscreen
+-   webfullscreen_cancel
+-   subtitle_show
+-   subtitle_hide
+-   subtitle_change
 
 ## Quality switching
 
@@ -405,19 +412,22 @@ Set video url and video type in `video.quality`, set default quality by `video.d
 const dp = new DPlayer({
     container: document.getElementById('dplayer'),
     video: {
-        quality: [{
-            name: 'HD',
-            url: 'demo.m3u8',
-            type: 'hls'
-        }, {
-            name: 'SD',
-            url: 'demo.mp4',
-            type: 'normal'
-        }],
+        quality: [
+            {
+                name: 'HD',
+                url: 'demo.m3u8',
+                type: 'hls',
+            },
+            {
+                name: 'SD',
+                url: 'demo.mp4',
+                type: 'normal',
+            },
+        ],
         defaultQuality: 0,
         pic: 'demo.png',
         thumbnails: 'thumbnails.jpg',
-    }
+    },
 });
 ```
 
@@ -447,9 +457,9 @@ API: <https://api.prprpr.me/dplayer/v3/bilibili?aid=[aid]>
 const option = {
     danmaku: {
         // ...
-        addition: ['https://api.prprpr.me/dplayer/v3/bilibili?aid=[aid]']
-    }
-}
+        addition: ['https://api.prprpr.me/dplayer/v3/bilibili?aid=[aid]'],
+    },
+};
 ```
 
 ## MSE support
@@ -466,7 +476,7 @@ It requires the library [hls.js](https://github.com/video-dev/hls.js) and it sho
 }"></DPlayer>
 
 ```html
-<link rel="stylesheet" href="DPlayer.min.css">
+<link rel="stylesheet" href="DPlayer.min.css" />
 <div id="dplayer"></div>
 <script src="hls.min.js"></script>
 <script src="DPlayer.min.js"></script>
@@ -477,8 +487,8 @@ const dp = new DPlayer({
     container: document.getElementById('dplayer'),
     video: {
         url: 'demo.m3u8',
-        type: 'hls'
-    }
+        type: 'hls',
+    },
 });
 ```
 
@@ -490,13 +500,13 @@ const dp = new DPlayer({
         url: 'demo.m3u8',
         type: 'customHls',
         customType: {
-            'customHls': function (video, player) {
+            customHls: function(video, player) {
                 const hls = new Hls();
                 hls.loadSource(video.src);
                 hls.attachMedia(video);
-            }
-        }
-    }
+            },
+        },
+    },
 });
 ```
 
@@ -505,7 +515,7 @@ const dp = new DPlayer({
 It requires the library [dash.js](https://github.com/Dash-Industry-Forum/dash.js) and it should be loaded before `DPlayer.min.js`.
 
 ```html
-<link rel="stylesheet" href="DPlayer.min.css">
+<link rel="stylesheet" href="DPlayer.min.css" />
 <div id="dplayer"></div>
 <script src="dash.min.js"></script>
 <script src="DPlayer.min.js"></script>
@@ -516,8 +526,8 @@ const dp = new DPlayer({
     container: document.getElementById('dplayer'),
     video: {
         url: 'demo.mpd',
-        type: 'dash'
-    }
+        type: 'dash',
+    },
 });
 ```
 
@@ -529,11 +539,14 @@ const dp = new DPlayer({
         url: 'demo.mpd',
         type: 'customDash',
         customType: {
-            'customDash': function (video, player) {
-                dashjs.MediaPlayer().create().initialize(video, video.src, false);
-            }
-        }
-    }
+            customDash: function(video, player) {
+                dashjs
+                    .MediaPlayer()
+                    .create()
+                    .initialize(video, video.src, false);
+            },
+        },
+    },
 });
 ```
 
@@ -542,7 +555,7 @@ const dp = new DPlayer({
 It requires the library [shaka-player](https://github.com/google/shaka-player) and it should be loaded before `DPlayer.min.js`.
 
 ```html
-<link rel="stylesheet" href="DPlayer.min.css">
+<link rel="stylesheet" href="DPlayer.min.css" />
 <div id="dplayer"></div>
 <script src="shaka-player.compiled.js"></script>
 <script src="DPlayer.min.js"></script>
@@ -556,13 +569,13 @@ const dp = new DPlayer({
         url: 'demo.mpd',
         type: 'shakaDash',
         customType: {
-            'shakaDash': function (video, player) {
+            shakaDash: function(video, player) {
                 var src = video.src;
                 var playerShaka = new shaka.Player(video); // 将会修改 video.src
                 playerShaka.load(src);
-            }
-        }
-    }
+            },
+        },
+    },
 });
 ```
 
@@ -578,7 +591,7 @@ It requires the library [flv.js](https://github.com/Bilibili/flv.js) and it shou
 }"></DPlayer>
 
 ```html
-<link rel="stylesheet" href="DPlayer.min.css">
+<link rel="stylesheet" href="DPlayer.min.css" />
 <div id="dplayer"></div>
 <script src="flv.min.js"></script>
 <script src="DPlayer.min.js"></script>
@@ -589,8 +602,8 @@ const dp = new DPlayer({
     container: document.getElementById('dplayer'),
     video: {
         url: 'demo.flv',
-        type: 'flv'
-    }
+        type: 'flv',
+    },
 });
 ```
 
@@ -602,16 +615,16 @@ const dp = new DPlayer({
         url: 'demo.flv',
         type: 'customFlv',
         customType: {
-            'customFlv': function (video, player) {
+            customFlv: function(video, player) {
                 const flvPlayer = flvjs.createPlayer({
                     type: 'flv',
-                    url: video.src
+                    url: video.src,
                 });
                 flvPlayer.attachMediaElement(video);
                 flvPlayer.load();
-            }
-        }
-    }
+            },
+        },
+    },
 });
 ```
 
@@ -627,7 +640,7 @@ It requires the library [webtorrent](https://github.com/webtorrent/webtorrent) a
 }"></DPlayer>
 
 ```html
-<link rel="stylesheet" href="DPlayer.min.css">
+<link rel="stylesheet" href="DPlayer.min.css" />
 <div id="dplayer"></div>
 <script src="webtorrent.min.js"></script>
 <script src="DPlayer.min.js"></script>
@@ -638,8 +651,8 @@ const dp = new DPlayer({
     container: document.getElementById('dplayer'),
     video: {
         url: 'magnet:demo',
-        type: 'webtorrent'
-    }
+        type: 'webtorrent',
+    },
 });
 ```
 
@@ -651,21 +664,25 @@ const dp = new DPlayer({
         url: 'magnet:demo',
         type: 'customWebTorrent',
         customType: {
-            'customWebTorrent': function (video, player) {
+            customWebTorrent: function(video, player) {
                 player.container.classList.add('dplayer-loading');
                 const client = new WebTorrent();
                 const torrentId = video.src;
                 client.add(torrentId, (torrent) => {
                     const file = torrent.files.find((file) => file.name.endsWith('.mp4'));
-                    file.renderTo(video, {
-                        autoplay: player.options.autoplay
-                    }, () => {
-                        player.container.classList.remove('dplayer-loading');
-                    });
+                    file.renderTo(
+                        video,
+                        {
+                            autoplay: player.options.autoplay,
+                        },
+                        () => {
+                            player.container.classList.remove('dplayer-loading');
+                        }
+                    );
                 });
-            }
-        }
-    }
+            },
+        },
+    },
 });
 ```
 
@@ -674,7 +691,7 @@ const dp = new DPlayer({
 DPlayer can work with any MSE library via `customType` option.
 
 ```html
-<link rel="stylesheet" href="DPlayer.min.css">
+<link rel="stylesheet" href="DPlayer.min.css" />
 <div id="dplayer"></div>
 <script src="pearplayer.js"></script>
 <script src="DPlayer.min.js"></script>
@@ -687,14 +704,14 @@ const dp = new DPlayer({
         url: 'https://qq.webrtc.win/tv/Pear-Demo-Yosemite_National_Park.mp4',
         type: 'pearplayer',
         customType: {
-            'pearplayer': function (video, player) {
+            pearplayer: function(video, player) {
                 new PearPlayer(video, {
                     src: video.src,
-                    autoplay: player.options.autoplay
+                    autoplay: player.options.autoplay,
                 });
-            }
-        }
-    }
+            },
+        },
+    },
 });
 ```
 
@@ -718,19 +735,19 @@ const dp = new DPlayer({
     live: true,
     danmaku: true,
     apiBackend: {
-        read: function (options) {
+        read: function(options) {
             console.log('Pretend to connect WebSocket');
             callback();
         },
-        send: function (options) {
+        send: function(options) {
             console.log('Pretend to send danamku via WebSocket', options.data);
             callback();
-        }
+        },
     },
     video: {
         url: 'demo.m3u8',
-        type: 'hls'
-    }
+        type: 'hls',
+    },
 });
 ```
 
@@ -740,7 +757,7 @@ Draw danmaku after getting a danmaku via WebSocket:
 const danmaku = {
     text: 'Get a danamku via WebSocket',
     color: '#fff',
-    type: 'right'
+    type: 'right',
 };
 dp.danmaku.draw(danmaku);
 ```
@@ -754,12 +771,7 @@ If player is contained in a iframe, try adding the `allowfullscreen` attribute t
 For full browser support it should look like this:
 
 ```html
-<iframe src="example.com"
-        allowfullscreen="allowfullscreen"
-        mozallowfullscreen="mozallowfullscreen"
-        msallowfullscreen="msallowfullscreen"
-        oallowfullscreen="oallowfullscreen"
-        webkitallowfullscreen="webkitallowfullscreen"></iframe> 
+<iframe src="example.com" allowfullscreen="allowfullscreen" mozallowfullscreen="mozallowfullscreen" msallowfullscreen="msallowfullscreen" oallowfullscreen="oallowfullscreen" webkitallowfullscreen="webkitallowfullscreen"></iframe>
 ```
 
 ### Why can't player autoplay in some mobile browsers?

+ 8 - 7
docs/support.md

@@ -16,16 +16,16 @@ You can support DPlayer development via the following methods:
 
 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)
+-   [Paypal](https://www.paypal.me/DIYgod)
+-   [WeChat Pay](https://i.imgur.com/aq6PtWa.png)
+-   [Alipay](https://i.imgur.com/wv1Pj2k.png)
 
 ## Recurring Pledges
 
 Recurring pledges come with exclusive perks, e.g. having your name or your company logo listed in the DPlayer GitHub repository and this website.
 
-- Become a Backer or a Sponser on [Patreon](https://www.patreon.com/DIYgod)
-- E-mail us: i#diygod.me
+-   Become a Backer or a Sponser on [Patreon](https://www.patreon.com/DIYgod)
+-   E-mail us: i#diygod.me
 
 ## Current Premium Sponsors
 
@@ -52,10 +52,11 @@ Recurring pledges come with exclusive perks, e.g. having your name or your compa
 ### Sponsors
 
 | [极酷社](https://www.acg.app) |
-| :--------------------------: |
+| :---------------------------: |
+
 
 ## DPlayer contributors
 
 This project exists thanks to all the people who contribute.
 
-<a href="https://github.com/MoePlayer/DPlayer/graphs/contributors"><img src="https://opencollective.com/DPlayer/contributors.svg?width=890" /></a>
+<a href="https://github.com/MoePlayer/DPlayer/graphs/contributors"><img src="https://opencollective.com/DPlayer/contributors.svg?width=890" /></a>

+ 1 - 1
docs/zh/README.md

@@ -12,4 +12,4 @@ footer: MIT Licensed | Made with love by DIYgod
   <DPlayer :immediate="true"></DPlayer>
 </div>
 
-<div class="hero custom"><p class="action"><router-link to="/guide/" class="nav-link action-button">快速上手 →</router-link></p></div>
+<div class="hero custom"><p class="action"><router-link to="/guide/" class="nav-link action-button">快速上手 →</router-link></p></div>

+ 27 - 27
docs/zh/ecosystem.md

@@ -10,50 +10,50 @@ sidebar: auto
 
 ### 参与讨论
 
-- [Telegram 群](https://t.me/adplayer)
+-   [Telegram 群](https://t.me/adplayer)
 
 ### 提交 issue
 
-- [MoePlayer/DPlayer/issues](https://github.com/MoePlayer/DPlayer/issues)
+-   [MoePlayer/DPlayer/issues](https://github.com/MoePlayer/DPlayer/issues)
 
 ## 相关项目
 
 ### 工具
 
-- [DPlayer-thumbnails](https://github.com/MoePlayer/DPlayer-thumbnails): generate video thumbnails
+-   [DPlayer-thumbnails](https://github.com/MoePlayer/DPlayer-thumbnails): generate video thumbnails
 
 ### 弹幕接口
 
-- [DPlayer-node](https://github.com/MoePlayer/DPlayer-node): Node.js
-- [laravel-danmaku](https://github.com/MoePlayer/laravel-danmaku): PHP
-- [dplayer-live-backend](https://github.com/Izumi-kun/dplayer-live-backend): Node.js, WebSocket live backend
-- [RailsGun](https://github.com/MoePlayer/RailsGun): Ruby
+-   [DPlayer-node](https://github.com/MoePlayer/DPlayer-node): Node.js
+-   [laravel-danmaku](https://github.com/MoePlayer/laravel-danmaku): PHP
+-   [dplayer-live-backend](https://github.com/Izumi-kun/dplayer-live-backend): Node.js, WebSocket live backend
+-   [RailsGun](https://github.com/MoePlayer/RailsGun): Ruby
 
 ### 插件
 
-- [DPlayer-for-typecho](https://github.com/volio/DPlayer-for-typecho): Typecho
-- [Hexo-tag-dplayer](https://github.com/NextMoe/hexo-tag-dplayer): Hexo
-- [DPlayer_for_Z-BlogPHP](https://github.com/fghrsh/DPlayer_for_Z-BlogPHP): Z-BlogPHP
-- [DPlayer for Discuz!](https://coding.net/u/Click_04/p/video/git): Discuz!
-- [DPlayer for WordPress](https://github.com/BlueCocoa/DPlayer-WordPress): WordPress
-- [DPlayerHandle](https://github.com/kn007/DPlayerHandle): WordPress
-- [Selection](https://github.com/GreatSatan79/Selection): WordPress
-- [Vue-DPlayer](https://github.com/sinchang/vue-dplayer): Vue
-- [react-dplayer](https://github.com/hnsylitao/react-dplayer): React
+-   [DPlayer-for-typecho](https://github.com/volio/DPlayer-for-typecho): Typecho
+-   [Hexo-tag-dplayer](https://github.com/NextMoe/hexo-tag-dplayer): Hexo
+-   [DPlayer_for_Z-BlogPHP](https://github.com/fghrsh/DPlayer_for_Z-BlogPHP): Z-BlogPHP
+-   [DPlayer for Discuz!](https://coding.net/u/Click_04/p/video/git): Discuz!
+-   [DPlayer for WordPress](https://github.com/BlueCocoa/DPlayer-WordPress): WordPress
+-   [DPlayerHandle](https://github.com/kn007/DPlayerHandle): WordPress
+-   [Selection](https://github.com/GreatSatan79/Selection): WordPress
+-   [Vue-DPlayer](https://github.com/sinchang/vue-dplayer): Vue
+-   [react-dplayer](https://github.com/hnsylitao/react-dplayer): React
 
 ### 其他
 
-- [DPlayer-Lite](https://github.com/kn007/DPlayer-Lite): lite version
-- [hlsjs-p2p-engine](https://github.com/cdnbye/hlsjs-p2p-engine)
+-   [DPlayer-Lite](https://github.com/kn007/DPlayer-Lite): lite version
+-   [hlsjs-p2p-engine](https://github.com/cdnbye/hlsjs-p2p-engine)
 
 ## 谁在用 DPlayer?
 
-- [学习强国](https://itunes.apple.com/cn/app/%E5%AD%A6%E4%B9%A0%E5%BC%BA%E5%9B%BD/id1426355645?mt=8): “学习强国”学习平台精心打造的手机客户端
-- [小红书](https://www.xiaohongshu.com/): 中国最大的生活社区分享平台,同时也是发现全球好物的电商平台
-- [极客时间](https://time.geekbang.org/): 极客邦科技出品的一款 IT 内容知识服务 App
-- [嘀哩嘀哩](http://www.dilidili.wang/): 兴趣使然的无名小站(D站)
-- [银色子弹](https://www.sbsub.com/): 银色子弹,简称银弹,由多数柯南热爱者聚集在一起的组织
-- [浙江大学CC98论坛](https://zh.wikipedia.org/wiki/CC98%E8%AE%BA%E5%9D%9B): 浙江大学校网内规模最大的论坛,中国各大学中较活跃的BBS之一
-- [纸飞机南航青年网络社区](http://my.nuaa.edu.cn/video-video.html): 南京航空航天大学门户网站
-- [otomads](https://otomads.com/): 专注于音MAD的视频弹幕网站
-- [Cloudreve](https://github.com/HFO4/Cloudreve): 基于ThinkPHP构建的网盘系统
+-   [学习强国](https://itunes.apple.com/cn/app/%E5%AD%A6%E4%B9%A0%E5%BC%BA%E5%9B%BD/id1426355645?mt=8): “学习强国”学习平台精心打造的手机客户端
+-   [小红书](https://www.xiaohongshu.com/): 中国最大的生活社区分享平台,同时也是发现全球好物的电商平台
+-   [极客时间](https://time.geekbang.org/): 极客邦科技出品的一款 IT 内容知识服务 App
+-   [嘀哩嘀哩](http://www.dilidili.wang/): 兴趣使然的无名小站(D 站)
+-   [银色子弹](https://www.sbsub.com/): 银色子弹,简称银弹,由多数柯南热爱者聚集在一起的组织
+-   [浙江大学 CC98 论坛](https://zh.wikipedia.org/wiki/CC98%E8%AE%BA%E5%9D%9B): 浙江大学校网内规模最大的论坛,中国各大学中较活跃的 BBS 之一
+-   [纸飞机南航青年网络社区](http://my.nuaa.edu.cn/video-video.html): 南京航空航天大学门户网站
+-   [otomads](https://otomads.com/): 专注于音 MAD 的视频弹幕网站
+-   [Cloudreve](https://github.com/HFO4/Cloudreve): 基于 ThinkPHP 构建的网盘系统

+ 252 - 239
docs/zh/guide.md

@@ -1,6 +1,7 @@
 ---
 sidebar: auto
 ---
+
 # 指南
 
 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dplayer/dist/DPlayer.min.css">
@@ -43,7 +44,8 @@ sidebar: auto
 ### Sponsors
 
 | [极酷社](https://www.acg.app) |
-| :--------------------------: |
+| :---------------------------: |
+
 
 ## 安装
 
@@ -66,7 +68,7 @@ yarn add dplayer
 加载播放器文件:
 
 ```html
-<link rel="stylesheet" href="DPlayer.min.css">
+<link rel="stylesheet" href="DPlayer.min.css" />
 <div id="dplayer"></div>
 <script src="DPlayer.min.js"></script>
 ```
@@ -86,7 +88,7 @@ const dp = new DPlayer(options);
 const dp = new DPlayer({
     container: document.getElementById('dplayer'),
     video: {
-        url: 'demo.mp4'
+        url: 'demo.mp4',
     },
 });
 ```
@@ -97,46 +99,46 @@ const dp = new DPlayer({
 
 DPlayer 有丰富的参数可以自定义你的播放器实例
 
-名称 | 默认值 | 描述
-----|-------|----
-container | document.querySelector('.dplayer') | 播放器容器元素
-live | false | 开启直播模式, 见[#直播](#直播)
-autoplay | false | 视频自动播放
-theme | '#b7daff' | 主题色
-loop | false | 视频循环播放
-lang | navigator.language.toLowerCase() | 可选值: 'en', 'zh-cn', 'zh-tw'
-screenshot | false | 开启截图,如果开启,视频和视频封面需要允许跨域
-hotkey | true | 开启热键,支持快进、快退、音量控制、播放暂停
-preload | 'auto' | 视频预加载,可选值: 'none', 'metadata', 'auto'
-volume | 0.7 | 默认音量,请注意播放器会记忆用户设置,用户手动设置音量后默认音量即失效
-logo | - | 在左上角展示一个 logo,你可以通过 CSS 调整它的大小和位置
-apiBackend | - | 自定义获取和发送弹幕行为,见[#直播](#直播)
-video | - | 视频信息
-video.quality | - | 见[#清晰度切换](#清晰度切换)
-video.defaultQuality | - | 见[#清晰度切换](#清晰度切换)
-video.url | - | 视频链接
-video.pic | - | 视频封面
-video.thumbnails | - | 视频缩略图,可以使用 [DPlayer-thumbnails](https://github.com/MoePlayer/DPlayer-thumbnails) 生成
-video.type | 'auto' | 可选值: 'auto', 'hls', 'flv', 'dash', 'webtorrent', 'normal' 或其他自定义类型, 见[#MSE 支持](#mse-支持)
-video.customType | - | 自定义类型, 见[#MSE 支持](#mse-支持)
-subtitle | - | 外挂字幕
-subtitle.url | `required` | 字幕链接
-subtitle.type | 'webvtt' | 字幕类型,可选值: 'webvtt', 'ass',目前只支持 webvtt
-subtitle.fontSize | '20px' | 字幕字号
-subtitle.bottom | '40px' | 字幕距离播放器底部的距离,取值形如: '10px' '10%'
-subtitle.color | '#fff' | 字幕颜色
-danmaku | - | 显示弹幕
-danmaku.id | `required` | 弹幕池id,必须唯一
-danmaku.api | `required` | 见[#弹幕接口](#弹幕接口)
-danmaku.token | - | 弹幕后端验证 token
-danmaku.maximum | - | 弹幕最大数量
-danmaku.addition | - | 额外外挂弹幕,见[#bilibili 弹幕](#bilibili-弹幕)
-danmaku.user | 'DIYgod' | 弹幕用户名
-danmaku.bottom | - | 弹幕距离播放器底部的距离,防止遮挡字幕,取值形如: '10px' '10%'
-danmaku.unlimited | false | 海量弹幕模式,即使重叠也展示全部弹幕,请注意播放器会记忆用户设置,用户手动设置后即失效
-contextmenu | [] | 自定义右键菜单
-highlight | [] | 自定义进度条提示点
-mutex | true | 互斥,阻止多个播放器同时播放,当前播放器播放时暂停其他播放器
+| 名称                 | 默认值                             | 描述                                                                                                    |
+| -------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------- |
+| container            | document.querySelector('.dplayer') | 播放器容器元素                                                                                          |
+| live                 | false                              | 开启直播模式, 见[#直播](#直播)                                                                          |
+| autoplay             | false                              | 视频自动播放                                                                                            |
+| theme                | '#b7daff'                          | 主题色                                                                                                  |
+| loop                 | false                              | 视频循环播放                                                                                            |
+| lang                 | navigator.language.toLowerCase()   | 可选值: 'en', 'zh-cn', 'zh-tw'                                                                          |
+| screenshot           | false                              | 开启截图,如果开启,视频和视频封面需要允许跨域                                                          |
+| hotkey               | true                               | 开启热键,支持快进、快退、音量控制、播放暂停                                                            |
+| preload              | 'auto'                             | 视频预加载,可选值: 'none', 'metadata', 'auto'                                                          |
+| volume               | 0.7                                | 默认音量,请注意播放器会记忆用户设置,用户手动设置音量后默认音量即失效                                  |
+| logo                 | -                                  | 在左上角展示一个 logo,你可以通过 CSS 调整它的大小和位置                                                |
+| apiBackend           | -                                  | 自定义获取和发送弹幕行为,见[#直播](#直播)                                                              |
+| video                | -                                  | 视频信息                                                                                                |
+| video.quality        | -                                  | 见[#清晰度切换](#清晰度切换)                                                                            |
+| video.defaultQuality | -                                  | 见[#清晰度切换](#清晰度切换)                                                                            |
+| video.url            | -                                  | 视频链接                                                                                                |
+| video.pic            | -                                  | 视频封面                                                                                                |
+| video.thumbnails     | -                                  | 视频缩略图,可以使用 [DPlayer-thumbnails](https://github.com/MoePlayer/DPlayer-thumbnails) 生成         |
+| video.type           | 'auto'                             | 可选值: 'auto', 'hls', 'flv', 'dash', 'webtorrent', 'normal' 或其他自定义类型, 见[#MSE 支持](#mse-支持) |
+| video.customType     | -                                  | 自定义类型, 见[#MSE 支持](#mse-支持)                                                                    |
+| subtitle             | -                                  | 外挂字幕                                                                                                |
+| subtitle.url         | `required`                         | 字幕链接                                                                                                |
+| subtitle.type        | 'webvtt'                           | 字幕类型,可选值: 'webvtt', 'ass',目前只支持 webvtt                                                    |
+| subtitle.fontSize    | '20px'                             | 字幕字号                                                                                                |
+| subtitle.bottom      | '40px'                             | 字幕距离播放器底部的距离,取值形如: '10px' '10%'                                                        |
+| subtitle.color       | '#fff'                             | 字幕颜色                                                                                                |
+| danmaku              | -                                  | 显示弹幕                                                                                                |
+| danmaku.id           | `required`                         | 弹幕池 id,必须唯一                                                                                     |
+| danmaku.api          | `required`                         | 见[#弹幕接口](#弹幕接口)                                                                                |
+| danmaku.token        | -                                  | 弹幕后端验证 token                                                                                      |
+| danmaku.maximum      | -                                  | 弹幕最大数量                                                                                            |
+| danmaku.addition     | -                                  | 额外外挂弹幕,见[#bilibili 弹幕](#bilibili-弹幕)                                                        |
+| danmaku.user         | 'DIYgod'                           | 弹幕用户名                                                                                              |
+| danmaku.bottom       | -                                  | 弹幕距离播放器底部的距离,防止遮挡字幕,取值形如: '10px' '10%'                                          |
+| danmaku.unlimited    | false                              | 海量弹幕模式,即使重叠也展示全部弹幕,请注意播放器会记忆用户设置,用户手动设置后即失效                  |
+| contextmenu          | []                                 | 自定义右键菜单                                                                                          |
+| highlight            | []                                 | 自定义进度条提示点                                                                                      |
+| mutex                | true                               | 互斥,阻止多个播放器同时播放,当前播放器播放时暂停其他播放器                                            |
 
 ```js
 const dp = new DPlayer({
@@ -155,14 +157,14 @@ const dp = new DPlayer({
         url: 'dplayer.mp4',
         pic: 'dplayer.png',
         thumbnails: 'thumbnails.jpg',
-        type: 'auto'
+        type: 'auto',
     },
     subtitle: {
         url: 'dplayer.vtt',
         type: 'webvtt',
         fontSize: '25px',
         bottom: '10%',
-        color: '#b7daff'
+        color: '#b7daff',
     },
     danmaku: {
         id: '9E2E3368B56CDBB4',
@@ -172,198 +174,204 @@ const dp = new DPlayer({
         addition: ['https://api.prprpr.me/dplayer/v3/bilibili?aid=4157142'],
         user: 'DIYgod',
         bottom: '15%',
-        unlimited: true
+        unlimited: true,
     },
     contextmenu: [
         {
             text: 'custom1',
-            link: 'https://github.com/DIYgod/DPlayer'
+            link: 'https://github.com/DIYgod/DPlayer',
         },
         {
             text: 'custom2',
             click: (player) => {
                 console.log(player);
-            }
-        }
+            },
+        },
     ],
     highlight: [
         {
             time: 20,
-            text: '这是第 20 秒'
+            text: '这是第 20 秒',
         },
         {
             time: 120,
-            text: '这是 2 分钟'
-        }
-    ]
+            text: '这是 2 分钟',
+        },
+    ],
 });
 ```
 
 ## API
 
-+ `dp.play()`: 播放视频
+-   `dp.play()`: 播放视频
 
-+ `dp.pause()`: 暂停视频
+-   `dp.pause()`: 暂停视频
 
-+ `dp.seek(time: number)`: 跳转到特定时间
+-   `dp.seek(time: number)`: 跳转到特定时间
 
-  ```js
-  dp.seek(100);
-  ```
+    ```js
+    dp.seek(100);
+    ```
 
-+ `dp.toggle()`: 切换播放和暂停
+-   `dp.toggle()`: 切换播放和暂停
 
-+ `dp.on(event: string, handler: function)`: 绑定视频和播放器事件,见[#事件绑定](#事件绑定)
+-   `dp.on(event: string, handler: function)`: 绑定视频和播放器事件,见[#事件绑定](#事件绑定)
 
-+ `dp.switchVideo(video, danmaku)`: 切换到其他视频
+-   `dp.switchVideo(video, danmaku)`: 切换到其他视频
 
-  ```js
-  dp.switchVideo({
-      url: 'second.mp4',
-      pic: 'second.png',
-      thumbnails: 'second.jpg'
-  }, {
-      id: 'test',
-      api: 'https://api.prprpr.me/dplayer/',
-      maximum: 3000,
-      user: 'DIYgod'
-  });
-  ```
+    ```js
+    dp.switchVideo(
+        {
+            url: 'second.mp4',
+            pic: 'second.png',
+            thumbnails: 'second.jpg',
+        },
+        {
+            id: 'test',
+            api: 'https://api.prprpr.me/dplayer/',
+            maximum: 3000,
+            user: 'DIYgod',
+        }
+    );
+    ```
 
-+ `dp.notice(text: string, time: number)`: 显示通知,时间的单位为毫秒,默认时间2000毫秒,默认透明度0.8
+-   `dp.notice(text: string, time: number)`: 显示通知,时间的单位为毫秒,默认时间 2000 毫秒,默认透明度 0.8
 
-+ `dp.switchQuality(index: number)`: 切换清晰度
+-   `dp.switchQuality(index: number)`: 切换清晰度
 
-+ `dp.destroy()`: 销毁播放器
+-   `dp.destroy()`: 销毁播放器
 
-+ `dp.speed(rate: number)`: 设置视频速度
+-   `dp.speed(rate: number)`: 设置视频速度
 
-+ `dp.volume(percentage: number, nostorage: boolean, nonotice: boolean)`: 设置视频音量
+-   `dp.volume(percentage: number, nostorage: boolean, nonotice: boolean)`: 设置视频音量
 
-  ```js
-  dp.volume(0.1, true, false);
-  ```
+    ```js
+    dp.volume(0.1, true, false);
+    ```
 
-+ `dp.video`: 原生 video
+-   `dp.video`: 原生 video
 
- + `dp.video.currentTime`: 返回视频当前播放时间
+-   `dp.video.currentTime`: 返回视频当前播放时间
 
- + `dp.video.duration`: 返回视频总时间
+-   `dp.video.duration`: 返回视频总时间
 
- + `dp.video.paused`: 返回视频是否暂停
+-   `dp.video.paused`: 返回视频是否暂停
 
- + 支持大多数[原生video接口](http://www.w3schools.com/tags/ref_av_dom.asp)
+-   支持大多数[原生 video 接口](http://www.w3schools.com/tags/ref_av_dom.asp)
 
-+ `dp.danmaku`
+-   `dp.danmaku`
 
- + `dp.danmaku.send(danmaku, callback: function)`: 提交一个新弹幕
+-   `dp.danmaku.send(danmaku, callback: function)`: 提交一个新弹幕
 
-   ```js
-   dp.danmaku.send({
-       text: 'dplayer is amazing',
-       color: '#b7daff',
-       type: 'right'   // should be `top` `bottom` or `right`
-   }, function () {
-       console.log('success');
-   });
-   ```
+    ```js
+    dp.danmaku.send(
+        {
+            text: 'dplayer is amazing',
+            color: '#b7daff',
+            type: 'right', // should be `top` `bottom` or `right`
+        },
+        function() {
+            console.log('success');
+        }
+    );
+    ```
 
- + `dp.danmaku.draw(danmaku)`: 实时绘制一个新弹幕
+-   `dp.danmaku.draw(danmaku)`: 实时绘制一个新弹幕
 
-   ```js
-   dp.danmaku.draw({
-       text: 'DIYgod is amazing',
-       color: '#fff',
-       type: 'top'
-   });
-   ```
+    ```js
+    dp.danmaku.draw({
+        text: 'DIYgod is amazing',
+        color: '#fff',
+        type: 'top',
+    });
+    ```
 
- + `dp.danmaku.opacity(percentage: number)`: 设置弹幕透明度,透明度值在 0 到 1 之间
+-   `dp.danmaku.opacity(percentage: number)`: 设置弹幕透明度,透明度值在 0 到 1 之间
 
-   ```js
-   dp.danmaku.opacity(0.5);
-   ```
+    ```js
+    dp.danmaku.opacity(0.5);
+    ```
 
- + `dp.danmaku.clear()`: 清除所有弹幕
+-   `dp.danmaku.clear()`: 清除所有弹幕
 
- + `dp.danmaku.hide()`: 隐藏弹幕
+-   `dp.danmaku.hide()`: 隐藏弹幕
 
- + `dp.danmaku.show()`: 显示弹幕
+-   `dp.danmaku.show()`: 显示弹幕
 
-+ `dp.fullScreen`: 两个类型:`web` 和 `browser`,默认类型是 `browser`
+-   `dp.fullScreen`: 两个类型:`web` 和 `browser`,默认类型是 `browser`
 
- + `dp.fullScreen.request(type: string)`: 进入全屏
+-   `dp.fullScreen.request(type: string)`: 进入全屏
 
-   ```js
-   dp.fullScreen.request('web');
-   ```
+    ```js
+    dp.fullScreen.request('web');
+    ```
 
- + `dp.fullScreen.cancel(type: string)`: 退出全屏
+-   `dp.fullScreen.cancel(type: string)`: 退出全屏
 
-   ```js
-   dp.fullScreen.cancel('web');
-   ```
+    ```js
+    dp.fullScreen.cancel('web');
+    ```
 
 ## 事件绑定
 
 `dp.on(event, handler)`
 
 ```js
-dp.on('ended', function () {
+dp.on('ended', function() {
     console.log('player ended');
 });
 ```
 
 视频事件
 
-- abort
-- canplay
-- canplaythrough
-- durationchange
-- emptied
-- ended
-- error
-- loadeddata
-- loadedmetadata
-- loadstart
-- mozaudioavailable
-- pause
-- play
-- playing
-- progress
-- ratechange
-- seeked
-- seeking
-- stalled
-- suspend
-- timeupdate
-- volumechange
-- waiting
+-   abort
+-   canplay
+-   canplaythrough
+-   durationchange
+-   emptied
+-   ended
+-   error
+-   loadeddata
+-   loadedmetadata
+-   loadstart
+-   mozaudioavailable
+-   pause
+-   play
+-   playing
+-   progress
+-   ratechange
+-   seeked
+-   seeking
+-   stalled
+-   suspend
+-   timeupdate
+-   volumechange
+-   waiting
 
 播放器事件
 
-- screenshot
-- thumbnails_show
-- thumbnails_hide
-- danmaku_show
-- danmaku_hide
-- danmaku_clear
-- danmaku_loaded
-- danmaku_send
-- danmaku_opacity
-- contextmenu_show
-- contextmenu_hide
-- notice_show
-- notice_hide
-- quality_start
-- quality_end
-- destroy
-- resize
-- fullscreen
-- fullscreen_cancel
-- subtitle_show
-- subtitle_hide
-- subtitle_change
+-   screenshot
+-   thumbnails_show
+-   thumbnails_hide
+-   danmaku_show
+-   danmaku_hide
+-   danmaku_clear
+-   danmaku_loaded
+-   danmaku_send
+-   danmaku_opacity
+-   contextmenu_show
+-   contextmenu_hide
+-   notice_show
+-   notice_hide
+-   quality_start
+-   quality_end
+-   destroy
+-   resize
+-   fullscreen
+-   fullscreen_cancel
+-   subtitle_show
+-   subtitle_hide
+-   subtitle_change
 
 ## 清晰度切换
 
@@ -390,19 +398,22 @@ dp.on('ended', function () {
 const dp = new DPlayer({
     container: document.getElementById('dplayer'),
     video: {
-        quality: [{
-            name: 'HD',
-            url: 'demo.m3u8',
-            type: 'hls'
-        }, {
-            name: 'SD',
-            url: 'demo.mp4',
-            type: 'normal'
-        }],
+        quality: [
+            {
+                name: 'HD',
+                url: 'demo.m3u8',
+                type: 'hls',
+            },
+            {
+                name: 'SD',
+                url: 'demo.mp4',
+                type: 'normal',
+            },
+        ],
         defaultQuality: 0,
         pic: 'demo.png',
         thumbnails: 'thumbnails.jpg',
-    }
+    },
 });
 ```
 
@@ -432,9 +443,9 @@ API: <https://api.prprpr.me/dplayer/v3/bilibili?aid=[aid]>
 const option = {
     danmaku: {
         // ...
-        addition: ['https://api.prprpr.me/dplayer/v3/bilibili?aid=[aid]']
-    }
-}
+        addition: ['https://api.prprpr.me/dplayer/v3/bilibili?aid=[aid]'],
+    },
+};
 ```
 
 ## MSE 支持
@@ -451,7 +462,7 @@ const option = {
 }"></DPlayer>
 
 ```html
-<link rel="stylesheet" href="DPlayer.min.css">
+<link rel="stylesheet" href="DPlayer.min.css" />
 <div id="dplayer"></div>
 <script src="hls.min.js"></script>
 <script src="DPlayer.min.js"></script>
@@ -462,8 +473,8 @@ const dp = new DPlayer({
     container: document.getElementById('dplayer'),
     video: {
         url: 'demo.m3u8',
-        type: 'hls'
-    }
+        type: 'hls',
+    },
 });
 ```
 
@@ -475,13 +486,13 @@ const dp = new DPlayer({
         url: 'demo.m3u8',
         type: 'customHls',
         customType: {
-            'customHls': function (video, player) {
+            customHls: function(video, player) {
                 const hls = new Hls();
                 hls.loadSource(video.src);
                 hls.attachMedia(video);
-            }
-        }
-    }
+            },
+        },
+    },
 });
 ```
 
@@ -490,7 +501,7 @@ const dp = new DPlayer({
 需要在 `DPlayer.min.js` 前面加载 [dash.js](https://github.com/Dash-Industry-Forum/dash.js)。
 
 ```html
-<link rel="stylesheet" href="DPlayer.min.css">
+<link rel="stylesheet" href="DPlayer.min.css" />
 <div id="dplayer"></div>
 <script src="dash.min.js"></script>
 <script src="DPlayer.min.js"></script>
@@ -501,8 +512,8 @@ const dp = new DPlayer({
     container: document.getElementById('dplayer'),
     video: {
         url: 'demo.mpd',
-        type: 'dash'
-    }
+        type: 'dash',
+    },
 });
 ```
 
@@ -514,11 +525,14 @@ const dp = new DPlayer({
         url: 'demo.mpd',
         type: 'customDash',
         customType: {
-            'customDash': function (video, player) {
-                dashjs.MediaPlayer().create().initialize(video, video.src, false);
-            }
-        }
-    }
+            customDash: function(video, player) {
+                dashjs
+                    .MediaPlayer()
+                    .create()
+                    .initialize(video, video.src, false);
+            },
+        },
+    },
 });
 ```
 
@@ -527,7 +541,7 @@ const dp = new DPlayer({
 需要在 `DPlayer.min.js` 前面加载 [shaka-player.compiled.js](https://github.com/google/shaka-player)。
 
 ```html
-<link rel="stylesheet" href="DPlayer.min.css">
+<link rel="stylesheet" href="DPlayer.min.css" />
 <div id="dplayer"></div>
 <script src="shaka-player.compiled.js"></script>
 <script src="DPlayer.min.js"></script>
@@ -541,13 +555,13 @@ const dp = new DPlayer({
         url: 'demo.mpd',
         type: 'shakaDash',
         customType: {
-            'shakaDash': function (video, player) {
+            shakaDash: function(video, player) {
                 var src = video.src;
                 var playerShaka = new shaka.Player(video); // 将会修改 video.src
                 playerShaka.load(src);
-            }
-        }
-    }
+            },
+        },
+    },
 });
 ```
 
@@ -563,7 +577,7 @@ const dp = new DPlayer({
 }"></DPlayer>
 
 ```html
-<link rel="stylesheet" href="DPlayer.min.css">
+<link rel="stylesheet" href="DPlayer.min.css" />
 <div id="dplayer"></div>
 <script src="flv.min.js"></script>
 <script src="DPlayer.min.js"></script>
@@ -574,8 +588,8 @@ const dp = new DPlayer({
     container: document.getElementById('dplayer'),
     video: {
         url: 'demo.flv',
-        type: 'flv'
-    }
+        type: 'flv',
+    },
 });
 ```
 
@@ -587,16 +601,16 @@ const dp = new DPlayer({
         url: 'demo.flv',
         type: 'customFlv',
         customType: {
-            'customFlv': function (video, player) {
+            customFlv: function(video, player) {
                 const flvPlayer = flvjs.createPlayer({
                     type: 'flv',
-                    url: video.src
+                    url: video.src,
                 });
                 flvPlayer.attachMediaElement(video);
                 flvPlayer.load();
-            }
-        }
-    }
+            },
+        },
+    },
 });
 ```
 
@@ -612,7 +626,7 @@ const dp = new DPlayer({
 }"></DPlayer>
 
 ```html
-<link rel="stylesheet" href="DPlayer.min.css">
+<link rel="stylesheet" href="DPlayer.min.css" />
 <div id="dplayer"></div>
 <script src="webtorrent.min.js"></script>
 <script src="DPlayer.min.js"></script>
@@ -623,8 +637,8 @@ const dp = new DPlayer({
     container: document.getElementById('dplayer'),
     video: {
         url: 'magnet:demo',
-        type: 'webtorrent'
-    }
+        type: 'webtorrent',
+    },
 });
 ```
 
@@ -636,21 +650,25 @@ const dp = new DPlayer({
         url: 'magnet:demo',
         type: 'customWebTorrent',
         customType: {
-            'customWebTorrent': function (video, player) {
+            customWebTorrent: function(video, player) {
                 player.container.classList.add('dplayer-loading');
                 const client = new WebTorrent();
                 const torrentId = video.src;
                 client.add(torrentId, (torrent) => {
                     const file = torrent.files.find((file) => file.name.endsWith('.mp4'));
-                    file.renderTo(video, {
-                        autoplay: player.options.autoplay
-                    }, () => {
-                        player.container.classList.remove('dplayer-loading');
-                    });
+                    file.renderTo(
+                        video,
+                        {
+                            autoplay: player.options.autoplay,
+                        },
+                        () => {
+                            player.container.classList.remove('dplayer-loading');
+                        }
+                    );
                 });
-            }
-        }
-    }
+            },
+        },
+    },
 });
 ```
 
@@ -659,7 +677,7 @@ const dp = new DPlayer({
 DPlayer 可以通过 `customType` 参数与任何 MSE 库一起使用
 
 ```html
-<link rel="stylesheet" href="DPlayer.min.css">
+<link rel="stylesheet" href="DPlayer.min.css" />
 <div id="dplayer"></div>
 <script src="pearplayer.js"></script>
 <script src="DPlayer.min.js"></script>
@@ -672,14 +690,14 @@ const dp = new DPlayer({
         url: 'https://qq.webrtc.win/tv/Pear-Demo-Yosemite_National_Park.mp4',
         type: 'pearplayer',
         customType: {
-            'pearplayer': function (video, player) {
+            pearplayer: function(video, player) {
                 new PearPlayer(video, {
                     src: video.src,
-                    autoplay: player.options.autoplay
+                    autoplay: player.options.autoplay,
                 });
-            }
-        }
-    }
+            },
+        },
+    },
 });
 ```
 
@@ -703,19 +721,19 @@ const dp = new DPlayer({
     live: true,
     danmaku: true,
     apiBackend: {
-        read: function (endpoint, callback) {
+        read: function(endpoint, callback) {
             console.log('Pretend to connect WebSocket');
             callback();
         },
-        send: function (endpoint, danmakuData, callback) {
+        send: function(endpoint, danmakuData, callback) {
             console.log('Pretend to send danamku via WebSocket', danmakuData);
             callback();
-        }
+        },
     },
     video: {
         url: 'demo.m3u8',
-        type: 'hls'
-    }
+        type: 'hls',
+    },
 });
 ```
 
@@ -725,7 +743,7 @@ const dp = new DPlayer({
 const danmaku = {
     text: 'Get a danamku via WebSocket',
     color: '#fff',
-    type: 'right'
+    type: 'right',
 };
 dp.danmaku.draw(danmaku);
 ```
@@ -739,12 +757,7 @@ dp.danmaku.draw(danmaku);
 为了完善的浏览器兼容性,它应该是这样:
 
 ```html
-<iframe src="example.com"
-        allowfullscreen="allowfullscreen"
-        mozallowfullscreen="mozallowfullscreen"
-        msallowfullscreen="msallowfullscreen"
-        oallowfullscreen="oallowfullscreen"
-        webkitallowfullscreen="webkitallowfullscreen"></iframe> 
+<iframe src="example.com" allowfullscreen="allowfullscreen" mozallowfullscreen="mozallowfullscreen" msallowfullscreen="msallowfullscreen" oallowfullscreen="oallowfullscreen" webkitallowfullscreen="webkitallowfullscreen"></iframe>
 ```
 
 ### 为什么播放器不能在手机上自动播放?

+ 8 - 7
docs/zh/support.md

@@ -16,16 +16,16 @@ DPlayer 是采用 MIT 许可的开源项目,使用完全免费。 但是随着
 
 我们通过以下方式接受赞助:
 
-- [微信支付](https://i.imgur.com/aq6PtWa.png)
-- [支付宝](https://i.imgur.com/wv1Pj2k.png)
-- [Paypal](https://www.paypal.me/DIYgod)
+-   [微信支付](https://i.imgur.com/aq6PtWa.png)
+-   [支付宝](https://i.imgur.com/wv1Pj2k.png)
+-   [Paypal](https://www.paypal.me/DIYgod)
 
 ## 周期性赞助
 
 周期性赞助可以获得额外的回报,比如你的名字或你的公司 logo 会出现在 DPlayer 的 GitHub 仓库和现在我们的官网中。
 
-- 通过 [Patreon](https://www.patreon.com/DIYgod) 赞助
-- 给我们发邮件联系赞助事宜: i#diygod.me
+-   通过 [Patreon](https://www.patreon.com/DIYgod) 赞助
+-   给我们发邮件联系赞助事宜: i#diygod.me
 
 ## 当前的顶级赞助商
 
@@ -52,10 +52,11 @@ DPlayer 是采用 MIT 许可的开源项目,使用完全免费。 但是随着
 ### Sponsors
 
 | [极酷社](https://www.acg.app) |
-| :--------------------------: |
+| :---------------------------: |
+
 
 ## DPlayer 贡献者
 
 感谢所有贡献者。
 
-<a href="https://github.com/MoePlayer/DPlayer/graphs/contributors"><img src="https://opencollective.com/DPlayer/contributors.svg?width=890" /></a>
+<a href="https://github.com/MoePlayer/DPlayer/graphs/contributors"><img src="https://opencollective.com/DPlayer/contributors.svg?width=890" /></a>

+ 21 - 16
src/js/api.js

@@ -2,40 +2,45 @@ import axios from 'axios';
 
 export default {
     send: (options) => {
-        axios.post(options.url, options.data).
-            then((response) => {
+        axios
+            .post(options.url, options.data)
+            .then((response) => {
                 const data = response.data;
                 if (!data || data.code !== 0) {
                     options.error && options.error(data && data.msg);
                     return;
                 }
                 options.success && options.success(data);
-            }).
-            catch((e) => {
+            })
+            .catch((e) => {
                 console.error(e);
                 options.error && options.error();
             });
     },
 
     read: (options) => {
-        axios.get(options.url).
-            then((response) => {
+        axios
+            .get(options.url)
+            .then((response) => {
                 const data = response.data;
                 if (!data || data.code !== 0) {
                     options.error && options.error(data && data.msg);
                     return;
                 }
-                options.success && options.success(data.data.map((item) => ({
-                    time: item[0],
-                    type: item[1],
-                    color: item[2],
-                    author: item[3],
-                    text: item[4]
-                })));
-            }).
-            catch((e) => {
+                options.success &&
+                    options.success(
+                        data.data.map((item) => ({
+                            time: item[0],
+                            type: item[1],
+                            color: item[2],
+                            author: item[3],
+                            text: item[4],
+                        }))
+                    );
+            })
+            .catch((e) => {
                 console.error(e);
                 options.error && options.error();
             });
-    }
+    },
 };

+ 4 - 4
src/js/bar.js

@@ -1,5 +1,5 @@
 class Bar {
-    constructor (template) {
+    constructor(template) {
         this.elements = {};
         this.elements.volume = template.volumeBar;
         this.elements.played = template.playedBar;
@@ -14,15 +14,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) {
+    get(type) {
         return parseFloat(this.elements[type].style.width) / 100;
     }
 }
 
-export default Bar;
+export default Bar;

+ 3 - 3
src/js/bezel.js

@@ -1,5 +1,5 @@
 class Bezel {
-    constructor (container) {
+    constructor(container) {
         this.container = container;
 
         this.container.addEventListener('animationend', () => {
@@ -7,10 +7,10 @@ class Bezel {
         });
     }
 
-    switch (icon) {
+    switch(icon) {
         this.container.innerHTML = icon;
         this.container.classList.add('dplayer-bezel-transition');
     }
 }
 
-export default Bezel;
+export default Bezel;

+ 20 - 18
src/js/comment.js

@@ -1,7 +1,7 @@
 import utils from './utils';
 
 class Comment {
-    constructor (player) {
+    constructor(player) {
         this.player = player;
 
         this.player.template.mask.addEventListener('click', () => {
@@ -39,7 +39,7 @@ class Comment {
         });
     }
 
-    show () {
+    show() {
         this.player.controller.disableAutoHide = true;
         this.player.template.controller.classList.add('dplayer-controller-comment');
         this.player.template.mask.classList.add('dplayer-mask-show');
@@ -47,7 +47,7 @@ class Comment {
         this.player.template.commentInput.focus();
     }
 
-    hide () {
+    hide() {
         this.player.template.controller.classList.remove('dplayer-controller-comment');
         this.player.template.mask.classList.remove('dplayer-mask-show');
         this.player.container.classList.remove('dplayer-show-controller');
@@ -55,24 +55,23 @@ class Comment {
         this.hideSetting();
     }
 
-    showSetting () {
+    showSetting() {
         this.player.template.commentSettingBox.classList.add('dplayer-comment-setting-open');
     }
 
-    hideSetting () {
+    hideSetting() {
         this.player.template.commentSettingBox.classList.remove('dplayer-comment-setting-open');
     }
 
-    toggleSetting () {
+    toggleSetting() {
         if (this.player.template.commentSettingBox.classList.contains('dplayer-comment-setting-open')) {
             this.hideSetting();
-        }
-        else {
+        } else {
             this.showSetting();
         }
     }
 
-    send () {
+    send() {
         this.player.template.commentInput.blur();
 
         // text can't be empty
@@ -81,15 +80,18 @@ class Comment {
             return;
         }
 
-        this.player.danmaku.send({
-            text: this.player.template.commentInput.value,
-            color: utils.color2Number(this.player.container.querySelector('.dplayer-comment-setting-color input:checked').value),
-            type: parseInt(this.player.container.querySelector('.dplayer-comment-setting-type input:checked').value),
-        }, () => {
-            this.player.template.commentInput.value = '';
-            this.hide();
-        });
+        this.player.danmaku.send(
+            {
+                text: this.player.template.commentInput.value,
+                color: utils.color2Number(this.player.container.querySelector('.dplayer-comment-setting-color input:checked').value),
+                type: parseInt(this.player.container.querySelector('.dplayer-comment-setting-type input:checked').value),
+            },
+            () => {
+                this.player.template.commentInput.value = '';
+                this.hide();
+            }
+        );
     }
 }
 
-export default Comment;
+export default Comment;

+ 5 - 7
src/js/contextmenu.js

@@ -1,5 +1,5 @@
 class ContextMenu {
-    constructor (player) {
+    constructor(player) {
         this.player = player;
         this.shown = false;
 
@@ -30,23 +30,21 @@ class ContextMenu {
         });
     }
 
-    show (x, y) {
+    show(x, y) {
         this.player.template.menu.classList.add('dplayer-menu-show');
 
         const clientRect = this.player.container.getBoundingClientRect();
         if (x + this.player.template.menu.offsetWidth >= clientRect.width) {
             this.player.template.menu.style.right = clientRect.width - x + 'px';
             this.player.template.menu.style.left = 'initial';
-        }
-        else {
+        } else {
             this.player.template.menu.style.left = x + 'px';
             this.player.template.menu.style.right = 'initial';
         }
         if (y + this.player.template.menu.offsetHeight >= clientRect.height) {
             this.player.template.menu.style.bottom = clientRect.height - y + 'px';
             this.player.template.menu.style.top = 'initial';
-        }
-        else {
+        } else {
             this.player.template.menu.style.top = y + 'px';
             this.player.template.menu.style.bottom = 'initial';
         }
@@ -57,7 +55,7 @@ class ContextMenu {
         this.player.events.trigger('contextmenu_show');
     }
 
-    hide () {
+    hide() {
         this.player.template.mask.classList.remove('dplayer-mask-show');
         this.player.template.menu.classList.remove('dplayer-menu-show');
 

+ 56 - 59
src/js/danmaku.js

@@ -1,13 +1,13 @@
 import utils from './utils';
 
 class Danmaku {
-    constructor (options) {
+    constructor(options) {
         this.options = options;
         this.container = this.options.container;
         this.danTunnel = {
             right: {},
             top: {},
-            bottom: {}
+            bottom: {},
         };
         this.danIndex = 0;
         this.dan = [];
@@ -20,12 +20,11 @@ class Danmaku {
         this.load();
     }
 
-    load () {
+    load() {
         let apiurl;
         if (this.options.api.maximum) {
             apiurl = `${this.options.api.address}v3/?id=${this.options.api.id}&max=${this.options.api.maximum}`;
-        }
-        else {
+        } else {
             apiurl = `${this.options.api.address}v3/?id=${this.options.api.id}`;
         }
         const endpoints = (this.options.api.addition || []).slice(0);
@@ -44,7 +43,7 @@ class Danmaku {
         });
     }
 
-    reload (newAPI) {
+    reload(newAPI) {
         this.options.api = newAPI;
         this.dan = [];
         this.clear();
@@ -52,9 +51,9 @@ class Danmaku {
     }
 
     /**
-    * Asynchronously read danmaku from all API endpoints
-    */
-    _readAllEndpoints (endpoints, callback) {
+     * Asynchronously read danmaku from all API endpoints
+     */
+    _readAllEndpoints(endpoints, callback) {
         const results = [];
         let readCount = 0;
 
@@ -82,7 +81,7 @@ class Danmaku {
         }
     }
 
-    send (dan, callback) {
+    send(dan, callback) {
         const danmakuData = {
             token: this.options.api.token,
             id: this.options.api.id,
@@ -90,7 +89,7 @@ class Danmaku {
             time: this.options.time(),
             text: dan.text,
             color: dan.color,
-            type: dan.type
+            type: dan.type,
         };
         this.options.apiBackend.send({
             url: this.options.api.address + 'v3/',
@@ -107,14 +106,14 @@ class Danmaku {
             text: this.htmlEncode(danmakuData.text),
             color: danmakuData.color,
             type: danmakuData.type,
-            border: `2px solid ${this.options.borderColor}`
+            border: `2px solid ${this.options.borderColor}`,
         };
         this.draw(danmaku);
 
         this.events && this.events.trigger('danmaku_send', danmakuData);
     }
 
-    frame () {
+    frame() {
         if (this.dan.length && !this.paused && this.showing) {
             let item = this.dan[this.danIndex];
             const dan = [];
@@ -129,7 +128,7 @@ class Danmaku {
         });
     }
 
-    opacity (percentage) {
+    opacity(percentage) {
         if (percentage !== undefined) {
             const items = this.container.getElementsByClassName('dplayer-danmaku-item');
             for (let i = 0; i < items.length; i++) {
@@ -150,7 +149,7 @@ class Danmaku {
      * color - danmaku color, default: `#fff`
      * type - danmaku type, `right` `top` `bottom`, default: `right`
      */
-    draw (dan) {
+    draw(dan) {
         if (this.showing) {
             const itemHeight = this.options.height;
             const danWidth = this.container.offsetWidth;
@@ -187,8 +186,7 @@ class Danmaku {
                                 return i % itemY;
                             }
                         }
-                    }
-                    else {
+                    } else {
                         this.danTunnel[type][i + ''] = [ele];
                         ele.addEventListener('animationend', () => {
                             this.danTunnel[type][i + ''].splice(0, 1);
@@ -215,8 +213,7 @@ class Danmaku {
                 item.classList.add(`dplayer-danmaku-${dan[i].type}`);
                 if (dan[i].border) {
                     item.innerHTML = `<span style="border:${dan[i].border}">${dan[i].text}</span>`;
-                }
-                else {
+                } else {
                     item.innerHTML = dan[i].text;
                 }
                 item.style.opacity = this._opacity;
@@ -230,28 +227,28 @@ class Danmaku {
 
                 // adjust
                 switch (dan[i].type) {
-                case 'right':
-                    tunnel = getTunnel(item, dan[i].type, itemWidth);
-                    if (tunnel >= 0) {
-                        item.style.width = itemWidth + 1 + 'px';
-                        item.style.top = itemHeight * tunnel + 'px';
-                        item.style.transform = `translateX(-${danWidth}px)`;
-                    }
-                    break;
-                case 'top':
-                    tunnel = getTunnel(item, dan[i].type);
-                    if (tunnel >= 0) {
-                        item.style.top = itemHeight * tunnel + 'px';
-                    }
-                    break;
-                case 'bottom':
-                    tunnel = getTunnel(item, dan[i].type);
-                    if (tunnel >= 0) {
-                        item.style.bottom = itemHeight * tunnel + 'px';
-                    }
-                    break;
-                default:
-                    console.error(`Can't handled danmaku type: ${dan[i].type}`);
+                    case 'right':
+                        tunnel = getTunnel(item, dan[i].type, itemWidth);
+                        if (tunnel >= 0) {
+                            item.style.width = itemWidth + 1 + 'px';
+                            item.style.top = itemHeight * tunnel + 'px';
+                            item.style.transform = `translateX(-${danWidth}px)`;
+                        }
+                        break;
+                    case 'top':
+                        tunnel = getTunnel(item, dan[i].type);
+                        if (tunnel >= 0) {
+                            item.style.top = itemHeight * tunnel + 'px';
+                        }
+                        break;
+                    case 'bottom':
+                        tunnel = getTunnel(item, dan[i].type);
+                        if (tunnel >= 0) {
+                            item.style.bottom = itemHeight * tunnel + 'px';
+                        }
+                        break;
+                    default:
+                        console.error(`Can't handled danmaku type: ${dan[i].type}`);
                 }
 
                 if (tunnel >= 0) {
@@ -269,15 +266,15 @@ class Danmaku {
         }
     }
 
-    play () {
+    play() {
         this.paused = false;
     }
 
-    pause () {
+    pause() {
         this.paused = true;
     }
 
-    _measure (text) {
+    _measure(text) {
         if (!this.context) {
             const measureStyle = getComputedStyle(this.container.getElementsByClassName('dplayer-danmaku-item')[0], null);
             this.context = document.createElement('canvas').getContext('2d');
@@ -286,7 +283,7 @@ class Danmaku {
         return this.context.measureText(text).width;
     }
 
-    seek () {
+    seek() {
         this.clear();
         for (let i = 0; i < this.dan.length; i++) {
             if (this.dan[i].time >= this.options.time()) {
@@ -297,11 +294,11 @@ class Danmaku {
         }
     }
 
-    clear () {
+    clear() {
         this.danTunnel = {
             right: {},
             top: {},
-            bottom: {}
+            bottom: {},
         };
         this.danIndex = 0;
         this.options.container.innerHTML = '';
@@ -309,17 +306,17 @@ class Danmaku {
         this.events && this.events.trigger('danmaku_clear');
     }
 
-    htmlEncode (str) {
-        return str.
-            replace(/&/g, '&amp;').
-            replace(/</g, '&lt;').
-            replace(/>/g, '&gt;').
-            replace(/"/g, '&quot;').
-            replace(/'/g, '&#x27;').
-            replace(/\//g, '&#x2f;');
+    htmlEncode(str) {
+        return str
+            .replace(/&/g, '&amp;')
+            .replace(/</g, '&lt;')
+            .replace(/>/g, '&gt;')
+            .replace(/"/g, '&quot;')
+            .replace(/'/g, '&#x27;')
+            .replace(/\//g, '&#x2f;');
     }
 
-    resize () {
+    resize() {
         const danWidth = this.container.offsetWidth;
         const items = this.container.getElementsByClassName('dplayer-danmaku-item');
         for (let i = 0; i < items.length; i++) {
@@ -327,7 +324,7 @@ class Danmaku {
         }
     }
 
-    hide () {
+    hide() {
         this.showing = false;
         this.pause();
         this.clear();
@@ -335,7 +332,7 @@ class Danmaku {
         this.events && this.events.trigger('danmaku_hide');
     }
 
-    show () {
+    show() {
         this.seek();
         this.showing = true;
         this.play();
@@ -343,7 +340,7 @@ class Danmaku {
         this.events && this.events.trigger('danmaku_show');
     }
 
-    unlimit (boolean) {
+    unlimit(boolean) {
         this.unlimited = boolean;
     }
 }

+ 48 - 17
src/js/events.js

@@ -1,29 +1,61 @@
 class Events {
-    constructor () {
+    constructor() {
         this.events = {};
 
         this.videoEvents = [
-            'abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied', 'ended', 'error',
-            'loadeddata', 'loadedmetadata', 'loadstart', 'mozaudioavailable', 'pause', 'play',
-            'playing', 'progress', 'ratechange', 'seeked', 'seeking', 'stalled', 'suspend',
-            'timeupdate', 'volumechange', 'waiting'
+            '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 = [
             'screenshot',
-            'thumbnails_show', 'thumbnails_hide',
-            'danmaku_show', 'danmaku_hide', 'danmaku_clear', 'danmaku_loaded', 'danmaku_send',
+            'thumbnails_show',
+            'thumbnails_hide',
+            'danmaku_show',
+            'danmaku_hide',
+            'danmaku_clear',
+            'danmaku_loaded',
+            'danmaku_send',
             'danmaku_opacity',
-            'contextmenu_show', 'contextmenu_hide',
-            'notice_show', 'notice_hide',
-            'quality_start', 'quality_end',
+            'contextmenu_show',
+            'contextmenu_hide',
+            'notice_show',
+            'notice_hide',
+            'quality_start',
+            'quality_end',
             'destroy',
             'resize',
-            'fullscreen', 'fullscreen_cancel', 'webfullscreen', 'webfullscreen_cancel',
-            'subtitle_show', 'subtitle_hide', 'subtitle_change'
+            'fullscreen',
+            'fullscreen_cancel',
+            'webfullscreen',
+            'webfullscreen_cancel',
+            'subtitle_show',
+            'subtitle_hide',
+            'subtitle_change',
         ];
     }
 
-    on (name, callback) {
+    on(name, callback) {
         if (this.type(name) && typeof callback === 'function') {
             if (!this.events[name]) {
                 this.events[name] = [];
@@ -32,7 +64,7 @@ class Events {
         }
     }
 
-    trigger (name, info) {
+    trigger(name, info) {
         if (this.events[name] && this.events[name].length) {
             for (let i = 0; i < this.events[name].length; i++) {
                 this.events[name][i](info);
@@ -40,11 +72,10 @@ class Events {
         }
     }
 
-    type (name) {
+    type(name) {
         if (this.playerEvents.indexOf(name) !== -1) {
             return 'player';
-        }
-        else if (this.videoEvents.indexOf(name) !== -1) {
+        } else if (this.videoEvents.indexOf(name) !== -1) {
             return 'video';
         }
 

+ 53 - 64
src/js/fullscreen.js

@@ -1,9 +1,9 @@
 import utils from './utils';
 
 class FullScreen {
-    constructor (player) {
+    constructor(player) {
         this.player = player;
-        this.lastScrollPosition = {left: 0, top: 0};
+        this.lastScrollPosition = { left: 0, top: 0 };
         this.player.events.on('webfullscreen', () => {
             this.player.resize();
         });
@@ -16,8 +16,7 @@ class FullScreen {
             this.player.resize();
             if (this.isFullScreen('browser')) {
                 this.player.events.trigger('fullscreen');
-            }
-            else {
+            } else {
                 utils.setScrollPosition(this.lastScrollPosition);
                 this.player.events.trigger('fullscreen_cancel');
             }
@@ -46,16 +45,16 @@ class FullScreen {
         }
     }
 
-    isFullScreen (type = 'browser') {
+    isFullScreen(type = 'browser') {
         switch (type) {
-        case 'browser':
-            return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
-        case 'web':
-            return this.player.container.classList.contains('dplayer-fulled');
+            case 'browser':
+                return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
+            case 'web':
+                return this.player.container.classList.contains('dplayer-fulled');
         }
     }
 
-    request (type = 'browser') {
+    request(type = 'browser') {
         const anotherType = type === 'browser' ? 'web' : 'browser';
         const anotherTypeOn = this.isFullScreen(anotherType);
         if (!anotherTypeOn) {
@@ -63,31 +62,27 @@ class FullScreen {
         }
 
         switch (type) {
-        case 'browser':
-            if (this.player.container.requestFullscreen) {
-                this.player.container.requestFullscreen();
-            }
-            else if (this.player.container.mozRequestFullScreen) {
-                this.player.container.mozRequestFullScreen();
-            }
-            else if (this.player.container.webkitRequestFullscreen) {
-                this.player.container.webkitRequestFullscreen();
-            }
-            else if (this.player.video.webkitEnterFullscreen) {   // Safari for iOS
-                this.player.video.webkitEnterFullscreen();
-            }
-            else if (this.player.video.webkitEnterFullScreen) {
-                this.player.video.webkitEnterFullScreen();
-            }
-            else if (this.player.container.msRequestFullscreen) {
-                this.player.container.msRequestFullscreen();
-            }
-            break;
-        case 'web':
-            this.player.container.classList.add('dplayer-fulled');
-            document.body.classList.add('dplayer-web-fullscreen-fix');
-            this.player.events.trigger('webfullscreen');
-            break;
+            case 'browser':
+                if (this.player.container.requestFullscreen) {
+                    this.player.container.requestFullscreen();
+                } else if (this.player.container.mozRequestFullScreen) {
+                    this.player.container.mozRequestFullScreen();
+                } else if (this.player.container.webkitRequestFullscreen) {
+                    this.player.container.webkitRequestFullscreen();
+                } else if (this.player.video.webkitEnterFullscreen) {
+                    // Safari for iOS
+                    this.player.video.webkitEnterFullscreen();
+                } else if (this.player.video.webkitEnterFullScreen) {
+                    this.player.video.webkitEnterFullScreen();
+                } else if (this.player.container.msRequestFullscreen) {
+                    this.player.container.msRequestFullscreen();
+                }
+                break;
+            case 'web':
+                this.player.container.classList.add('dplayer-fulled');
+                document.body.classList.add('dplayer-web-fullscreen-fix');
+                this.player.events.trigger('webfullscreen');
+                break;
         }
 
         if (anotherTypeOn) {
@@ -95,41 +90,35 @@ class FullScreen {
         }
     }
 
-    cancel (type = 'browser') {
+    cancel(type = 'browser') {
         switch (type) {
-        case 'browser':
-            if (document.cancelFullScreen) {
-                document.cancelFullScreen();
-            }
-            else if (document.mozCancelFullScreen) {
-                document.mozCancelFullScreen();
-            }
-            else if (document.webkitCancelFullScreen) {
-                document.webkitCancelFullScreen();
-            }
-            else if (document.webkitCancelFullscreen) {
-                document.webkitCancelFullscreen();
-            }
-            else if (document.msCancelFullScreen) {
-                document.msCancelFullScreen();
-            }
-            else if (document.msExitFullscreen) {
-                document.msExitFullscreen();
-            }
-            break;
-        case 'web':
-            this.player.container.classList.remove('dplayer-fulled');
-            document.body.classList.remove('dplayer-web-fullscreen-fix');
-            this.player.events.trigger('webfullscreen_cancel');
-            break;
+            case 'browser':
+                if (document.cancelFullScreen) {
+                    document.cancelFullScreen();
+                } else if (document.mozCancelFullScreen) {
+                    document.mozCancelFullScreen();
+                } else if (document.webkitCancelFullScreen) {
+                    document.webkitCancelFullScreen();
+                } else if (document.webkitCancelFullscreen) {
+                    document.webkitCancelFullscreen();
+                } else if (document.msCancelFullScreen) {
+                    document.msCancelFullScreen();
+                } else if (document.msExitFullscreen) {
+                    document.msExitFullscreen();
+                }
+                break;
+            case 'web':
+                this.player.container.classList.remove('dplayer-fulled');
+                document.body.classList.remove('dplayer-web-fullscreen-fix');
+                this.player.events.trigger('webfullscreen_cancel');
+                break;
         }
     }
 
-    toggle (type = 'browser') {
+    toggle(type = 'browser') {
         if (this.isFullScreen(type)) {
             this.cancel(type);
-        }
-        else {
+        } else {
             this.request(type);
         }
     }

+ 31 - 31
src/js/hotkey.js

@@ -1,5 +1,5 @@
 class HotKey {
-    constructor (player) {
+    constructor(player) {
         if (player.options.hotkey) {
             document.addEventListener('keydown', (e) => {
                 if (player.focus) {
@@ -9,30 +9,30 @@ class HotKey {
                         const event = e || window.event;
                         let percentage;
                         switch (event.keyCode) {
-                        case 32:
-                            event.preventDefault();
-                            player.toggle();
-                            break;
-                        case 37:
-                            event.preventDefault();
-                            player.seek(player.video.currentTime - 5);
-                            player.controller.setAutoHide();
-                            break;
-                        case 39:
-                            event.preventDefault();
-                            player.seek(player.video.currentTime + 5);
-                            player.controller.setAutoHide();
-                            break;
-                        case 38:
-                            event.preventDefault();
-                            percentage = player.volume() + 0.1;
-                            player.volume(percentage);
-                            break;
-                        case 40:
-                            event.preventDefault();
-                            percentage = player.volume() - 0.1;
-                            player.volume(percentage);
-                            break;
+                            case 32:
+                                event.preventDefault();
+                                player.toggle();
+                                break;
+                            case 37:
+                                event.preventDefault();
+                                player.seek(player.video.currentTime - 5);
+                                player.controller.setAutoHide();
+                                break;
+                            case 39:
+                                event.preventDefault();
+                                player.seek(player.video.currentTime + 5);
+                                player.controller.setAutoHide();
+                                break;
+                            case 38:
+                                event.preventDefault();
+                                percentage = player.volume() + 0.1;
+                                player.volume(percentage);
+                                break;
+                            case 40:
+                                event.preventDefault();
+                                percentage = player.volume() - 0.1;
+                                player.volume(percentage);
+                                break;
                         }
                     }
                 }
@@ -42,14 +42,14 @@ class HotKey {
         document.addEventListener('keydown', (e) => {
             const event = e || window.event;
             switch (event.keyCode) {
-            case 27:
-                if (player.fullScreen.isFullScreen('web')) {
-                    player.fullScreen.cancel('web');
-                }
-                break;
+                case 27:
+                    if (player.fullScreen.isFullScreen('web')) {
+                        player.fullScreen.cancel('web');
+                    }
+                    break;
             }
         });
     }
 }
 
-export default HotKey;
+export default HotKey;

+ 35 - 36
src/js/i18n.js

@@ -7,13 +7,12 @@ W3C def language codes is :
 NOTE: use lowercase to prevent case typo from user!
 Use this as shown below..... */
 
-function i18n (lang) {
+function i18n(lang) {
     this.lang = lang;
     this.tran = (text) => {
         if (tranTxt[this.lang] && tranTxt[this.lang][text]) {
             return tranTxt[this.lang][text];
-        }
-        else {
+        } else {
             return text;
         }
     };
@@ -21,19 +20,19 @@ function i18n (lang) {
 
 // add translation text here
 const tranTxt = {
-    'zh-cn' : {
+    'zh-cn': {
         'Danmaku is loading': '弹幕加载中',
-        'Top': '顶部',
-        'Bottom': '底部',
-        'Rolling': '滚动',
+        Top: '顶部',
+        Bottom: '底部',
+        Rolling: '滚动',
         'Input danmaku, hit Enter': '输入弹幕,回车发送',
         'About author': '关于作者',
         'DPlayer feedback': '播放器意见反馈',
         'About DPlayer': '关于 DPlayer 播放器',
-        'Loop': '洗脑循环',
-        'Speed': '速度',
+        Loop: '洗脑循环',
+        Speed: '速度',
         'Opacity for danmaku': '弹幕透明度',
-        'Normal': '正常',
+        Normal: '正常',
         'Please input danmaku content!': '要输入弹幕内容啊喂!',
         'Set danmaku color': '设置弹幕颜色',
         'Set danmaku type': '设置弹幕类型',
@@ -43,36 +42,36 @@ const tranTxt = {
         'Danmaku send failed': '弹幕发送失败',
         'Switching to': '正在切换至',
         'Switched to': '已经切换至',
-        'quality': '画质',
-        'FF': '快进',
-        'REW': '快退',
+        quality: '画质',
+        FF: '快进',
+        REW: '快退',
         'Unlimited danmaku': '海量弹幕',
         'Send danmaku': '发送弹幕',
-        'Setting': '设置',
+        Setting: '设置',
         'Full screen': '全屏',
         'Web full screen': '页面全屏',
-        'Send': '发送',
-        'Screenshot': '截图',
-        's': '秒',
+        Send: '发送',
+        Screenshot: '截图',
+        s: '秒',
         'Show subtitle': '显示字幕',
         'Hide subtitle': '隐藏字幕',
-        'Volume': '音量',
-        'Live': '直播',
+        Volume: '音量',
+        Live: '直播',
         'Video info': '视频统计信息',
     },
-    'zh-tw' : {
+    'zh-tw': {
         'Danmaku is loading': '彈幕載入中',
-        'Top': '頂部',
-        'Bottom': '底部',
-        'Rolling': '滾動',
+        Top: '頂部',
+        Bottom: '底部',
+        Rolling: '滾動',
         'Input danmaku, hit Enter': '輸入彈幕,Enter 發送',
         'About author': '關於作者',
         'DPlayer feedback': '播放器意見回饋',
         'About DPlayer': '關於 DPlayer 播放器',
-        'Loop': '循環播放',
-        'Speed': '速度',
+        Loop: '循環播放',
+        Speed: '速度',
         'Opacity for danmaku': '彈幕透明度',
-        'Normal': '正常',
+        Normal: '正常',
         'Please input danmaku content!': '請輸入彈幕內容啊!',
         'Set danmaku color': '設定彈幕顏色',
         'Set danmaku type': '設定彈幕類型',
@@ -82,23 +81,23 @@ const tranTxt = {
         'Danmaku send failed': '彈幕發送失敗',
         'Switching to': '正在切換至',
         'Switched to': '已經切換至',
-        'quality': '畫質',
-        'FF': '快進',
-        'REW': '快退',
+        quality: '畫質',
+        FF: '快進',
+        REW: '快退',
         'Unlimited danmaku': '巨量彈幕',
         'Send danmaku': '發送彈幕',
-        'Setting': '設定',
+        Setting: '設定',
         'Full screen': '全螢幕',
         'Web full screen': '頁面全螢幕',
-        'Send': '發送',
-        'Screenshot': '截圖',
-        's': '秒',
+        Send: '發送',
+        Screenshot: '截圖',
+        s: '秒',
         'Show subtitle': '顯示字幕',
         'Hide subtitle': '隱藏字幕',
-        'Volume': '音量',
-        'Live': '直播',
+        Volume: '音量',
+        Live: '直播',
         'Video info': '影片統計訊息',
-    }
+    },
 };
 
 export default i18n;

+ 1 - 1
src/js/index.js

@@ -4,4 +4,4 @@ import DPlayer from './player';
 /* global DPLAYER_VERSION GIT_HASH */
 console.log(`${'\n'} %c DPlayer v${DPLAYER_VERSION} ${GIT_HASH} %c http://dplayer.js.org ${'\n'}${'\n'}`, 'color: #fadfa3; background: #030307; padding:5px 0;', 'background: #fadfa3; padding:5px 0;');
 
-export default DPlayer;
+export default DPlayer;

+ 8 - 9
src/js/info-panel.js

@@ -1,7 +1,7 @@
 /* global DPLAYER_VERSION GIT_HASH */
 
 class InfoPanel {
-    constructor (player) {
+    constructor(player) {
         this.container = player.template.infoPanel;
         this.template = player.template;
         this.video = player.video;
@@ -12,7 +12,7 @@ class InfoPanel {
         });
     }
 
-    show () {
+    show() {
         this.beginTime = Date.now();
         this.update();
         this.player.timer.enable('info');
@@ -20,22 +20,21 @@ class InfoPanel {
         this.container.classList.remove('dplayer-info-panel-hide');
     }
 
-    hide () {
+    hide() {
         this.player.timer.disable('info');
         this.player.timer.disable('fps');
         this.container.classList.add('dplayer-info-panel-hide');
     }
 
-    triggle () {
+    triggle() {
         if (this.container.classList.contains('dplayer-info-panel-hide')) {
             this.show();
-        }
-        else {
+        } else {
             this.hide();
         }
     }
 
-    update () {
+    update() {
         this.template.infoVersion.innerHTML = `v${DPLAYER_VERSION} ${GIT_HASH}`;
         this.template.infoType.innerHTML = this.player.type;
         this.template.infoUrl.innerHTML = this.player.options.video.url;
@@ -48,9 +47,9 @@ class InfoPanel {
         }
     }
 
-    fps (value) {
+    fps(value) {
         this.template.infoFPS.innerHTML = `${value.toFixed(1)}`;
     }
 }
 
-export default InfoPanel;
+export default InfoPanel;

+ 7 - 10
src/js/setting.js

@@ -1,7 +1,7 @@
 import utils from './utils';
 
 class Setting {
-    constructor (player) {
+    constructor(player) {
         this.player = player;
 
         this.player.template.mask.addEventListener('click', () => {
@@ -18,8 +18,7 @@ class Setting {
             this.player.template.loopToggle.checked = !this.player.template.loopToggle.checked;
             if (this.player.template.loopToggle.checked) {
                 this.loop = true;
-            }
-            else {
+            } else {
                 this.loop = false;
             }
             this.hide();
@@ -36,8 +35,7 @@ class Setting {
             if (this.player.template.showDanmakuToggle.checked) {
                 this.showDanmaku = true;
                 this.player.danmaku.show();
-            }
-            else {
+            } else {
                 this.showDanmaku = false;
                 this.player.danmaku.hide();
             }
@@ -53,8 +51,7 @@ class Setting {
             if (this.player.template.unlimitDanmakuToggle.checked) {
                 this.unlimitDanmaku = true;
                 this.player.danmaku.unlimit(true);
-            }
-            else {
+            } else {
                 this.unlimitDanmaku = false;
                 this.player.danmaku.unlimit(false);
             }
@@ -111,7 +108,7 @@ class Setting {
         }
     }
 
-    hide () {
+    hide() {
         this.player.template.settingBox.classList.remove('dplayer-setting-box-open');
         this.player.template.mask.classList.remove('dplayer-mask-show');
         setTimeout(() => {
@@ -122,7 +119,7 @@ class Setting {
         this.player.controller.disableAutoHide = false;
     }
 
-    show () {
+    show() {
         this.player.template.settingBox.classList.add('dplayer-setting-box-open');
         this.player.template.mask.classList.add('dplayer-mask-show');
 
@@ -130,4 +127,4 @@ class Setting {
     }
 }
 
-export default Setting;
+export default Setting;

+ 10 - 8
src/js/subtitle.js

@@ -1,5 +1,5 @@
 class Subtitle {
-    constructor (container, video, options, events) {
+    constructor(container, video, options, events) {
         this.container = container;
         this.video = video;
         this.options = options;
@@ -8,7 +8,7 @@ class Subtitle {
         this.init();
     }
 
-    init () {
+    init() {
         this.container.style.fontSize = this.options.fontSize;
         this.container.style.bottom = this.options.bottom;
         this.container.style.color = this.options.color;
@@ -22,7 +22,10 @@ class Subtitle {
                 if (cue) {
                     const template = document.createElement('div');
                     template.appendChild(cue.getCueAsHTML());
-                    const trackHtml = template.innerHTML.split(/\r?\n/).map((item) => `<p>${item}</p>`).join('');
+                    const trackHtml = template.innerHTML
+                        .split(/\r?\n/)
+                        .map((item) => `<p>${item}</p>`)
+                        .join('');
                     this.container.innerHTML = trackHtml;
                 }
                 this.events.trigger('subtitle_change');
@@ -30,21 +33,20 @@ class Subtitle {
         }
     }
 
-    show () {
+    show() {
         this.container.classList.remove('dplayer-subtitle-hide');
         this.events.trigger('subtitle_show');
     }
 
-    hide () {
+    hide() {
         this.container.classList.add('dplayer-subtitle-hide');
         this.events.trigger('subtitle_hide');
     }
 
-    toggle () {
+    toggle() {
         if (this.container.classList.contains('dplayer-subtitle-hide')) {
             this.show();
-        }
-        else {
+        } else {
             this.hide();
         }
     }

+ 4 - 4
src/js/template.js

@@ -2,7 +2,7 @@ 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.index = options.index;
@@ -10,7 +10,7 @@ class Template {
         this.init();
     }
 
-    init () {
+    init() {
         this.container.innerHTML = tplPlayer({
             options: this.options,
             index: this.index,
@@ -22,8 +22,8 @@ class Template {
                 screenshot: this.options.screenshot,
                 preload: this.options.preload,
                 url: this.options.video.url,
-                subtitle: this.options.subtitle
-            }
+                subtitle: this.options.subtitle,
+            },
         });
 
         this.volumeBar = this.container.querySelector('.dplayer-volume-bar-inner');

+ 6 - 6
src/js/thumbnails.js

@@ -1,29 +1,29 @@
 class Thumbnails {
-    constructor (options) {
+    constructor(options) {
         this.container = options.container;
         this.barWidth = options.barWidth;
         this.container.style.backgroundImage = `url('${options.url}')`;
         this.events = options.events;
     }
 
-    resize (width, height, barWrapWidth) {
+    resize(width, height, barWrapWidth) {
         this.container.style.width = `${width}px`;
         this.container.style.height = `${height}px`;
         this.container.style.top = `${-height + 2}px`;
         this.barWidth = barWrapWidth;
     }
 
-    show () {
+    show() {
         this.container.style.display = 'block';
         this.events && this.events.trigger('thumbnails_show');
     }
 
-    move (position) {
-        this.container.style.backgroundPosition = `-${(Math.ceil(position / this.barWidth * 100) - 1) * 160}px 0`;
+    move(position) {
+        this.container.style.backgroundPosition = `-${(Math.ceil((position / this.barWidth) * 100) - 1) * 160}px 0`;
         this.container.style.left = `${Math.min(Math.max(position - this.container.offsetWidth / 2, -10), this.barWidth - 150)}px`;
     }
 
-    hide () {
+    hide() {
         this.container.style.display = 'none';
 
         this.events && this.events.trigger('thumbnails_hide');

+ 16 - 23
src/js/timer.js

@@ -1,5 +1,5 @@
 class Timer {
-    constructor (player) {
+    constructor(player) {
         this.player = player;
 
         window.requestAnimationFrame = (() =>
@@ -8,17 +8,16 @@ class Timer {
             window.mozRequestAnimationFrame ||
             window.oRequestAnimationFrame ||
             window.msRequestAnimationFrame ||
-            function (callback) {
+            function(callback) {
                 window.setTimeout(callback, 1000 / 60);
-            }
-        )();
+            })();
 
         this.types = ['loading', 'info', 'fps'];
 
         this.init();
     }
 
-    init () {
+    init() {
         this.types.map((item) => {
             if (item !== 'fps') {
                 this[`init${item}Checker`]();
@@ -27,7 +26,7 @@ class Timer {
         });
     }
 
-    initloadingChecker () {
+    initloadingChecker() {
         let lastPlayPos = 0;
         let currentPlayPos = 0;
         let bufferingDetected = false;
@@ -35,15 +34,11 @@ class Timer {
             if (this.enableloadingChecker) {
                 // whether the video is buffering
                 currentPlayPos = this.player.video.currentTime;
-                if (!bufferingDetected
-                    && currentPlayPos === lastPlayPos
-                    && !this.player.video.paused) {
+                if (!bufferingDetected && currentPlayPos === lastPlayPos && !this.player.video.paused) {
                     this.player.container.classList.add('dplayer-loading');
                     bufferingDetected = true;
                 }
-                if (bufferingDetected
-                    && currentPlayPos > lastPlayPos
-                    && !this.player.video.paused) {
+                if (bufferingDetected && currentPlayPos > lastPlayPos && !this.player.video.paused) {
                     this.player.container.classList.remove('dplayer-loading');
                     bufferingDetected = false;
                 }
@@ -52,32 +47,30 @@ class Timer {
         }, 100);
     }
 
-    initfpsChecker () {
+    initfpsChecker() {
         window.requestAnimationFrame(() => {
             if (this.enablefpsChecker) {
                 this.initfpsChecker();
                 if (!this.fpsStart) {
                     this.fpsStart = new Date();
                     this.fpsIndex = 0;
-                }
-                else {
+                } else {
                     this.fpsIndex++;
                     const fpsCurrent = new Date();
                     if (fpsCurrent - this.fpsStart > 1000) {
-                        this.player.infoPanel.fps(this.fpsIndex / (fpsCurrent - this.fpsStart) * 1000);
+                        this.player.infoPanel.fps((this.fpsIndex / (fpsCurrent - this.fpsStart)) * 1000);
                         this.fpsStart = new Date();
                         this.fpsIndex = 0;
                     }
                 }
-            }
-            else {
+            } else {
                 this.fpsStart = 0;
                 this.fpsIndex = 0;
             }
         });
     }
 
-    initinfoChecker () {
+    initinfoChecker() {
         this.infoChecker = setInterval(() => {
             if (this.enableinfoChecker) {
                 this.player.infoPanel.update();
@@ -85,7 +78,7 @@ class Timer {
         }, 1000);
     }
 
-    enable (type) {
+    enable(type) {
         this[`enable${type}Checker`] = true;
 
         if (type === 'fps') {
@@ -93,11 +86,11 @@ class Timer {
         }
     }
 
-    disable (type) {
+    disable(type) {
         this[`enable${type}Checker`] = false;
     }
 
-    destroy () {
+    destroy() {
         this.types.map((item) => {
             this[`enable${item}Checker`] = false;
             this[`${item}Checker`] && clearInterval(this[`${item}Checker`]);
@@ -106,4 +99,4 @@ class Timer {
     }
 }
 
-export default Timer;
+export default Timer;

+ 6 - 6
src/js/user.js

@@ -1,38 +1,38 @@
 import utils from './utils';
 
 class User {
-    constructor (player) {
+    constructor(player) {
         this.storageName = {
             opacity: 'dplayer-danmaku-opacity',
             volume: 'dplayer-volume',
             unlimited: 'dplayer-danmaku-unlimited',
             danmaku: 'dplayer-danmaku-show',
-            subtitle: 'dplayer-subtitle-show'
+            subtitle: 'dplayer-subtitle-show',
         };
         this.default = {
             opacity: 0.7,
             volume: player.options.hasOwnProperty('volume') ? player.options.volume : 0.7,
             unlimited: (player.options.danmaku && player.options.danmaku.unlimited ? 1 : 0) || 0,
             danmaku: 1,
-            subtitle: 1
+            subtitle: 1,
         };
         this.data = {};
 
         this.init();
     }
 
-    init () {
+    init() {
         for (const item in this.storageName) {
             const name = this.storageName[item];
             this.data[item] = parseFloat(utils.storage.get(name) || this.default[item]);
         }
     }
 
-    get (key) {
+    get(key) {
         return this.data[key];
     }
 
-    set (key, value) {
+    set(key, value) {
         this.data[key] = value;
         utils.storage.set(this.storageName[key], value);
     }