Files
ArtPlayer/packages/artplayer-plugin-danmuku/src/bilibili-parser.ts
T

59 lines
1.5 KiB
TypeScript

import type { ParsedDanmu, ParserReply, ParserRequest } from './parser-types'
export function getMode(key: number): number {
switch (key) {
case 1:
case 2:
case 3:
return 0
case 4:
return 2
case 5:
return 1
default:
return 0
}
}
export function bilibiliDanmuParseFromXml(xmlString: unknown): ParsedDanmu[] {
if (typeof xmlString !== 'string')
return []
const reg = /<d[^>]*?p="(?<p>[^"]+)"[^>]*>(?<text>.*?)<\/d>/gs
const matches = xmlString.matchAll(reg)
return Array.from(matches)
.map((match) => {
const attr = match.groups!.p!.split(',')
if (attr.length >= 8) {
const text = match.groups!.text!
.trim()
.replaceAll('&quot;', '"')
.replaceAll('&apos;', '\'')
.replaceAll('&lt;', '<')
.replaceAll('&gt;', '>')
.replaceAll('&amp;', '&')
return {
text,
time: Number(attr[0]),
mode: getMode(Number(attr[1])),
fontSize: Number(attr[2]),
color: `#${Number(attr[3]).toString(16)}`,
timestamp: Number(attr[4]),
pool: Number(attr[5]),
userID: attr[6]!,
rowID: Number(attr[7]),
}
}
else {
return null
}
})
.filter(Boolean) as ParsedDanmu[]
}
export function onmessage({ data }: MessageEvent<ParserRequest>) {
const { xml, id } = data
const danmus = bilibiliDanmuParseFromXml(xml)
globalThis.postMessage({ danmus, id } satisfies ParserReply)
}