diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/docs/CNAME b/docs/CNAME new file mode 100644 index 0000000..e8d7166 --- /dev/null +++ b/docs/CNAME @@ -0,0 +1 @@ +dplayer.js.org \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..183e4e8 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,647 @@ +--- +search: english +--- + +# DPlayer + +🍭 Wow, such a lovely HTML5 danmaku video player + +## Special Sponsors + + + + + + + + +
+ + + + + + + +
+ +## Installation + +Using npm: + +``` +npm install dplayer --save +``` + +Using Yarn: + +``` +yarn add dplayer +``` + +## Quick Start + +
+
+
+ +```html + +
+ +``` + +```js +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + screenshot: true, + video: { + url: 'demo.mp4', + pic: 'demo.jpg', + thumbnails: 'thumbnails.jpg' + }, + subtitle: { + url: 'webvtt.vtt' + }, + danmaku: { + id: 'demo', + api: 'https://api.prprpr.me/dplayer/' + } +}); +``` + +Work with module bundler: + +```js +import 'DPlayer/dist/DPlayer.min.css'; +import DPlayer from 'DPlayer'; + +const dp = new DPlayer(options); +``` + +## Options + +Name|Default|Note +----|-------|---- +container | document.querySelector('.dplayer') | player container +live | false | enable live mode, [see more details](http://dplayer.js.org/docs/#/?id=live-mode) +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 +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 more details](http://dplayer.js.org/docs/#/?id=live-mode) +video | - | video info +video.quality | - | [see more details](http://dplayer.js.org/docs/#/?id=quality-switching) +video.defaultQuality | - | [see more details](http://dplayer.js.org/docs/#/?id=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' or custom type, [see more details](http://dplayer.js.org/docs/#/?id=mse-support) +video.customType | - | custom video type, [see more details](http://dplayer.js.org/docs/#/?id=mse-support) +subtitle | - | external subtitle +subtitle.url | `required` | subtitle url +subtitle.type | 'webvtt' | values: 'webvtt', 'ass', but only webvtt is supported for now +subtitle.fontSize | '20px' | subtitle font size +subtitle.bottom | '40px' | values like: '10px' '10%', the distance between the subtitle and player bottom +subtitle.color | '#fff' | subtitle color +danmaku | - | showing danmaku +danmaku.id | `required` | danamku pool id, it must be unique +danmaku.api | `required` | [see more details](http://dplayer.js.org/docs/#/?id=back-end) +danmaku.token | - | back end verification token +danmaku.maximum | - | danmaku maximum quantity +danmaku.addition | - | additional danmaku, [see more details](http://dplayer.js.org/docs/#/?id=bilibili-danmaku-and-video-link) +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 | allow danmaku overlap, notice that player will remember user setting, default setting will not work after user set it themselves +contextmenu | [] | custom contextmenu +mutex | true | pause other players when this player start play + +For example: + +
+
+
+ +```js +const dp = new DPlayer({ + container: document.getElementById('player'), + autoplay: false, + theme: '#FADFA3', + loop: true, + lang: 'zh-cn', + screenshot: true, + hotkey: true, + preload: 'auto', + logo: 'logo.png', + volume: 0.7, + mutex: true, + video: { + url: 'dplayer.mp4', + pic: 'dplayer.png', + thumbnails: 'thumbnails.jpg', + type: 'auto' + }, + subtitle: { + url: 'dplayer.vtt', + type: 'webvtt', + fontSize: '25px', + bottom: '10%', + color: '#b7daff' + }, + danmaku: { + id: '9E2E3368B56CDBB4', + api: 'https://api.prprpr.me/dplayer/', + token: 'tokendemo', + maximum: 1000, + addition: ['https://api.prprpr.me/dplayer/bilibili?aid=4157142'], + user: 'DIYgod', + bottom: '15%', + unlimited: true + }, + contextmenu: [ + { + text: 'custom1', + link: 'https://github.com/DIYgod/DPlayer' + }, + { + text: 'custom2', + click: (player) => { + console.log(player); + } + } + ] +}); +``` + +## API + ++ `dp.play()`: play video + ++ `dp.pause()`: pause video + ++ `dp.seek(time: number)`: seek to specified millisecond time + + ```js + dp.seek(1000); + ``` + ++ `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/docs/#/?id=event-binding) + ++ `dp.switchVideo(video, danmaku)`: switch to a new video, the parameters in `video` and `danmaku` is the same as option + + ```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)`: show message + ++ `dp.switchQuality(index: number)`: switch quality + ++ `dp.destroy()`: destroy player + ++ `dp.speed(rate: number)`: set video speed + ++ `dp.video`: native video + + + `dp.video.currentTime`: returns the current playback position + + + `dp.video.loop`: returns whether the video should start over again when finished + + + `dp.video.paused`: returns whether the video paused + + + most [native api](http://www.w3schools.com/tags/ref_av_dom.asp) are supported + ++ `dp.danmaku` + + + `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'); + }); + ``` + + + `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' + }); + ``` + + + `dp.danmaku.opacity(percentage: number)`: set danmaku opacity, opacity should between 0 and 1 + + ```js + dp.danmaku.opacity(0.5); + ``` + + + `dp.danmaku.clear()`: clear all danmakus + + + `dp.danmaku.hide()`: hide danmaku + + + `dp.danmaku.show()`: show danmaku + ++ `dp.fullScreen`: two type: `web` or `browser`, the default one is `browser` + + + `dp.fullScreen.request(type: string)`: request fullscreen + + ```js + dp.fullScreen.request('web'); + ``` + + + `dp.fullScreen.cancel(type: string)`: cancel fullscreen + + ```js + dp.fullScreen.cancel('web'); + ``` + +## Event binding + +`dp.on(event, handler)` + +```js +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 + +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 +- subtitle_show +- subtitle_hide +- subtitle_change + +## Quality switching + +Set video url and video type in video.quality, set default quality by video.defaultQuality. + +
+
+
+ +```js +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + quality: [{ + name: 'HD', + url: 'demo.m3u8', + type: 'hls' + }, { + name: 'SD', + url: 'demo.mp4', + type: 'normal' + }], + defaultQuality: 0, + pic: 'demo.png', + thumbnails: 'thumbnails.jpg', + } +}); +``` + +## Danmaku + +### Danmaku API + +**Ready-made API** + +url: https://api.prprpr.me/dplayer/ + +Daily backup data: [DPlayer-data](https://github.com/DIYgod/DPlayer-data) + +**Setting up yourself** + +[DPlayer-node](https://github.com/MoePlayer/DPlayer-node) + +### Bilibili danmaku + +API: [https://api.prprpr.me/dplayer/v2/bilibili?aid=[aid]](https://api.prprpr.me/dplayer/v2/bilibili?aid=[aid]) or [https://api.prprpr.me/dplayer/v2/bilibili?cid=[cid]](https://api.prprpr.me/dplayer/v2/bilibili?cid=[cid]) + +```js +const option = { + danmaku: { + // ... + addition: ['https://api.prprpr.me/dplayer/v2/bilibili?aid=[aid]'] + } +} +``` + +## MSE support + +### HLS + +It requires the library [hls.js](https://github.com/video-dev/hls.js) and it should be loaded before `DPlayer.min.js`. + +
+
+
+ +```html + +
+ + +``` + +```js +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'demo.m3u8', + type: 'hls' + } +}); +``` + +```js +// another way, use customType +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'demo.m3u8', + type: 'customHls', + customType: { + 'customHls': function (video, player) { + const hls = new Hls(); + hls.loadSource(video.src); + hls.attachMedia(video); + } + } + } +}); +``` + +### MPEG DASH + +It requires the library [dash.js](https://github.com/Dash-Industry-Forum/dash.js) and it should be loaded before `DPlayer.min.js`. + +
+
+
+ +```html + +
+ + +``` + +```js +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'demo.mpd', + type: 'dash' + } +}); +``` + +```js +// another way, use customType +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'demo.mpd', + type: 'customDash', + customType: { + 'customDash': function (video, player) { + dashjs.MediaPlayer().create().initialize(video, video.src, false); + } + } + } +}); +``` + +### FLV + +It requires the library [flv.js](https://github.com/Bilibili/flv.js) and it should be loaded before `DPlayer.min.js`. + +
+
+
+ +```html + +
+ + +``` + +```js +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'demo.flv', + type: 'flv' + } +}); +``` + +```js +// another way, use customType +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'demo.flv', + type: 'customFlv', + customType: { + 'customFlv': function (video, player) { + const flvPlayer = flvjs.createPlayer({ + type: 'flv', + url: video.src + }); + flvPlayer.attachMediaElement(video); + flvPlayer.load(); + } + } + } +}); +``` + +### WebTorrent + +It requires the library [webtorrent](https://github.com/webtorrent/webtorrent) and it should be loaded before `DPlayer.min.js`. + +
+
+
+ +```html + +
+ + +``` + +```js +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'magnet:demo', + type: 'webtorrent' + } +}); +``` + +```js +// another way, use customType +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'magnet:demo', + type: 'customWebTorrent', + customType: { + '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'); + }); + }); + } + } + } +}); +``` + +## Live + +
+
+
+ +You can also regard DPlayer as a live player, at first, you should prepare a WebSocket backend yourself. + +Init DPlayer: + +```js +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + live: true, + danmaku: true, + apiBackend: { + read: function (endpoint, callback) { + console.log('Pretend to connect WebSocket'); + callback(); + }, + send: function (endpoint, danmakuData, callback) { + console.log('Pretend to send danamku via WebSocket', danmakuData); + callback(); + } + }, + video: { + url: 'demo.m3u8', + type: 'hls' + } +}); +``` + +After getting a danmaku via WebSocket: + +```js +const danmaku = { + text: 'Get a danamku via WebSocket', + color: '#fff', + type: 'right' +}; +dp.danmaku.draw(danmaku); +``` + +## CDN + +- [jsDelivr](https://www.jsdelivr.com/package/npm/dplayer) +- [cdnjs](https://cdnjs.com/libraries/dplayer) +- [unpkg](https://unpkg.com/dplayer/) + +## FAQ + +### Why can't some videos be full screen? + +If player is contained in a iframe, try adding the allowfullscreen attribute to the iframe. + +For full browser support it should look like this: + +```html + +``` + +### Why can't player autoplay in some mobile browsers? + +Most mobile browsers forbid video autoplay, you wont be able to achieve it without hacks. \ No newline at end of file diff --git a/docs/config.js b/docs/config.js new file mode 100644 index 0000000..4aeaa47 --- /dev/null +++ b/docs/config.js @@ -0,0 +1,243 @@ +const langs = [ + { title: 'English', path: '/home', matchPath: /^\/(home|ecosystem)/ }, + { title: '简体中文', path: '/zh-Hans/', matchPath: /^\/zh-Hans/ }, +] + +docute.init({ + landing: 'landing.html', + title: 'DPlayer', + repo: 'DIYgod/DPlayer', + twitter: 'DIYgod', + 'edit-link': 'https://github.com/MoePlayer/DPlayer/tree/master/docs', + nav: { + default: [ + { + title: 'Home', path: '/home' + }, + { + title: 'Ecosystem', path: '/ecosystem' + }, + { + title: 'Languages', type: 'dropdown', items: langs + } + ], + 'zh-Hans': [ + { + title: '首页', path: '/zh-Hans/' + }, + { + title: '生态系统', path: '/zh-Hans/ecosystem' + }, + { + title: '选择语言', type: 'dropdown', items: langs + } + ], + }, + plugins: [ + docsearch({ + apiKey: '46a8ba306e368972c1d75feb581fb430', + indexName: 'dplayer', + url: 'http://dplayer.js.org' + }), + evanyou(), + player() + ] +}) + +function player (options) { + return function (context) { + context.event.on('landing:updated', function () { + console.log('landing:updated'); + clearPlayer(); + dplayer1(); + }); + context.event.on('content:updated', function () { + console.log('content:updated'); + clearPlayer(); + for (var i = 0; i < document.querySelectorAll('.load').length; i++) { + document.querySelectorAll('.load')[i].addEventListener('click', function () { + window[this.parentElement.id] && window[this.parentElement.id](); + }); + } + }) + } +} + +function clearPlayer () { + for (var i = 1; i < 10; i++) { + if (window['dp' + (i + 1)]) { + window['dp' + (i + 1)].destroy(); + } + } +} + +function dplayer1 () { + window.dp1 = new DPlayer({ + container: document.getElementById('dplayer1'), + screenshot: true, + video: { + url: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara.mp4', + pic: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara.png', + thumbnails: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara_thumbnails.jpg' + }, + subtitle: { + url: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara.vtt' + }, + danmaku: { + id: '9E2E3368B56CDBB4', + api: 'https://api.prprpr.me/dplayer/' + } + }); +} + +function dplayer2 () { + window.dp2 = new DPlayer({ + container: document.getElementById('dplayer2'), + screenshot: true, + video: { + url: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara.mp4', + pic: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara.png', + thumbnails: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara_thumbnails.jpg' + }, + subtitle: { + url: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara.vtt' + }, + danmaku: { + id: '9E2E3368B56CDBB4', + api: 'https://api.prprpr.me/dplayer/' + } + }); +} + +function dplayer3 () { + window.dp3 = new DPlayer({ + container: document.getElementById('dplayer3'), + autoplay: false, + theme: '#FADFA3', + loop: true, + lang: 'zh-cn', + screenshot: true, + hotkey: true, + preload: 'auto', + logo: 'https://moeplayer.b0.upaiyun.com/dplayer/DPlayer.png', + volume: 0.7, + mutex: true, + video: { + url: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara.mp4', + pic: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara.png', + thumbnails: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara_thumbnails.jpg', + type: 'auto' + }, + subtitle: { + url: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara.vtt', + type: 'webvtt', + fontSize: '25px', + bottom: '10%', + color: '#b7daff' + }, + danmaku: { + id: '9E2E3368B56CDBB4', + api: 'https://api.prprpr.me/dplayer/', + token: 'tokendemo', + maximum: 1000, + addition: ['https://api.prprpr.me/dplayer/bilibili?aid=4157142'], + user: 'DIYgod', + bottom: '15%', + unlimited: true + }, + contextmenu: [ + { + text: 'custom1', + link: 'https://github.com/DIYgod/DPlayer' + }, + { + text: 'custom2', + click: (player) => { + console.log(player); + } + } + ] + }); +} + +function dplayer4 () { + window.dp4 = new DPlayer({ + container: document.getElementById('dplayer4'), + video: { + quality: [{ + name: 'HD', + url: 'https://moeplayer.b0.upaiyun.com/dplayer/hls/hikarunara.m3u8', + type: 'hls' + }, { + name: 'SD', + url: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara.mp4', + type: 'normal' + }], + defaultQuality: 0, + pic: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara.png', + thumbnails: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara_thumbnails.jpg' + } + }); +} + +function dplayer5 () { + window.dp5 = new DPlayer({ + container: document.getElementById('dplayer5'), + video: { + url: 'https://moeplayer.b0.upaiyun.com/dplayer/hls/hikarunara.m3u8', + type: 'hls' + } + }); +} + +function dplayer6 () { + window.dp6 = new DPlayer({ + container: document.getElementById('dplayer6'), + video: { + url: 'https://moeplayer.b0.upaiyun.com/dplayer/dash/hikarunara.mpd', + type: 'dash' + } + }); +} + +function dplayer7 () { + window.dp7 = new DPlayer({ + container: document.getElementById('dplayer7'), + video: { + url: 'https://moeplayer.b0.upaiyun.com/dplayer/hikarunara.flv', + type: 'flv' + } + }); +} + +function dplayer8 () { + window.dp8 = new DPlayer({ + container: document.getElementById('dplayer8'), + video: { + url: 'magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent', + type: 'webtorrent' + } + }); +} + +function dplayer9 () { + window.dp9 = new DPlayer({ + container: document.getElementById('dplayer9'), + live: true, + danmaku: true, + apiBackend: { + read: function (endpoint, callback) { + console.log('Pretend to connect WebSocket'); + callback(); + }, + send: function (endpoint, danmakuData, callback) { + console.log('Pretend to send danamku via WebSocket', danmakuData); + callback(); + } + }, + video: { + url: 'https://moeplayer.b0.upaiyun.com/dplayer/hls/hikarunara.m3u8', + type: 'hls' + } + }); +} \ No newline at end of file diff --git a/docs/ecosystem.md b/docs/ecosystem.md new file mode 100644 index 0000000..71a9718 --- /dev/null +++ b/docs/ecosystem.md @@ -0,0 +1,59 @@ +--- +search: english +--- + +# Ecosystem + +Let's make DPlayer better, feel free to submit yours in [`Let me know!`](https://github.com/MoePlayer/DPlayer/issues/31) + +## Help + +### Joining the Discussion + +- [Telegram Group](https://t.me/adplayer) +- [QQ Group](https://shang.qq.com/wpa/qunwpa?idkey=bf22213ae0028a82e5adf3f286dfd4f01e0997dc9f1dcd8e831a0a85e799be17): 415835947 + +### Creating issue + +- [MoePlayer/DPlayer/issues](https://github.com/MoePlayer/DPlayer/issues) + +## Related Projects + +### Tooling + +- [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 + +### 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 +- [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 + +## Who use DPlayer? + +- [嘀哩嘀哩](http://www.dilidili.wang/) +- [银弹字幕组](https://www.sbsub.com/) +- [纸飞机南航青年网络社区](http://my.nuaa.edu.cn/video-video.html) +- [otomads](https://otomads.com/) + +## Contributors + +This project exists thanks to all the people who contribute. + + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..acfc896 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,48 @@ + + + + + + + DPlayer + + + + + + + + + + + + + + + +
+ + + + + + + + diff --git a/docs/landing.html b/docs/landing.html new file mode 100644 index 0000000..28b7fb4 --- /dev/null +++ b/docs/landing.html @@ -0,0 +1,83 @@ +

DPlayer

+ +

🍭 Wow, such a lovely HTML5 danmaku video player.

+ +
+
+
+ +
+ + GitHub + + + + Docs + +
+ + \ No newline at end of file diff --git a/docs/zh-Hans/README.md b/docs/zh-Hans/README.md new file mode 100644 index 0000000..5625e58 --- /dev/null +++ b/docs/zh-Hans/README.md @@ -0,0 +1,648 @@ +--- +nav: zh-Hans +search: zh-Hans +--- + +# DPlayer + +🍭 Wow, such a lovely HTML5 danmaku video player + +## 特别赞助商 + + + + + + + + +
+ + + + + + + +
+ +## Installation + +Using npm: + +``` +npm install dplayer --save +``` + +Using Yarn: + +``` +yarn add dplayer +``` + +## Quick Start + +
+
+
+ +```html + +
+ +``` + +```js +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + screenshot: true, + video: { + url: 'demo.mp4', + pic: 'demo.jpg', + thumbnails: 'thumbnails.jpg' + }, + subtitle: { + url: 'webvtt.vtt' + }, + danmaku: { + id: 'demo', + api: 'https://api.prprpr.me/dplayer/' + } +}); +``` + +Work with module bundler: + +```js +import 'DPlayer/dist/DPlayer.min.css'; +import DPlayer from 'DPlayer'; + +const dp = new DPlayer(options); +``` + +## Options + +Name|Default|Note +----|-------|---- +container | document.querySelector('.dplayer') | player container +live | false | enable live mode, [see more details](http://dplayer.js.org/docs/#/?id=live-mode) +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 +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 more details](http://dplayer.js.org/docs/#/?id=live-mode) +video | - | video info +video.quality | - | [see more details](http://dplayer.js.org/docs/#/?id=quality-switching) +video.defaultQuality | - | [see more details](http://dplayer.js.org/docs/#/?id=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' or custom type, [see more details](http://dplayer.js.org/docs/#/?id=mse-support) +video.customType | - | custom video type, [see more details](http://dplayer.js.org/docs/#/?id=mse-support) +subtitle | - | external subtitle +subtitle.url | `required` | subtitle url +subtitle.type | 'webvtt' | values: 'webvtt', 'ass', but only webvtt is supported for now +subtitle.fontSize | '20px' | subtitle font size +subtitle.bottom | '40px' | values like: '10px' '10%', the distance between the subtitle and player bottom +subtitle.color | '#fff' | subtitle color +danmaku | - | showing danmaku +danmaku.id | `required` | danamku pool id, it must be unique +danmaku.api | `required` | [see more details](http://dplayer.js.org/docs/#/?id=back-end) +danmaku.token | - | back end verification token +danmaku.maximum | - | danmaku maximum quantity +danmaku.addition | - | additional danmaku, [see more details](http://dplayer.js.org/docs/#/?id=bilibili-danmaku-and-video-link) +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 | allow danmaku overlap, notice that player will remember user setting, default setting will not work after user set it themselves +contextmenu | [] | custom contextmenu +mutex | true | pause other players when this player start play + +For example: + +
+
+
+ +```js +const dp = new DPlayer({ + container: document.getElementById('player'), + autoplay: false, + theme: '#FADFA3', + loop: true, + lang: 'zh-cn', + screenshot: true, + hotkey: true, + preload: 'auto', + logo: 'logo.png', + volume: 0.7, + mutex: true, + video: { + url: 'dplayer.mp4', + pic: 'dplayer.png', + thumbnails: 'thumbnails.jpg', + type: 'auto' + }, + subtitle: { + url: 'dplayer.vtt', + type: 'webvtt', + fontSize: '25px', + bottom: '10%', + color: '#b7daff' + }, + danmaku: { + id: '9E2E3368B56CDBB4', + api: 'https://api.prprpr.me/dplayer/', + token: 'tokendemo', + maximum: 1000, + addition: ['https://api.prprpr.me/dplayer/bilibili?aid=4157142'], + user: 'DIYgod', + bottom: '15%', + unlimited: true + }, + contextmenu: [ + { + text: 'custom1', + link: 'https://github.com/DIYgod/DPlayer' + }, + { + text: 'custom2', + click: (player) => { + console.log(player); + } + } + ] +}); +``` + +## API + ++ `dp.play()`: play video + ++ `dp.pause()`: pause video + ++ `dp.seek(time: number)`: seek to specified millisecond time + + ```js + dp.seek(1000); + ``` + ++ `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/docs/#/?id=event-binding) + ++ `dp.switchVideo(video, danmaku)`: switch to a new video, the parameters in `video` and `danmaku` is the same as option + + ```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)`: show message + ++ `dp.switchQuality(index: number)`: switch quality + ++ `dp.destroy()`: destroy player + ++ `dp.speed(rate: number)`: set video speed + ++ `dp.video`: native video + + + `dp.video.currentTime`: returns the current playback position + + + `dp.video.loop`: returns whether the video should start over again when finished + + + `dp.video.paused`: returns whether the video paused + + + most [native api](http://www.w3schools.com/tags/ref_av_dom.asp) are supported + ++ `dp.danmaku` + + + `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'); + }); + ``` + + + `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' + }); + ``` + + + `dp.danmaku.opacity(percentage: number)`: set danmaku opacity, opacity should between 0 and 1 + + ```js + dp.danmaku.opacity(0.5); + ``` + + + `dp.danmaku.clear()`: clear all danmakus + + + `dp.danmaku.hide()`: hide danmaku + + + `dp.danmaku.show()`: show danmaku + ++ `dp.fullScreen`: two type: `web` or `browser`, the default one is `browser` + + + `dp.fullScreen.request(type: string)`: request fullscreen + + ```js + dp.fullScreen.request('web'); + ``` + + + `dp.fullScreen.cancel(type: string)`: cancel fullscreen + + ```js + dp.fullScreen.cancel('web'); + ``` + +## Event binding + +`dp.on(event, handler)` + +```js +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 + +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 +- subtitle_show +- subtitle_hide +- subtitle_change + +## Quality switching + +Set video url and video type in video.quality, set default quality by video.defaultQuality. + +
+
+
+ +```js +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + quality: [{ + name: 'HD', + url: 'demo.m3u8', + type: 'hls' + }, { + name: 'SD', + url: 'demo.mp4', + type: 'normal' + }], + defaultQuality: 0, + pic: 'demo.png', + thumbnails: 'thumbnails.jpg', + } +}); +``` + +## Danmaku + +### Danmaku API + +**Ready-made API** + +url: https://api.prprpr.me/dplayer/ + +Daily backup data: [DPlayer-data](https://github.com/DIYgod/DPlayer-data) + +**Setting up yourself** + +[DPlayer-node](https://github.com/MoePlayer/DPlayer-node) + +### Bilibili danmaku + +API: [https://api.prprpr.me/dplayer/v2/bilibili?aid=[aid]](https://api.prprpr.me/dplayer/v2/bilibili?aid=[aid]) or [https://api.prprpr.me/dplayer/v2/bilibili?cid=[cid]](https://api.prprpr.me/dplayer/v2/bilibili?cid=[cid]) + +```js +const option = { + danmaku: { + // ... + addition: ['https://api.prprpr.me/dplayer/v2/bilibili?aid=[aid]'] + } +} +``` + +## MSE support + +### HLS + +It requires the library [hls.js](https://github.com/video-dev/hls.js) and it should be loaded before `DPlayer.min.js`. + +
+
+
+ +```html + +
+ + +``` + +```js +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'demo.m3u8', + type: 'hls' + } +}); +``` + +```js +// another way, use customType +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'demo.m3u8', + type: 'customHls', + customType: { + 'customHls': function (video, player) { + const hls = new Hls(); + hls.loadSource(video.src); + hls.attachMedia(video); + } + } + } +}); +``` + +### MPEG DASH + +It requires the library [dash.js](https://github.com/Dash-Industry-Forum/dash.js) and it should be loaded before `DPlayer.min.js`. + +
+
+
+ +```html + +
+ + +``` + +```js +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'demo.mpd', + type: 'dash' + } +}); +``` + +```js +// another way, use customType +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'demo.mpd', + type: 'customDash', + customType: { + 'customDash': function (video, player) { + dashjs.MediaPlayer().create().initialize(video, video.src, false); + } + } + } +}); +``` + +### FLV + +It requires the library [flv.js](https://github.com/Bilibili/flv.js) and it should be loaded before `DPlayer.min.js`. + +
+
+
+ +```html + +
+ + +``` + +```js +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'demo.flv', + type: 'flv' + } +}); +``` + +```js +// another way, use customType +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'demo.flv', + type: 'customFlv', + customType: { + 'customFlv': function (video, player) { + const flvPlayer = flvjs.createPlayer({ + type: 'flv', + url: video.src + }); + flvPlayer.attachMediaElement(video); + flvPlayer.load(); + } + } + } +}); +``` + +### WebTorrent + +It requires the library [webtorrent](https://github.com/webtorrent/webtorrent) and it should be loaded before `DPlayer.min.js`. + +
+
+
+ +```html + +
+ + +``` + +```js +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'magnet:demo', + type: 'webtorrent' + } +}); +``` + +```js +// another way, use customType +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + video: { + url: 'magnet:demo', + type: 'customWebTorrent', + customType: { + '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'); + }); + }); + } + } + } +}); +``` + +## Live + +
+
+
+ +You can also regard DPlayer as a live player, at first, you should prepare a WebSocket backend yourself. + +Init DPlayer: + +```js +const dp = new DPlayer({ + container: document.getElementById('dplayer'), + live: true, + danmaku: true, + apiBackend: { + read: function (endpoint, callback) { + console.log('Pretend to connect WebSocket'); + callback(); + }, + send: function (endpoint, danmakuData, callback) { + console.log('Pretend to send danamku via WebSocket', danmakuData); + callback(); + } + }, + video: { + url: 'demo.m3u8', + type: 'hls' + } +}); +``` + +After getting a danmaku via WebSocket: + +```js +const danmaku = { + text: 'Get a danamku via WebSocket', + color: '#fff', + type: 'right' +}; +dp.danmaku.draw(danmaku); +``` + +## CDN + +- [jsDelivr](https://www.jsdelivr.com/package/npm/dplayer) +- [cdnjs](https://cdnjs.com/libraries/dplayer) +- [unpkg](https://unpkg.com/dplayer/) + +## FAQ + +### Why can't some videos be full screen? + +If player is contained in a iframe, try adding the allowfullscreen attribute to the iframe. + +For full browser support it should look like this: + +```html + +``` + +### Why can't player autoplay in some mobile browsers? + +Most mobile browsers forbid video autoplay, you wont be able to achieve it without hacks. \ No newline at end of file diff --git a/docs/zh-Hans/ecosystem.md b/docs/zh-Hans/ecosystem.md new file mode 100644 index 0000000..0875ebc --- /dev/null +++ b/docs/zh-Hans/ecosystem.md @@ -0,0 +1,60 @@ +--- +nav: zh-Hans +search: zh-Hans +--- + +# 生态系统 + +Let's make DPlayer better, feel free to submit yours in [`Let me know!`](https://github.com/MoePlayer/DPlayer/issues/31) + +## Help + +### Joining the Discussion + +- [Telegram Group](https://t.me/adplayer) +- [QQ Group](https://shang.qq.com/wpa/qunwpa?idkey=bf22213ae0028a82e5adf3f286dfd4f01e0997dc9f1dcd8e831a0a85e799be17): 415835947 + +### Creating issue + +- [MoePlayer/DPlayer/issues](https://github.com/MoePlayer/DPlayer/issues) + +## Related Projects + +### Tooling + +- [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 + +### 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 +- [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 + +## Who use DPlayer? + +- [嘀哩嘀哩](http://www.dilidili.wang/) +- [银弹字幕组](https://www.sbsub.com/) +- [纸飞机南航青年网络社区](http://my.nuaa.edu.cn/video-video.html) +- [otomads](https://otomads.com/) + +## Contributors + +This project exists thanks to all the people who contribute. + + \ No newline at end of file