From b1819b3ea2ccaf65aea8d894afabdbec4cb2d28f Mon Sep 17 00:00:00 2001 From: Harvey Zack Date: Thu, 25 Apr 2019 14:15:12 +0800 Subject: [PATCH] add bilibiliDanmuParse --- .../src/bilibiliDanmuParse.js | 26 ++++ .../artplayer-plugin-danmu/src/danmuku.js | 113 ++++++++++++++++++ packages/artplayer-plugin-danmu/src/index.js | 69 +++-------- packages/artplayer/src/utils/component.js | 49 ++++---- 4 files changed, 174 insertions(+), 83 deletions(-) create mode 100644 packages/artplayer-plugin-danmu/src/bilibiliDanmuParse.js create mode 100644 packages/artplayer-plugin-danmu/src/danmuku.js diff --git a/packages/artplayer-plugin-danmu/src/bilibiliDanmuParse.js b/packages/artplayer-plugin-danmu/src/bilibiliDanmuParse.js new file mode 100644 index 000000000..85e67d963 --- /dev/null +++ b/packages/artplayer-plugin-danmu/src/bilibiliDanmuParse.js @@ -0,0 +1,26 @@ +export default function bilibiliDanmuParse(xmlString) { + if (typeof xmlString !== 'string') return []; + const regSrt = '(.+)'; + const listReg = new RegExp(regSrt, 'gi'); + const itemReg = new RegExp(regSrt, 'i'); + const srtList = xmlString.match(listReg); + return srtList.length + ? srtList.map(item => { + const [, attrStr, text] = item.match(itemReg); + const attr = attrStr.split(','); + return attr.length === 8 && text.trim() + ? { + text, + time: Number(attr[0]), + mode: Number(attr[1]), + size: Number(attr[2]), + color: `#${Number(attr[3]).toString(16)}`, + timestamp: Number(attr[4]), + pool: Number(attr[5]), + userID: Number(attr[6]), + rowID: Number(attr[7]), + } + : null; + }) + : []; +} diff --git a/packages/artplayer-plugin-danmu/src/danmuku.js b/packages/artplayer-plugin-danmu/src/danmuku.js new file mode 100644 index 000000000..b8ae63dd6 --- /dev/null +++ b/packages/artplayer-plugin-danmu/src/danmuku.js @@ -0,0 +1,113 @@ +export default class Danmuku { + constructor(art, option) { + this.art = art; + this.option = {}; + this.config(option); + this.current = []; + this.layer = null; + this.isStop = false; + this.init(); + } + + static get option() { + return { + danmu: [], + speed: 3, + opacity: 1, + color: '#fff', + size: 14, + }; + } + + static get scheme() { + return { + danmu: { + type: 'array', + child: { + text: 'string', + size: 'number', + time: 'number', + color: 'string', + mode: 'number', + }, + }, + speed: 'number', + opacity: 'number', + color: 'string', + size: 'number', + }; + } + + init() { + const { layers } = this.art; + this.layer = layers.add({ + name: 'danmu', + style: { + position: 'absolute', + left: 0, + top: 0, + right: 0, + bottom: 0, + width: '100%', + height: '100%', + overflow: 'hidden', + }, + }); + } + + emit(danmu) { + const { errorHandle, setStyles, append } = this.art.constructor.utils; + errorHandle(danmu.text, 'Danmu text cannot be empty'); + errorHandle(danmu.time, 'Danmu time cannot be empty'); + const $danmu = document.createElement('div'); + $danmu.innerText = danmu.text; + setStyles($danmu, { + userSelect: 'none', + position: 'absolute', + whiteSpace: 'pre', + pointerEvents: 'none', + perspective: '500px', + display: 'inline-block', + willChange: 'transform', + fontSize: `${danmu.size || 14}px`, + color: danmu.color || '#fff', + fontFamily: 'SimHei, "Microsoft JhengHei", Arial, Helvetica, sans-serif', + fontWeight: 'normal', + lineHeight: '1.125', + opacity: '1', + textShadow: + 'rgb(0, 0, 0) 1px 0px 1px, rgb(0, 0, 0) 0px 1px 1px, rgb(0, 0, 0) 0px -1px 1px, rgb(0, 0, 0) -1px 0px 1px', + left: '638px', + top: '0px', + transform: 'translateX(-626.14px) translateY(0px) translateZ(0px)', + transition: '-webkit-transform 0s linear 0s', + }); + this.current.push(append(this.layer.$ref, $danmu)); + this.art.emit('artplayerPluginDanmu:emit', danmu); + } + + config(option) { + this.option = Object.assign({}, Danmuku.option, option); + this.art.constructor.validator(this.option, Danmuku.scheme); + } + + stop() { + this.isStop = true; + this.art.emit('artplayerPluginDanmu:stop'); + } + + start() { + this.isStop = false; + this.art.emit('artplayerPluginDanmu:start'); + } + + show() { + this.layer.$ref.style = 'none'; + this.art.emit('artplayerPluginDanmu:show'); + } + + hide() { + this.layer.$ref.style = 'block'; + this.art.emit('artplayerPluginDanmu:hide'); + } +} diff --git a/packages/artplayer-plugin-danmu/src/index.js b/packages/artplayer-plugin-danmu/src/index.js index ecd8fa32d..b083e74fd 100644 --- a/packages/artplayer-plugin-danmu/src/index.js +++ b/packages/artplayer-plugin-danmu/src/index.js @@ -1,60 +1,21 @@ -function artplayerPluginDanmu(art) { - const { layers } = art; - const { - utils: { append, errorHandle, setStyles }, - } = art.constructor; +import Danmuku from './danmuku'; +import bilibiliDanmuParse from './bilibiliDanmuParse'; - const layer = layers.add({ - name: 'danmu', - style: { - position: 'absolute', - left: 0, - top: 0, - right: 0, - bottom: 0, - width: '100%', - height: '100%', - overflow: 'hidden', - }, - }); - - const danmuList = []; - function emit(style = {}) { - const $danmu = document.createElement('div'); - $danmu.innerText = '23333'; - setStyles($danmu, { - 'user-select': 'none', - 'position': 'absolute', - 'white-space': 'pre', - 'pointer-events': 'none', - 'perspective': '500px', - 'display': 'inline-block', - 'will-change': 'transform', - 'font-size': '25px', - 'color': 'rgb(254, 241, 2)', - 'font-family': 'SimHei, "Microsoft JhengHei", Arial, Helvetica, sans-serif', - 'font-weight': 'normal', - 'line-height': '1.125', - 'opacity': '1', - 'text-shadow': 'rgb(0, 0, 0) 1px 0px 1px, rgb(0, 0, 0) 0px 1px 1px, rgb(0, 0, 0) 0px -1px 1px, rgb(0, 0, 0) -1px 0px 1px', - 'left': '638px', - 'top': '0px', - 'transform': 'translateX(-626.14px) translateY(0px) translateZ(0px)', - 'transition': '-webkit-transform 0s linear 0s', - }); - danmuList.push(append(layer.$ref, $danmu)); - } - - emit({ - - }); - - return { - name: 'artplayerPluginDanmu', - config(option) {}, - emit() {}, +function artplayerPluginDanmu(option) { + return art => { + const danmuku = new Danmuku(art, option); + return { + name: 'artplayerPluginDanmu', + emit: danmuku.emit, + start: danmuku.start, + stop: danmuku.stop, + hide: danmuku.hide, + show: danmuku.show, + config: danmuku.config, + }; }; } +artplayerPluginDanmu.bilibiliDanmuParse = bilibiliDanmuParse; window.artplayerPluginDanmu = artplayerPluginDanmu; export default artplayerPluginDanmu; diff --git a/packages/artplayer/src/utils/component.js b/packages/artplayer/src/utils/component.js index 4de40dd4a..d56478b94 100644 --- a/packages/artplayer/src/utils/component.js +++ b/packages/artplayer/src/utils/component.js @@ -16,6 +16,8 @@ export default function component(art, parent, target, getOption, callback, titl setStyles($element, option.style); } + insertByIndex(target, $element, option.index || parent.id); + if (option.click) { art.events.proxy($element, 'click', event => { event.preventDefault(); @@ -24,33 +26,6 @@ export default function component(art, parent, target, getOption, callback, titl }); } - Object.defineProperty(option, '$ref', { - get: () => $element, - }); - - Object.defineProperty(option, 'hide', { - value: () => { - setStyle($element, 'display', 'none'); - art.emit(`${title}:hide`, $element); - }, - }); - - Object.defineProperty(option, 'show', { - value: (type = 'block') => { - setStyle($element, 'display', type); - art.emit(`${title}:show`, $element); - }, - }); - - Object.defineProperty(option, 'remove', { - value: () => { - remove($element); - art.emit(`${title}:remove`, $element); - }, - }); - - insertByIndex(target, $element, option.index || parent.id); - if (option.mounted) { option.mounted($element, parent, art); } @@ -59,9 +34,25 @@ export default function component(art, parent, target, getOption, callback, titl callback($element, parent, art); } - parent[name] = option; + parent[name] = { + $ref: $element, + hide() { + setStyle($element, 'display', 'none'); + art.emit(`${title}:hide`, $element); + }, + show(type = 'block') { + setStyle($element, 'display', type); + art.emit(`${title}:show`, $element); + }, + remove() { + remove($element); + art.emit(`${title}:remove`, $element); + }, + }; + art.emit(`${title}:add`, option); + return parent[name]; } - return option; + return null; }