mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-12 23:36:15 -08:00
docs(core): [SITE-04] document event payloads and synchronous dispatch
This commit is contained in:
1 parent
0a060e6088
commit
8d2ec199d7
96 files changed
+5823
-2965
No files matched your search
+99
-1
@@ -1027,6 +1027,104 @@ art.on('ready', onReady);
|
||||
|
||||
:::
|
||||
|
||||
## Subscription and synchronous dispatch {#emitter-contract}
|
||||
|
||||
Players inherit `Artplayer.Emitter`. `on(name, callback, ctx?)`, `once`, `off`, and `emit(name, ...args)` all return the current instance. They are neither DOM addEventListener nor a Promise-based message queue.
|
||||
|
||||
- on keeps registration order. Registering the same function twice invokes it twice. ctx is passed unchanged as an ordinary function's this; omission means undefined, not an automatic player binding. Arrows retain their lexical this.
|
||||
- emit synchronously walks a snapshot taken at dispatch start. Added listeners wait until a later dispatch; removed ordinary listeners already in the snapshot still run. Arguments retain their references; callback return values are ignored.
|
||||
- once removes itself before invoking the callback and prevents nested dispatch from consuming the same registration twice, even if the callback throws. off(name, callback) removes all ordinary/once registrations for that function regardless of ctx; off(name) removes every listener for the name.
|
||||
- A synchronous throw stops subsequent listeners in that dispatch and propagates through the call stack. Async callbacks are not awaited; handle their failures yourself. The name error has no special Node EventEmitter behavior.
|
||||
- e is the lazily created registry of fn/ctx records and remains a visible historical interface. A fresh standalone Emitter may not have it yet. Use on/off rather than editing the table. Numeric keys share their string-equivalent channel; symbols have separate keys. The root player's historical overloads accept narrower names than the accurate entry or a generic Emitter.
|
||||
|
||||
Manual emit only sends a notification; it does not replace player methods. Emitting built-in names may also trigger internal listeners. Destruction releases core-owned DOM/internal subscriptions but does not clear every user registration; remove unwanted subscriptions if you retain the instance. The advanced-properties guide explains the separate DOM listener manager, art.events.
|
||||
|
||||
## Native forwarding {#native-event-contract}
|
||||
|
||||
The default media events below are forwarded with a `video:` prefix and the original Event object. The browser or proxy determines when they occur:
|
||||
|
||||
`abort`, `canplay`, `canplaythrough`, `durationchange`, `emptied`, `ended`, `error`, `loadeddata`, `loadedmetadata`, `loadstart`, `pause`, `play`, `playing`, `progress`, `ratechange`, `seeked`, `seeking`, `stalled`, `suspend`, `timeupdate`, `volumechange`, `waiting`.
|
||||
|
||||
The `video:error` argument is not a MediaError or Error instance; inspect `art.video.error` when needed. Historical types include `video:complete` and `video:encrypted`, but neither appears in the default config.events, so the core does not automatically forward them. An adapter must provide forwarding or configure the event inventory before construction. A declared name does not prove an event is produced at runtime.
|
||||
|
||||
Global forwarding uses the player's currently bound document/window and passes the original Event:
|
||||
|
||||
| Prefix | Default names |
|
||||
| --- | --- |
|
||||
| `document:` | click, mouseup, keydown, touchend, touchcancel, touchmove, mousemove, pointerup, contextmenu, pointermove, visibilitychange, webkitfullscreenchange |
|
||||
| `window:` | resize, scroll, orientationchange |
|
||||
|
||||
These are not restricted to interactions inside the player. events.bindGlobalEvents can rebind them to the owning window. Destruction stops native forwarding. Arguments preserve native subtypes such as KeyboardEvent/MouseEvent; forwarding does not guarantee that a browser produces every event.
|
||||
|
||||
## Custom payloads and timing {#custom-event-contract}
|
||||
|
||||
Internal and user listeners share synchronous dispatch. Internal listeners registered during construction can emit a custom event before later user listeners receive the native forwarding event. Do not assume one total ordering across all browsers and proxies.
|
||||
|
||||
### Media and lifecycle
|
||||
|
||||
| Event | Payload and actual stage |
|
||||
| --- | --- |
|
||||
| `ready` | No arguments; once in the first successfully handled video:canplay, after isReady is set. Does not wait for async plugins, subtitles, or SDKs |
|
||||
| `restart` | Submitted URL; for a ready player with an existing URL, the active source change emits at canplay when the actual media URL changed. Assigning the same URL need not emit it |
|
||||
| `play` | No arguments; art.play emits after the media play call succeeds while its operation remains current. Direct video.play does not generate this custom event, though native video:play can occur |
|
||||
| `pause` | No arguments; art.pause emits synchronously after calling media pause and updating the notice, even if already paused. Separate from video:pause |
|
||||
| `destroy` | No arguments; after native resources/template cleanup, instance removal, and setting isDestroy true. Do not assume mounted DOM inside the callback; destroy(false) separately preserves DOM |
|
||||
| `error` | Original error value and retry count; emitted when reconnection submits a retry after waiting, not on every native error or every async failure |
|
||||
| `seek` | currentTime after assignment and the original requested time (number or string), not native seeked completion |
|
||||
| `muted` | Boolean supplied to art.muted, including repeated assignments. Observe video:volumechange for direct video.muted changes |
|
||||
| `screenshot` | PNG data URI after image capture and an attempted download, not proof a file was saved. getDataURL/getBlobUrl alone do not emit it |
|
||||
| `airplay` | No arguments; after invoking an available native picker, not confirmation of remote connection or playback |
|
||||
| `raf` | No arguments; emitted during playback when USE_RAF was enabled before construction. Not a decoded-video-frame callback |
|
||||
|
||||
### UI and input
|
||||
|
||||
| Event | Payload and actual stage |
|
||||
| --- | --- |
|
||||
| `info`, `layer`, `loading`, `mask`, `subtitle`, `contextmenu`, `control`, `setting` | Boolean assigned to show; repeated identical assignments can emit again. Not animation completion |
|
||||
| `focus` / `blur` | Original document click/contextmenu event, classified by whether its path includes the player. Not DOM focus/blur; can emit even without a state change |
|
||||
| `click` / `dblclick` | Video click event. Double-click is counted within DBCLICK_TIME; the first click emits immediately, before playback/fullscreen actions |
|
||||
| `hover` | Enter/leave boolean and original mouseenter/mouseleave event |
|
||||
| `mousemove` | MouseEvent from the player node, not throttled document coordinates |
|
||||
| `hotkey` | KeyboardEvent after matching shortcut callbacks, subject to focus/input filtering |
|
||||
| `keydown` | KeyboardEvent after desktop shortcut dispatch, even without a matching key or player focus. Mobile does not automatically install this shortcut dispatcher; use document:keydown for the raw global event |
|
||||
| `resize` | No arguments; window debounce, metadata, display-mode changes, or explicit layout paths, not just window:resize |
|
||||
| `view` | Viewport-intersection boolean after leading scroll throttling, not complete visibility or occlusion detection |
|
||||
| `lock` | Boolean after the built-in lock plugin updates state, not an observer of direct isLock assignment |
|
||||
| `setBar` | Type, fraction, and optional original mouse/touch event. Built-in types are loaded/played/hover; programmatic and keyboard updates may omit the third argument. A progress UI protocol, not playback completion |
|
||||
|
||||
### Size, display, and subtitles
|
||||
|
||||
| Event | Payload and actual stage |
|
||||
| --- | --- |
|
||||
| `aspectRatio` / `flip` | String after the setter normalizes an empty value; not necessarily a member of the built-in selector list |
|
||||
| `autoHeight` / `autoSize` | Height number / {width, height} after valid media dimensions allow layout. No event when calculation is unavailable |
|
||||
| `fullscreen` / `fullscreenWeb` / `mini` / `pip` | Boolean from the display adapter's observation or transition. Duplicate-assignment behavior varies by mode; not a universal replacement for request completion |
|
||||
| `fullscreenError` | Owned native fullscreen error event/adapter value. A request Promise rejection may instead only update the notice; this does not collect every fullscreen failure |
|
||||
| `subtitleOffset` | Original requested offset; stored offset clamps to[-10,10]. No event without cues |
|
||||
| `subtitleBeforeUpdate` / `subtitleAfterUpdate` | Cue arrays, not individual cues, synchronously before/after rendering. Neither emits without active cues |
|
||||
| `subtitleLoad` | Current cue array and the subtitle manager's current options (possibly null), after native track load. Not an alias for switch fulfillment |
|
||||
|
||||
## TypeScript event views {#event-types}
|
||||
|
||||
The root entry retains historical declarations and custom augmentation: video:error was typed as Error and subtitle updates as one VTTCue. It also has array overloads through SubtitleUpdateEvents. Use `artplayer/runtime` for accurate contextual inference: Event for native media payloads, SubtitleCue arrays for updates, unknown for error/fullscreenError, and a string-capable second seek argument. Unknown custom events retain unknown arrays without runtime payload validation. A generic Emitter can declare its own event tuples:
|
||||
|
||||
```ts
|
||||
import Artplayer from 'artplayer/runtime';
|
||||
import type { Events, SubtitleCue } from 'artplayer/runtime';
|
||||
|
||||
const bus = new Artplayer.Emitter<{ progress: [value: number] }>();
|
||||
const context = { total: 0 };
|
||||
bus.on('progress', function (value) { this.total += value; }, context);
|
||||
bus.emit('progress', 2);
|
||||
|
||||
const art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4' });
|
||||
art.on('video:error', (event: Event) => console.info(event.type));
|
||||
art.on('subtitleBeforeUpdate', (cues: SubtitleCue[]) => console.info(cues.length));
|
||||
const seekArgs: Events['seek'] = [0, '0'];
|
||||
void seekArgs;
|
||||
```
|
||||
|
||||
|
||||
## `ready`
|
||||
|
||||
Triggered when the player is ready for the first time.
|
||||
@@ -1782,7 +1880,7 @@ The browser estimates it can play the media through to the end without stopping
|
||||
|
||||
## `video:complete`
|
||||
|
||||
The OfflineAudioContext rendering is complete.
|
||||
Historical declared name; not forwarded by the default video event inventory. Use `video:ended` for media reaching its end.
|
||||
|
||||
## `video:durationchange`
|
||||
|
||||
|
||||
Reference in new issue
Block a user