mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-08 19:06:15 -08:00
109 lines
5.1 KiB
TypeScript
109 lines
5.1 KiB
TypeScript
import type { Danmu, EventMap, Icons, Input, Item, NormalizedDanmu, NormalizedOption, Owner, Point, RuntimeFactory, RuntimeOption, RuntimeResult, Slider } from 'artplayer-plugin-danmuku/runtime'
|
|
import Artplayer from 'artplayer'
|
|
import runtime from 'artplayer-plugin-danmuku/runtime'
|
|
|
|
type Equal<A, B> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? true : false
|
|
type Assert<T extends true> = T
|
|
type FactoryArguments = Assert<Equal<Parameters<typeof runtime>, [option: RuntimeOption]>>
|
|
type FactoryReturns = Assert<Equal<ReturnType<ReturnType<typeof runtime>>, RuntimeResult>>
|
|
type EmitReturns = Assert<Equal<ReturnType<RuntimeResult['emit']>, Promise<Owner>>>
|
|
type LoadReturns = Assert<Equal<ReturnType<RuntimeResult['load']>, Promise<Owner>>>
|
|
type CommandReturns = Assert<Equal<ReturnType<RuntimeResult['config']>, Owner>>
|
|
type OwnerHasNoFacadeKeys = Assert<Equal<Extract<'name' | 'mount', keyof Owner>, never>>
|
|
type VisiblePayload = Assert<Equal<EventMap['artplayerPluginDanmuku:visible'], [item: Item]>>
|
|
type LoadedPayload = Assert<Equal<EventMap['artplayerPluginDanmuku:loaded'], [queue: Item[]]>>
|
|
|
|
function expectOption(_option: NormalizedOption) {}
|
|
const row: Danmu = { text: 'extended input', id: 'message-1', author: { name: 'test' }, style: { fontWeight: 'bold' } }
|
|
const input: Input = () => [row]
|
|
const asyncInput: Input = async () => [row]
|
|
const point: Point = [10, 5]
|
|
const margin: Slider<[number | string, number | string]> = { steps: [{ name: 'half', value: [10, '50%'], hide: true, show: false }] }
|
|
const options: RuntimeOption = {
|
|
danmuku: input,
|
|
points: [point],
|
|
MARGIN: margin,
|
|
SPEED: { steps: [{ name: 'fast', value: 2.5, hide: true }] },
|
|
filter(danmu) {
|
|
expectOption(this)
|
|
const normalized: NormalizedDanmu = danmu
|
|
const time: number = danmu.time
|
|
const extension: unknown = danmu.author
|
|
// @ts-expect-error Queue allocation has not run when filter is invoked.
|
|
const state: string = danmu.$state
|
|
void [normalized, time, extension, state]
|
|
return true
|
|
},
|
|
async beforeEmit(danmu) {
|
|
expectOption(this)
|
|
const text: string = danmu.text
|
|
void text
|
|
return true
|
|
},
|
|
async beforeVisible(item) {
|
|
expectOption(this)
|
|
const state: 'wait' | 'ready' | 'emit' | 'stop' = item.$state
|
|
const index: number = item.$index
|
|
const node: HTMLDivElement | null = item.$ref
|
|
const extra: unknown = item.author
|
|
void [state, index, node, extra]
|
|
return true
|
|
},
|
|
}
|
|
const art = new Artplayer({ container: '#player', url: '/video.mp4', plugins: [runtime(options)] })
|
|
const factory: RuntimeFactory = runtime
|
|
const result = runtime({})(art)
|
|
const registered: 'artplayerPluginDanmuku' = result.name
|
|
const icon: string = runtime.icons.$check_on
|
|
const icons: Icons = runtime.icons
|
|
runtime.icons = icons
|
|
runtime.icons.$on = '<svg></svg>'
|
|
const promise: Promise<Owner> = result.emit(row)
|
|
const loading: Promise<Owner> = result.load(asyncInput)
|
|
const replacing: Promise<Owner> = result.load()
|
|
const owner: Owner = result.config({ opacity: 0.5 })
|
|
const stopped: Owner = owner.stop().start().suspend().continue().reset()
|
|
const configured: NormalizedOption = result.option
|
|
result.option.visible = false
|
|
result.mount(document.createElement('div'))
|
|
result.mount('#danmuku-mount')
|
|
const loadedPayload: EventMap['artplayerPluginDanmuku:loaded'] = [owner.queue]
|
|
const pointsPayload: EventMap['artplayerPluginDanmuku:points'] = [[point]]
|
|
const failedPayload: EventMap['artplayerPluginDanmuku:error'] = [new Error('failed')]
|
|
|
|
async function consume() {
|
|
const emitted = await result.emit({ text: 'await owner' })
|
|
const rows: Item[] = emitted.queue
|
|
const next: Owner = emitted.hide().show()
|
|
// @ts-expect-error The resolved owner does not expose the facade name.
|
|
void emitted.name
|
|
// @ts-expect-error The resolved owner does not own setting.mount.
|
|
emitted.mount('#mount')
|
|
return [rows, next]
|
|
}
|
|
// @ts-expect-error The factory still requires its options object.
|
|
runtime()
|
|
// @ts-expect-error Undefined is not a valid options object.
|
|
runtime(undefined)
|
|
// @ts-expect-error An emitted row requires text.
|
|
result.emit({ id: 'missing-text' })
|
|
// @ts-expect-error The runtime heatmap uses mutable pairs, not historical object points.
|
|
runtime({ points: [{ time: 1, value: 2 }] })
|
|
// @ts-expect-error Margin sliders carry pairs rather than scalar numbers.
|
|
runtime({ MARGIN: { steps: [{ value: 10 }] } })
|
|
// @ts-expect-error A live mount needs an explicit destination.
|
|
result.mount()
|
|
// @ts-expect-error Facade option is a getter, although the returned options object is mutable.
|
|
result.option = configured
|
|
// @ts-expect-error Facade isHide is a getter.
|
|
result.isHide = true
|
|
// @ts-expect-error Facade isStop is a getter.
|
|
result.isStop = true
|
|
// @ts-expect-error emit returns a Promise; synchronous chaining is not available.
|
|
result.emit(row).hide()
|
|
// @ts-expect-error The factory has icons but no default self-reference.
|
|
void runtime.default
|
|
|
|
export type { CommandReturns, EmitReturns, FactoryArguments, FactoryReturns, LoadedPayload, LoadReturns, OwnerHasNoFacadeKeys, VisiblePayload }
|
|
void [factory, registered, icon, promise, loading, replacing, stopped, loadedPayload, pointsPayload, failedPayload, consume]
|