Bilibili-Evolved/registry/lib/components/video/danmaku/converter/ass-danmaku.ts
2021-10-26 13:19:37 +08:00

86 lines
2.4 KiB
TypeScript

import { BasicDanmakuData, Danmaku } from './danmaku-data'
import { DanmakuType } from './danmaku-type'
export type Duration = (danmaku: Danmaku) => number
export type BlockTypes = (DanmakuType | 'color')[]
export interface AssDanmakuData extends BasicDanmakuData {
typeTag: string
colorTag: string
endTime: string
}
export interface FontStyles {
[size: number]: string
}
export interface Resolution {
x: number
y: number
}
export class AssDanmaku extends Danmaku {
typeTag: string
colorTag: string
endTime: string
constructor({
content, time, type, fontSize, color, typeTag, colorTag, endTime,
}: AssDanmakuData) {
super({
content, time, type, fontSize, color,
})
this.typeTag = typeTag
this.colorTag = colorTag
this.endTime = endTime
}
text(fontStyles: FontStyles) {
let style = fontStyles[this.fontSize]
if (!style) {
style = fontStyles['25']
}
const styleName = style.match(/Style:(.*?),/)[1].trim()
return `Dialogue: 0,${this.time},${this.endTime},${styleName},,0,0,0,,{${this.typeTag}${this.colorTag}}${this.content}`
}
}
export class AssDanmakuDocument {
danmakus: AssDanmaku[]
title: string
fontStyles: FontStyles
blockTypes: BlockTypes
resolution: Resolution
constructor(
danmakus: AssDanmaku[],
title: string,
fontStyles: FontStyles,
blockTypes: BlockTypes,
resolution: Resolution,
) {
this.danmakus = danmakus
this.title = title
this.fontStyles = fontStyles
this.blockTypes = blockTypes
this.resolution = resolution
}
generateAss() {
const meta = `
[Script Info]
; Script generated by Bilibili Evolved Danmaku Converter
; https://github.com/the1812/Bilibili-Evolved/
Title: ${this.title}
ScriptType: v4.00+
PlayResX: ${this.resolution.x}
PlayResY: ${this.resolution.y}
Timer: 10.0000
WrapStyle: 2
ScaledBorderAndShadow: no
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
${Object.values(this.fontStyles).join('\n')}
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
`.trim()
return `${meta}\n${this.danmakus
.map(it => it.text(this.fontStyles))
.filter(it => it !== '').join('\n')}`
}
}