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')}` } }