UNPKG

@oplayer/danmaku

Version:

Danmaku plugin for oplayer

73 lines (64 loc) 1.98 kB
import { Comment } from './types' // 1..3滚动弹幕 4底端弹幕 5顶端弹幕 6逆向弹幕 7精准定位 8高级弹幕 export function getMode(key: number): Comment['mode'] { switch (key) { case 1: case 2: case 3: return 'rtl' case 4: return 'bottom' case 5: return 'top' case 6: return 'ltr' case 7: return 'top' default: return 'top' } } // http://jabbany.github.io/CommentCoreLibrary/docs/data-formats/bilibili-xml.html export function danmakuParseFromXml(xmlString: string) { //TODO: Named capturing groups are only available when targeting 'ES2018' or later. //@ts-ignore const matches = xmlString.matchAll(/<d (?:.*? )??p="(?<p>.+?)"(?: .*?)?>(?<text>.+?)<\/d>/gs) const result: Comment[] = [] Array.from(matches).forEach((match) => { const p = match.groups?.['p']?.split(',') let text = match.groups?.['text']?.trim() if (p && p.length >= 8 && text) { const modeId = Number(p[1]) const style: CSSStyleDeclaration = { fontSize: `${Number(p[2])}px`, color: `#${Number(p[3]).toString(16)}` } as any if (modeId >= 7) { const styledText = JSON.parse(text) text = styledText[4] if (styledText[12]) style.fontFamily = styledText[12] if (modeId == 7) { style.position = 'absolute' style.left = `${styledText[0]}px` style.right = `${styledText[1]}px` } else { // TODO custom render // https://github.com/weizhenye/Danmaku // style.transform = `rotateZ(${styledText[5]}deg) rotateY(${styledText[6]}deg)` } } result.push({ text, style, mode: getMode(Number(modeId)), time: Number(p[0]) }) } }) return result } export function danmakuParseFromUrl(src: string) { return fetch(src) .then((res) => res.text()) .then((xmlString) => danmakuParseFromXml(xmlString)) }