ArtPlayer documentation source bundle Generated offline by yarn build:llm. Source text is preserved after LF normalization. These are source references, not proof that every example or documented feature has passed release review. ===== Documentation Summary ===== ===== packages/artplayer-vitepress/docs/en/advanced/built-in.md ===== # Advanced Properties The `Advanced Properties` here refer to the `secondary properties` attached to the `instance`, which are less commonly used. ## `option` The player's options.
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); console.info(art.option); ``` :::warning Note If you directly modify this `option` object, the player will not respond immediately. ::: ## `template` Manages all `DOM` elements of the player.
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); console.info(art.template); console.info(art.template.$video); ``` :::warning Note To easily distinguish between `DOM` elements and regular objects, all `DOM` elements within the player are named with a `$` prefix. This is the definition of all `DOM` elements: [artplayer/types/template.d.ts](https://github.com/zhw2590582/ArtPlayer/blob/master/packages/artplayer/types/template.d.ts) ::: ## `events` Manages all `DOM` events for the player. It essentially proxies `addEventListener` and `removeEventListener`. When using the following methods to handle events, the events will also be automatically destroyed when the player is destroyed. - The `proxy` method is used to proxy `DOM` events. - The `hover` method is used to proxy custom `hover` events.
▶ Run Code
```js var container = document.querySelector('.artplayer-app'); var art = new Artplayer({ container: container, url: '/assets/sample/video.mp4', }); art.events.proxy(container, 'click', event => { console.info('click', event); }); art.events.hover(container, (event) => { console.info('mouseenter', event); }, (event) => { console.info('mouseleave', event); }); ``` :::warning Note If you need `DOM` events that should only exist during the player's lifecycle, it is strongly recommended to use these functions to avoid memory leaks. ::: ## `storage` Manages the player's local storage. - The `name` property is used to set the cache `key`. - The `set` method is used to set a cache. - The `get` method is used to retrieve a cache. - The `del` method is used to delete a cache. - The `clear` method is used to clear all caches.
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.storage.set('test', { foo: 'bar' }); const test = art.storage.get('test'); console.info(test); art.storage.del('test'); art.storage.clear(); ``` :::warning Note By default, all player instances share the same `localStorage`, and the default `key` is `artplayer_settings`. If you want different players to use different `localStorage`, you can modify `art.storage.name`. :::
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.storage.name = 'your-storage-key'; art.storage.set('test', { foo: 'bar' }); ``` ## `icons` Manages all `svg` icons for the player.
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); console.info(art.icons.loading); ``` :::warning This is the definition of all icons: [artplayer/types/icons.d.ts](https://github.com/zhw2590582/ArtPlayer/blob/master/packages/artplayer/types/icons.d.ts) ::: ## `i18n` Manages the player's `i18n`. - The `get` method is used to retrieve an `i18n` value. - The `update` method is used to update the `i18n` object.
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); console.info(art.i18n.get('Play')); art.i18n.update({ 'zh-cn': { Play: 'Your Play' } }); ``` :::warning Using `art.i18n.update` can only update the `i18n` after instantiation. If you want to update `i18n` before instantiation, please use the `i18n` option in the basic settings. ::: ## `notice` Manages the player's notifications. It only has a `show` property for displaying notifications.
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.notice.show = 'Video Ready To Play'; }) ``` :::warning If you want to hide the `notice` immediately: `art.notice.show = '';` ::: ## `layers` Manages the player's layers. - The `add` method is used to dynamically add a layer. - The `remove` method is used to dynamically remove a layer. - The `update` method is used to dynamically update a layer. - The `show` property is used to set whether all layers are displayed. - The `toggle` method is used to toggle the display of all layers.
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.layers.add({ html: 'Some Text', }); setTimeout(() => { art.layers.show = false; }, 1000); }); ``` :::warning For `Component Configuration`, please refer to: [/component/layers.html](/component/layers.html) ::: ## `controls` Manages the player's controls. - The `add` method is used to dynamically add a control. - The `remove` method is used to dynamically remove a control. - The `update` method is used to dynamically update controls - The `show` property is used to set whether to display all controls - The `toggle` method is used to toggle the display of all controls
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.controls.add({ html: 'Some Text', position: 'left', }); setTimeout(() => { art.controls.show = false; }, 1000); }); ``` :::warning For `Component Configuration`, please refer to: [/component/controls.html](/component/controls.html) ::: ## `contextmenu` Manages the player's context menu - The `add` method is used to dynamically add menu items - The `remove` method is used to dynamically remove menu items - The `update` method is used to dynamically update menu items - The `show` property is used to set whether to display all menu items - The `toggle` method is used to toggle the display of all menu items
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.contextmenu.add({ html: 'Some Text', }); art.contextmenu.show = true; setTimeout(() => { art.contextmenu.show = false; }, 1000); }); ``` :::warning For `Component Configuration`, please refer to: [/component/contextmenu.html](/component/contextmenu.html) ::: ## `subtitle` Manages the player's subtitle functionality - The `url` property sets and returns the current subtitle URL - The `style` method sets the style of the current subtitle - The `switch` method sets the current subtitle URL and options - `textTrack` gets the current text track - `activeCues` gets the list of currently active cues - `cues` gets the overall list of cues
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.subtitle.url = '/assets/sample/subtitle.srt' art.subtitle.style({ color: 'red', }); }); ``` ## `info` Manages the player's information panel, commonly used to view the current status of the player and video, such as version number, resolution, duration, etc. - Control the panel's visibility via `art.info.show` - The triggered event is named `info` (see the event documentation for details)
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.info.show = true; setTimeout(() => { art.info.show = false; }, 3000); }); ``` ## `loading` Manages the player's loading layer - The `show` property is used to set whether to display the loading layer - The `toggle` property is used to toggle the display of the loading layer
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.loading.show = true; setTimeout(() => { art.loading.show = false; }, 1000); }); ``` ## `hotkey` Manages the player's hotkey functionality - The `add` method is used to add hotkeys - The `remove` method is used to remove hotkeys
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); function hotkeyEvent(event) { console.info('click', event); } art.on('ready', () => { art.hotkey.add(32, hotkeyEvent); setTimeout(() => { art.hotkey.remove(32, hotkeyEvent); }, 5000); }); ``` :::warning Note These hotkeys only take effect after the player gains focus (e.g., after clicking on the player) ::: ## `mask` Manages the player's mask layer - The `show` property is used to set whether to display the mask layer - The `toggle` property is used to toggle the display of the mask layer
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.mask.show = false; setTimeout(() => { art.mask.show = true; }, 1000); }); ``` ## `setting` Manages the player's settings panel - The `add` method is used to dynamically add settings items - The `remove` method is used to dynamically remove settings items - The `update` method is used to dynamically update settings items - The `show` property is used to set whether to display all settings items - The `toggle` method is used to toggle the display of all settings items
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, flip: true, playbackRate: true, aspectRatio: true, subtitleOffset: true, }); art.on('ready', () => { art.setting.show = true; setTimeout(() => { art.setting.show = false; }, 1000); }); ``` :::warning For `Settings Panel`, please refer to [/component/setting.html](/component/setting.html) ::: ## `plugins` Manages the player's plugin functionality, with only one method `add` for dynamically adding plugins
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); function myPlugin(art) { console.info(art); return { name: 'myPlugin', something: 'something', doSomething: function () { console.info('doSomething'); }, }; } art.on('ready', () => { art.plugins.add(myPlugin); }); ``` ===== packages/artplayer-vitepress/docs/en/advanced/class.md ===== # Static Properties Here, `static properties` refer to the `first-level properties` attached to the `constructor`, which are rarely used. ## `instances` Returns an array of all player instances. This property can be useful when you need to manage multiple players simultaneously.
▶ Run Code
```js console.info([...Artplayer.instances]); var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); console.info([...Artplayer.instances]); ``` ## `version` Returns the version information of the player.
▶ Run Code
```js console.info(Artplayer.version); ``` ## `env` Returns the environment variables of the player.
▶ Run Code
```js console.info(Artplayer.env); ``` ## `build` Returns the build timestamp of the player.
▶ Run Code
```js console.info(Artplayer.build); ``` ## `config` Returns the default configuration for videos.
▶ Run Code
```js console.info(Artplayer.config); ``` ## `utils` Returns the collection of utility functions for the player.
▶ Run Code
```js console.info(Artplayer.utils); ``` :::warning For all utility functions, please refer to the following address: [artplayer/types/utils.d.ts](https://github.com/zhw2590582/ArtPlayer/blob/master/packages/artplayer/types/utils.d.ts) ::: ## `scheme` Returns the validation schema for player options.
▶ Run Code
```js console.info(Artplayer.scheme); ``` ## `Emitter` Returns the constructor of the event emitter.
▶ Run Code
```js console.info(Artplayer.Emitter); ``` ## `validator` Returns the validation function for options.
▶ Run Code
```js console.info(Artplayer.validator); ``` ## `kindOf` Returns the type detection utility function.
▶ Run Code
```js console.info(Artplayer.kindOf); ``` ## `html` Returns the `html` string required by the player.
▶ Run Code
```js console.info(Artplayer.html); ``` ## `option` Returns the default options of the player.
▶ Run Code
```js console.info(Artplayer.option); ``` ===== packages/artplayer-vitepress/docs/en/advanced/event.md ===== # Instance Events Player events are divided into two types: `native events` of the video (prefixed with `video:`), and `custom events`. Listening to events:
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('video:canplay', () => { console.info('video:canplay'); }); ``` Listening to an event only once:
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.once('video:canplay', () => { console.info('video:canplay'); }); ``` Manually triggering an event:
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.emit('focus'); ``` Removing an event:
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); const onReady = () => { console.info('ready'); art.off('ready', onReady); } art.on('ready', onReady); ``` :::warning For a complete list of events, please refer to: [artplayer/types/events.d.ts](https://github.com/zhw2590582/ArtPlayer/blob/master/packages/artplayer/types/events.d.ts) ::: ## `ready` Triggered when the player is ready for the first time.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { console.info('ready'); }); ``` ## `restart` Triggered when the player switches URLs and becomes ready to play.
▶ Run Code
```js{10} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.url = '/assets/sample/video.mp4' }); art.on('restart', (url) => { console.info('restart', url); }); ``` ## `pause` Triggered when the player is paused.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('pause', () => { console.info('pause'); }); ``` ## `play` Triggered when the player starts playing.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('play', () => { console.info('play'); }); ``` ## `hotkey` Triggered when a player hotkey is pressed.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('hotkey', (event) => { console.info('hotkey', event); }); ``` ## `destroy` Triggered when the player is destroyed.
▶ Run Code
```js{10} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.destroy(); }); art.on('destroy', () => { console.info('destroy'); }); ``` ## `focus` Triggered when the player gains focus.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('focus', (event) => { console.info('focus', event); }); ``` ## `blur` Triggered when the player loses focus.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('blur', (event) => { console.info('blur', event); }); ``` ## `dblclick` Triggered when the player is double-clicked.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('dblclick', (event) => { console.info('dblclick', event); }); ``` ## `click` Triggered when the player is clicked.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('click', (event) => { console.info('click', event); }); ``` ## `error` Triggered when an error occurs while the player is loading a video.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/404.mp4', }); art.on('error', (error, reconnectTime) => { console.info(error, reconnectTime); }); ``` ## `hover` Triggered when the mouse enters or leaves the player.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('hover', (state, event) => { console.info('hover', state, event); }); ``` ## `mousemove` Triggered when the mouse moves over the player.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('mousemove', (event) => { console.info('mousemove', event); }); ``` ## `resize` Triggered when the player's dimensions change.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('resize', () => { console.info('resize'); }); ``` ## `view` Triggered when the player enters the viewport.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('view', (state) => { console.info('view', state); }); ``` ## `lock` Triggered when the lock state changes on mobile devices.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', lock: true, }); art.on('lock', (state) => { console.info('lock', state); }); ``` ## `aspectRatio` Triggered when the player's aspect ratio changes.
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', aspectRatio: true, setting: true, }); art.on('aspectRatio', (aspectRatio) => { console.info('aspectRatio', aspectRatio); }); ``` ## `autoHeight` Triggered when the player's height is automatically set.
▶ Run Code
```js{10} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.autoHeight(); }); art.on('autoHeight', (height) => { console.info('autoHeight', height); }); ``` ## `autoSize` Triggered when the player's size is automatically set.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', autoSize: true, }); art.on('autoSize', () => { console.info('autoSize'); }); ``` ## `flip` Triggered when the player is flipped.
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', flip: true, setting: true, }); art.on('flip', (flip) => { console.info('flip', flip); }); ``` ## `fullscreen` Triggered when the player enters or exits windowed fullscreen mode.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', fullscreen: true, }); art.on('fullscreen', (state) => { console.info('fullscreen', state); }); ``` ## `fullscreenError` Triggered when a windowed fullscreen error occurs.
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.fullscreen = true; }); art.on('fullscreenError', (event) => { console.info('fullscreenError', event); }); ``` ## `fullscreenWeb` Triggered when the player enters or exits web fullscreen mode.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', fullscreenWeb: true, }); art.on('fullscreenWeb', (state) => { console.info('fullscreenWeb', state); }); ``` ## `mini` Triggered when the player enters or exits mini mode.
▶ Run Code
```js{10} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.mini = true; }); art.on('mini', (state) => { console.info('mini', state); }); ``` ## `pip` Triggered when the player enters or exits Picture-in-Picture mode.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', pip: true, }); art.on('pip', (state) => { console.info('pip', state); }); ``` ## `screenshot` Triggered when the player takes a screenshot.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', screenshot: true, }); art.on('screenshot', (dataUri) => { console.info('screenshot', dataUri); }); ``` ## `seek` Triggered when the player performs a time seek.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('seek', (currentTime) => { console.info('seek', currentTime); }); ``` ## `subtitleOffset` Triggered when the subtitle offset changes in the player.
▶ Run Code
```js{11} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', subtitleOffset: true, subtitle: { url: '/assets/sample/subtitle.srt', }, setting: true, }); art.on('subtitleOffset', (offset) => { console.info('subtitleOffset', offset); }); ``` ## `subtitleBeforeUpdate` Triggered before subtitles are updated.
▶ Run Code
```js{9} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', subtitle: { url: '/assets/sample/subtitle.srt', }, }); art.on('subtitleBeforeUpdate', (cues) => { console.info('subtitleBeforeUpdate', cues); }); ``` ## `subtitleAfterUpdate` Triggered after subtitles are updated.
▶ Run Code
```js{9} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', subtitle: { url: '/assets/sample/subtitle.srt', }, }); art.on('subtitleAfterUpdate', (cues) => { console.info('subtitleAfterUpdate', cues); }); ``` ## `subtitleLoad` Triggered when subtitles are loaded.
▶ Run Code
```js{9} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', subtitle: { url: '/assets/sample/subtitle.srt', }, }); art.on('subtitleLoad', (option, cues) => { console.info('subtitleLoad', cues, option); }); ``` ## `info` Triggered when the info panel is shown or hidden.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('info', (state) => { console.log(state); }); ``` ## `layer` Triggered when a custom layer is shown or hidden.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('layer', (state) => { console.log(state); }); ``` ## `loading` Triggered when the loader is shown or hidden.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('loading', (state) => { console.log(state); }); ``` ## `mask` Triggered when the mask layer is shown or hidden.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('mask', (state) => { console.log(state); }); ``` ## `subtitle` Triggered when the subtitle layer is shown or hidden.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('subtitle', (state) => { console.log(state); }); ``` ## `contextmenu` Triggered when the context menu is shown or hidden.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('contextmenu', (state) => { console.log(state); }); ``` ## `control` Triggered when the control bar is shown or hidden.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('control', (state) => { console.log(state); }); ``` ## `setting` Triggered when the settings panel is shown or hidden.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, }); art.on('setting', (state) => { console.log(state); }); ``` ## `muted` Triggered when the muted state changes.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('muted', (state) => { console.log(state); }); ``` ## `keydown` Listens for the `keydown` event from the `document`.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('keydown', (event) => { console.log(event.code); }); ``` ## `video:canplay` The browser can start playing the media, but estimates there is not enough data to play through to the end without stopping for further buffering. ## `video:canplaythrough` The browser estimates it can play the media through to the end without stopping for buffering. ## `video:complete` The OfflineAudioContext rendering is complete. ## `video:durationchange` Triggered when the value of the `duration` property changes. ## `video:emptied` The media has become empty; for example, this event is sent when the media has already been loaded (or partially loaded), and the `load()` method is called to reload it. ## `video:ended` Playback has stopped because the media has reached its end. ## `video:error` An error occurred while fetching the media data, or the resource type is not a supported media format. ## `video:loadeddata` The first frame of the media has finished loading. ## `video:loadedmetadata` Metadata has been loaded. ## `video:pause` Playback has been paused. ## `video:play` Playback has begun. ## `video:playing` Playback is ready to start after having been paused or delayed due to lack of data. ## `video:progress` Fired periodically as the browser loads the resource. ## `video:ratechange` The playback rate has changed. ## `video:seeked` A seek operation has completed. ## `video:seeking` A seek operation has begun. ## `video:stalled` The user agent is trying to fetch media data, but data is unexpectedly not forthcoming. ## `video:suspend` Media data loading has been suspended. ## `video:timeupdate` The time indicated by the `currentTime` property has changed. ## `video:volumechange` The volume has changed. ## `video:waiting` Playback has stopped because of a temporary lack of data. ===== packages/artplayer-vitepress/docs/en/advanced/global.md ===== # Global Properties The `global properties` here refer to the `top-level properties` mounted on the `constructor`. All property names are in uppercase. These are subject to change in the future and are rarely used. ## DEBUG Whether to enable `debug` mode, which can print all built-in video events. Default is off.
▶ Run Code
```js Artplayer.DEBUG = true; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); ``` ## STYLE Returns the player style text.
▶ Run Code
```js console.log(Artplayer.STYLE); ``` ## CONTEXTMENU Whether to enable the context menu. Default is on.
▶ Run Code
```js Artplayer.CONTEXTMENU = false; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); ``` ## NOTICE_TIME The display duration of notification messages, in milliseconds. Default is `2000`.
▶ Run Code
```js Artplayer.NOTICE_TIME = 5000; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); ``` ## SETTING_WIDTH The default width of the settings panel, in pixels. Default is `250`.
▶ Run Code
```js Artplayer.SETTING_WIDTH = 300; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, loop: true, flip: true, playbackRate: true, aspectRatio: true, }); ``` ## SETTING_ITEM_WIDTH The default width of a setting item in the settings panel, in pixels. Default is `200`.
▶ Run Code
```js Artplayer.SETTING_ITEM_WIDTH = 300; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, loop: true, flip: true, playbackRate: true, aspectRatio: true, }); ``` ## SETTING_ITEM_HEIGHT The default height of a setting item in the settings panel, in pixels. Default is `35`.
▶ Run Code
```js Artplayer.SETTING_ITEM_HEIGHT = 40; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, loop: true, flip: true, playbackRate: true, aspectRatio: true, }); ``` ## RESIZE_TIME The throttle time for the `resize` event, in milliseconds. Default is `200`.
▶ Run Code
```js Artplayer.RESIZE_TIME = 500; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('resize', () => { console.log('resize'); }); ``` ## SCROLL_TIME The throttle time for the `scroll` event, in milliseconds. Default is `200`.
▶ Run Code
```js Artplayer.SCROLL_TIME = 500; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('scroll', () => { console.log('scroll'); }); ``` ## SCROLL_GAP The boundary tolerance distance for the `view` event, in pixels. Default is `50`.
▶ Run Code
```js Artplayer.SCROLL_GAP = 100; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('scroll', () => { console.log('scroll'); }); ``` ## AUTO_PLAYBACK_MAX The maximum record count for the auto-playback feature. Default is `10`.
▶ Run Code
```js Artplayer.AUTO_PLAYBACK_MAX = 20; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', autoPlayback: true, }); ``` ## AUTO_PLAYBACK_MIN The minimum record duration for the auto-playback feature, in seconds. Default is `5`.
▶ Run Code
```js Artplayer.AUTO_PLAYBACK_MIN = 10; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', autoPlayback: true, }); ``` ## AUTO_PLAYBACK_TIMEOUT The hide delay duration for the auto-playback feature, in milliseconds. Default is `3000`.
▶ Run Code
```js Artplayer.AUTO_PLAYBACK_TIMEOUT = 5000; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', autoPlayback: true, }); ``` ## RECONNECT_TIME_MAX The maximum number of automatic reconnection attempts when a connection error occurs. Default is `5`.
▶ Run Code
```js Artplayer.RECONNECT_TIME_MAX = 10; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/404.mp4', }); ``` ## RECONNECT_SLEEP_TIME The delay time for automatic reconnection when a connection error occurs, in milliseconds. Default is `1000`.
▶ Run Code
```js Artplayer.RECONNECT_SLEEP_TIME = 3000; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/404.mp4', }); ``` ## CONTROL_HIDE_TIME The auto-hide delay time for the bottom control bar, in milliseconds. Default is `3000`.
▶ Run Code
```js Artplayer.CONTROL_HIDE_TIME = 5000; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); ``` ## DBCLICK_TIME The delay time for the double-click event, in milliseconds. Default is `300`.
▶ Run Code
```js Artplayer.DBCLICK_TIME = 500; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('dblclick', () => { console.log('dblclick'); }); ``` ## DBCLICK_FULLSCREEN On desktop, whether double-click toggles fullscreen. Default is `true`.
▶ Run Code
```js Artplayer.DBCLICK_FULLSCREEN = false; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); ``` ## MOBILE_DBCLICK_PLAY On mobile, whether double-click toggles play/pause. Default is `true`.
▶ Run Code
```js Artplayer.MOBILE_DBCLICK_PLAY = false; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); ``` ## MOBILE_CLICK_PLAY On mobile, whether single-click toggles play/pause. Default is `false`.
▶ Run Code
```js Artplayer.MOBILE_CLICK_PLAY = true; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); ``` ## AUTO_ORIENTATION_TIME On mobile, the delay time for auto-rotation, in milliseconds. Default is `200`.
▶ Run Code
```js Artplayer.AUTO_ORIENTATION_TIME = 500; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', autoOrientation: true, }); ``` ## INFO_LOOP_TIME The refresh interval for the info panel, in milliseconds. Default is `1000`.
▶ Run Code
```js Artplayer.INFO_LOOP_TIME = 2000; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.info.show = true; ``` ## FAST_FORWARD_VALUE On mobile, the speed multiplier for long-press fast-forward. Default is `3`.
▶ Run Code
```js Artplayer.FAST_FORWARD_VALUE = 5; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', fastForward: true, }); ``` ## FAST_FORWARD_TIME On mobile, the delay time for long-press fast-forward, in milliseconds. Default is `1000`.
▶ Run Code
```js Artplayer.FAST_FORWARD_TIME = 2000; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', fastForward: true, }); ``` ## TOUCH_MOVE_RATIO On mobile, the speed multiplier for left/right swipe to seek. Default is `0.5`.
▶ Run Code
```js Artplayer.TOUCH_MOVE_RATIO = 1; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); ``` ## VOLUME_STEP The step size for volume adjustment via keyboard shortcuts. Default is `0.1`.
▶ Run Code
```js Artplayer.VOLUME_STEP = 0.2; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); ``` ## SEEK_STEP The step size for seeking via keyboard shortcuts, in seconds. Default is `5`.
▶ Run Code
```js Artplayer.SEEK_STEP = 10; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); ``` ## PLAYBACK_RATE The built-in list of playback rates. Default is `[0.5, 0.75, 1, 1.25, 1.5, 2]`.
▶ Run Code
```js Artplayer.PLAYBACK_RATE = [0.5, 1, 2, 3, 4, 5]; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, playbackRate: true, }); art.contextmenu.show = true; art.setting.show = true; ``` ## ASPECT_RATIO The built-in list of video aspect ratios. Default is `['default', '4:3', '16:9']`.
▶ Run Code
```js Artplayer.ASPECT_RATIO = ['default', '1:1', '2:1', '4:3', '6:5']; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, aspectRatio: true, }); art.contextmenu.show = true; art.setting.show = true; ``` ## FLIP The built-in list of video flip options. Default is `['normal', 'horizontal', 'vertical']`.
▶ Run Code
```js Artplayer.FLIP = ['normal', 'horizontal']; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, flip: true, }); art.contextmenu.show = true; art.setting.show = true; ``` ## FULLSCREEN_WEB_IN_BODY Whether to mount the player under the `body` element during web fullscreen mode. Default is `true`.
▶ Run Code
```js Artplayer.FULLSCREEN_WEB_IN_BODY = false; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', fullscreenWeb: true, }); ``` ## LOG_VERSION Sets whether to print the player version. Default is `true`.
▶ Run Code
```js Artplayer.LOG_VERSION = false; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); ``` ## USE_RAF Sets whether to use `requestAnimationFrame`. Default is `false`. Currently, it is primarily used for smooth progress bar effects.
▶ Run Code
```js Artplayer.USE_RAF = true; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', miniProgressBar: true, }); ``` ## REMOVE_SRC_WHEN_DESTROY Whether to remove the video's `src` attribute and call `load()` to actively release media resources when destroying the player. Default is `true`. Enabling this can reduce video resource usage in single-page applications or scenarios where players are frequently created/destroyed. If you wish to preserve the state of the video element and only remove the UI, you can set this to `false`.
▶ Run Code
```js Artplayer.REMOVE_SRC_WHEN_DESTROY = false; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); // Only destroy the UI, do not actively clear the src art.destroy(); ``` ===== packages/artplayer-vitepress/docs/en/advanced/plugin.md ===== # Writing Plugins Once you are familiar with the player's `properties`, `methods`, and `events`, writing a plugin becomes a very straightforward task. You can load a plugin function during instantiation.
▶ Run Code
```js{15} function myPlugin(art) { console.info(art); return { name: 'myPlugin', something: 'something', doSomething: function () { console.info('doSomething'); }, }; } var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', plugins: [myPlugin], }); art.on('ready', () => { console.info(art.plugins.myPlugin); }); ``` You can also load a plugin function after instantiation.
▶ Run Code
```js{17} function myPlugin(art) { console.info(art); return { name: 'myPlugin', something: 'something', doSomething: function () { console.info('doSomething'); }, }; } var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.plugins.add(myPlugin); art.on('ready', () => { console.info(art.plugins.myPlugin); }); ``` For example, let's say I want to write a plugin that displays an image ad when the video is paused.
▶ Run Code
```js function adsPlugin(option) { return (art) => { art.layers.add({ name: 'ads', html: ``, style: { display: 'none', position: 'absolute', top: '20px', right: '20px', }, }); function show() { art.layers.ads.style.display = 'block'; } function hide() { art.layers.ads.style.display = 'none'; } art.controls.add({ name: 'hide-ads', position: 'right', html: 'Hide Ads', tooltip: 'Hide Ads', click: hide, style: { marginRight: '20px' } }); art.controls.add({ name: 'show-ads', position: 'right', html: 'Show Ads', tooltip: 'Show Ads', click: show, }); art.on('play', hide); art.on('pause', show); return { name: 'adsPlugin', show, hide }; } } var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', plugins: [ adsPlugin({ url: '/assets/sample/layer.png' }) ], }); ``` ===== packages/artplayer-vitepress/docs/en/advanced/property.md ===== # Instance Properties Here, `Instance Properties` refer to the `first-level properties` mounted on the `instance`, which are commonly used. ## `play` - Type: `Function` Play the video.
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', muted: true, }); art.on('ready', () => { art.play(); }); ``` ## `pause` - Type: `Function` Pause the video.
▶ Run Code
```js{11} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', muted: true, }); art.on('ready', () => { art.play(); setTimeout(() => { art.pause(); }, 3000); }); ``` ## `toggle` - Type: `Function` Toggle video play and pause.
▶ Run Code
```js{11} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', muted: true, }); art.on('ready', () => { art.toggle(); setTimeout(() => { art.toggle(); }, 3000); }); ``` ## `destroy` - Type: `Function` - Parameter: `Boolean` Destroy the player. Accepts a parameter indicating whether to also remove the player's `html` after destruction. Defaults to `true`.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.destroy(); }); ``` ## `reset` - Type: `Function` Reset the player's video element: removes the current `src` and calls `load()` once. Commonly used to manually release media resources or reinitialize the video tag in single-page applications. > Note: The global configuration `Artplayer.REMOVE_SRC_WHEN_DESTROY` will also automatically execute similar logic when `destroy()` is called.
▶ Run Code
```js{9} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { // Only reset the video, do not remove the interface art.reset(); }); ``` ## `seek` - Type: `Setter` - Parameter: `Number` Seek to a specific time in the video, in seconds.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.seek = 5; }); ``` ## `forward` - Type: `Setter` - Parameter: `Number` Fast-forward the video time, in seconds.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.forward = 5; }); ``` ## `backward` - Type: `Setter` - Parameter: `Number` Rewind the video time, in seconds.
▶ Run Code
```js{10} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.seek = 5; setTimeout(() => { art.backward = 2; }, 3000); }); ``` ## `volume` - Type: `Setter/Getter` - Parameter: `Number` Set and get the video volume, range: `[0, 1]`.
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { console.info(art.volume); art.volume = 0.5; console.info(art.volume); }); ``` ## `url` - Type: `Setter/Getter` - Parameter: `String` Set and get the video URL.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.url = '/assets/sample/video.mp4?t=0'; }); ``` ## `switch` - Type: `Setter` - Parameter: `String` Set the video URL. Similar to `art.url` when setting, but performs some optimization operations.
▶ Run Code
```js{9} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.seek = 10; setTimeout(() => { art.switch = '/assets/sample/video.mp4?t=0'; }, 3000); }); ``` ## `switchUrl` - Type: `Function` - Parameter: `String` Set the video URL. Similar to `art.url` when setting, but performs some optimization operations.
▶ Run Code
```js{9} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.seek = 10; setTimeout(() => { art.switchUrl('/assets/sample/video.mp4?t=0'); }, 3000); }); ``` :::warning Note `art.switch` and `art.switchUrl` have the same functionality, but the `art.switchUrl` method returns a `Promise`. It `resolve`s when the new URL is playable and `reject`s when the new URL fails to load. ::: ## `switchQuality` - Type: `Function` - Parameter: `String` Sets the video quality URL. Similar to `art.switchUrl`, but retains the previous playback progress.
▶ Run Code
```js{9} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.seek = 10; setTimeout(() => { art.switchQuality('/assets/sample/video.mp4?t=0'); }, 3000); }); ``` ## `muted` - Type: `Setter/Getter` - Parameter: `Boolean` Sets or gets whether the video is muted.
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { console.info(art.muted); art.muted = true; console.info(art.muted); }); ``` ## `currentTime` - Type: `Setter/Getter` - Parameter: `Number` Sets or gets the current playback time of the video. Setting the time is similar to `seek`, but it does not trigger additional events.
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { console.info(art.currentTime); art.currentTime = 5; console.info(art.currentTime); }); ``` ## `duration` - Type: `Getter` Gets the duration of the video.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { console.info(art.duration); }); ``` :::warning Note Some videos may not have a duration, such as live streams or videos that have not been fully decoded. In such cases, the obtained duration will be `0`. ::: ## `screenshot` - Type: `Function` Downloads a screenshot of the current video frame. An optional parameter specifies the screenshot filename.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.screenshot('your-name'); }); ``` ## `getDataURL` - Type: `Function` Gets the `base64` URL of a screenshot of the current video frame. Returns a `Promise`.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', async () => { const url = await art.getDataURL(); console.info(url) }); ``` ## `getBlobUrl` - Type: `Function` Gets the `blob` URL of a screenshot of the current video frame. Returns a `Promise`.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', async () => { const url = await art.getBlobUrl(); console.info(url); }); ``` ## `fullscreen` - Type: `Setter/Getter` - Parameter: `Boolean` Sets or gets the player's window fullscreen state.
▶ Run Code
```js{9} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', controls: [ { position: 'right', html: 'Fullscreen Switch', click: function () { art.fullscreen = !art.fullscreen; }, }, ], }); ``` :::warning Note Due to browser security mechanisms, a user interaction (e.g., a click on the page) must occur before triggering window fullscreen. ::: ## `fullscreenWeb` - Type: `Setter/Getter` - Parameter: `Boolean` Sets or gets the player's web page fullscreen state.
▶ Run Code
```js{8,11} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', fullscreenWeb: true, }); art.on('ready', () => { art.fullscreenWeb = true; setTimeout(() => { art.fullscreenWeb = false; }, 3000); }); ``` ## `pip` - Type: `Setter/Getter` - Parameter: `Boolean` Sets or gets the player's Picture-in-Picture (PIP) mode.
▶ Run Code
```js{9} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', controls: [ { position: 'right', html: 'PIP', click: function () { art.pip = !art.pip; }, }, ], }); ``` :::warning Note Due to browser security mechanisms, a user interaction (e.g., a click on the page) must occur before triggering Picture-in-Picture. ::: ## `poster` - Type: `Setter/Getter` - Parameter: `String` Sets and gets the video poster. The poster effect is only visible before the video starts playing.
▶ Run Code
```js{9} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', poster: '/assets/sample/poster.jpg', }); art.on('ready', () => { console.info(art.poster); art.poster = '/assets/sample/poster.jpg?t=0'; console.info(art.poster); }); ``` ## `mini` - Type: `Setter/Getter` - Parameter: `Boolean` Sets and gets the player's mini mode.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.mini = true; }); ``` ## `playing` - Type: `Getter` - Parameter: `Boolean` Gets whether the video is currently playing.
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', muted: true, }); art.on('ready', () => { console.info(art.playing); }); ``` ## `state` - Type: `Setter/Getter` - Parameter: `String` Gets or sets the player's current state. Supported values: `standard` (normal), `mini` (mini window), `pip` (picture-in-picture), `fullscreen` (window fullscreen), `fullscreenWeb` (webpage fullscreen).
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { console.info(art.state); // Default is 'standard' art.state = 'mini'; }); ``` ## `autoSize` - Type: `Function` Sets whether the video adapts its size automatically.
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.autoSize(); }); ``` ## `rect` - Type: `Getter` Gets the player's dimensions and coordinate information.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { console.info(JSON.stringify(art.rect)); }); ``` :::warning Note The dimension and coordinate information is obtained via `getBoundingClientRect`. ::: ## `bottom` / `top` / `left` / `right` / `x` / `y` / `width` / `height` - Type: `Getter` These properties provide quick access to `rect`: - `bottom`, `top`, `left`, `right`, `x`, `y`: Correspond to the fields of the same name in `DOMRect`. - `width`, `height`: The player's current visible width and height.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { console.info(art.width, art.height, art.left, art.top); }); ``` ## `flip` - Type: `Setter/Getter` - Parameter: `String` Sets and gets the player's flip state. Supported values: `normal`, `horizontal`, `vertical`.
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { console.info(art.flip); art.flip = 'horizontal'; console.info(art.flip); }); ``` ## `playbackRate` - Type: `Setter/Getter` - Parameter: `Number` Sets and gets the player's playback speed.
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { console.info(art.playbackRate); art.playbackRate = 2; console.info(art.playbackRate); }); ``` ## `aspectRatio` - Type: `Setter/Getter` - Parameter: `String` Sets and gets the player's aspect ratio.
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { console.info(art.aspectRatio); art.aspectRatio = '16:9'; console.info(art.aspectRatio); }); ``` ## `autoHeight` - Type: `Function` When the container only has a defined width, this property can automatically calculate and set the video's height.
▶ Run Code
```js{7,11} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.autoHeight(); }); art.on('resize', () => { art.autoHeight(); }); ``` :::warning Note This property is useful when your container has only a width but the exact height is unknown. It can automatically calculate the video height, but you need to determine the timing for setting this property. ::: ## `attr` - Type: `Function` - Parameter: `String` Dynamically get and set attributes of the video element.
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { console.info(art.attr('playsInline')); art.attr('playsInline', true); console.info(art.attr('playsInline')); }); ``` ## `type` - Type: `Setter/Getter` - Parameter: `String` Dynamically get and set the video type.
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { console.info(art.type); art.type = 'm3u8'; console.info(art.type); }); ``` ## `theme` - Type: `Setter/Getter` - Parameter: `String` Dynamically get and set the player's theme color.
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { console.info(art.theme); art.theme = '#000'; console.info(art.theme); }); ``` ## `airplay` - Type: `Function` Initiate AirPlay.
▶ Run Code
```js{9} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', controls: [ { position: 'right', html: 'AirPlay', click: function () { art.airplay(); }, }, ], }); ``` ## `loaded` - Type: `Getter` The proportion of video buffered, ranging from `[0, 1]`. Often used with the `video:timeupdate` event.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('video:timeupdate', () => { console.info(art.loaded); }); ``` ## `loadedTime` - Type: `Getter` The buffered media duration in seconds. Typically used alongside `loaded` to display detailed buffering progress.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('video:timeupdate', () => { console.info(art.loadedTime); }); ``` ## `played` - Type: `Getter` The proportion of video played, ranging from `[0, 1]`. Often used with the `video:timeupdate` event.
▶ Run Code
```js{7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('video:timeupdate', () => { console.info(art.played); }); ``` ## `proxy` - Type: `Function` A proxy function for `DOM` events, essentially proxying `addEventListener` and `removeEventListener`. When using `proxy` to handle events, the event is automatically cleaned up when the player is destroyed.
▶ Run Code
```js{8-10} var container = document.querySelector('.artplayer-app'); var art = new Artplayer({ container: container, url: '/assets/sample/video.mp4', }); art.proxy(container, 'click', event => { console.info(event); }); ``` :::warning Note If you need certain `DOM` events to exist only for the player's lifecycle, it is strongly recommended to use this function to avoid memory leaks. ::: ## `query` - Type: `Function` A `DOM` query function, similar to `document.querySelector`, but the search is scoped to the current player, preventing errors with duplicate class names.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); console.info(art.query('.art-video')); ``` ## `video` - Type: `Element` Quickly returns the player's `video` element.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); console.info(art.video); ``` ## `cssVar` - Type: `Function` Dynamically get or set `CSS` variables.
▶ Run Code
```js{8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { console.log(art.cssVar('--art-theme')); art.cssVar('--art-theme', 'green'); console.log(art.cssVar('--art-theme')); }); ``` ## `quality` - Type: `Setter` - Parameter: `Array` Dynamically set the quality list.
▶ Run Code
```js{19-29} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', quality: [ { default: true, html: 'SD 480P', url: '/assets/sample/video.mp4', }, { html: 'HD 720P', url: '/assets/sample/video.mp4', }, ], }); art.on('ready', () => { setTimeout(() => { art.quality = [ { default: true, html: '1080P', url: '/assets/sample/video.mp4', }, { html: '4K', url: '/assets/sample/video.mp4', }, ]; }, 3000); }) ``` ## `thumbnails` - Type: `Setter/Getter` - Parameter: `Object` Dynamically set thumbnails.
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.on('ready', () => { art.thumbnails = { url: '/assets/sample/thumbnails.png', number: 60, column: 10, }; }); ``` ## `subtitleOffset` - Type: `Setter/Getter` - Parameter: `Number` Dynamically set subtitle offset.
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', subtitle: { url: '/assets/sample/subtitle.srt', }, }); art.on('ready', () => { art.subtitleOffset = 1; }); ``` ===== packages/artplayer-vitepress/docs/en/component/contextmenu.md ===== # Context Menu ## Configuration | Property | Type | Description | | --------- | ------------------- | ------------------------------------ | | `disable` | `Boolean` | Whether to disable the component | | `name` | `String` | Unique component name for CSS class | | `index` | `Number` | Component index for display priority | | `html` | `String`, `Element` | DOM element of the component | | `style` | `Object` | Component style object | | `click` | `Function` | Component click event | | `mounted` | `Function` | Triggered after component mount | | `tooltip` | `String` | Tooltip text for the component | ## Creation
▶ Run Code
```js{4-13} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', contextmenu: [ { name: 'your-menu', html: 'Your Menu', click: function (...args) { console.info(args); art.contextmenu.show = false; }, }, ], }); art.contextmenu.show = true; // Get the Element of contextmenu by name console.info(art.contextmenu['your-menu']); ``` ## Addition
▶ Run Code
```js{6-13} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.contextmenu.add({ name: 'your-menu', html: 'Your Menu', click: function (...args) { console.info(args); art.contextmenu.show = false; }, }); art.contextmenu.show = true; // Get the Element of contextmenu by name console.info(art.contextmenu['your-menu']); ``` ## Deletion
▶ Run Code
```js{21} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', contextmenu: [ { name: 'your-menu', html: 'Your Menu', click: function (...args) { console.info(args); art.contextmenu.show = false; }, }, ], }); art.contextmenu.show = true; art.on('ready', () => { setTimeout(() => { // Delete the contextmenu by name art.contextmenu.remove('your-menu') }, 3000); }); ``` ## Update
▶ Run Code
```js{21-24} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', contextmenu: [ { name: 'your-menu', html: 'Your Menu', click: function (...args) { console.info(args); art.contextmenu.show = false; }, }, ], }); art.contextmenu.show = true; art.on('ready', () => { setTimeout(() => { // Update the contextmenu by name art.contextmenu.update({ name: 'your-menu', html: 'Your New Menu', }) }, 3000); }); ``` ===== packages/artplayer-vitepress/docs/en/component/controls.md ===== # Controls ## Configuration | Property | Type | Description | | ---------- | ------------------- | ------------------------------------------------ | | `disable` | `Boolean` | Whether to disable the control | | `name` | `String` | Unique name of the control, used for class marking | | `index` | `Number` | Control index, determines display priority | | `html` | `String`, `Element` | DOM element of the control | | `style` | `Object` | Style object for the control | | `click` | `Function` | Click event handler for the control | | `mounted` | `Function` | Triggered after the control is mounted | | `tooltip` | `String` | Tooltip text for the control | | `position` | `String` | `left` or `right` - controls which side the control appears on | | `selector` | `Array` | Array of objects for selection list | | `onSelect` | `Function` | Function triggered when a selection list item is clicked | ## Creation
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', controls: [ { name: 'your-button', index: 10, position: 'left', html: 'Your Button', tooltip: 'Your Button', style: { color: 'red', }, click: function (...args) { console.info('click', args); }, mounted: function (...args) { console.info('mounted', args); }, }, { name: 'subtitle', position: 'right', html: 'Subtitle', selector: [ { default: true, html: 'subtitle 01', }, { html: 'subtitle 02', }, ], onSelect: function (item, $dom) { console.info(item, $dom); return 'Your ' + item.html; }, }, ], }); // Get the Element of control by name console.info(art.controls['your-button']); console.info(art.controls['subtitle']); ``` ## Adding
▶ Run Code
```js{6-21} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.controls.add({ name: 'button1', index: 10, position: 'left', html: 'Your Button', tooltip: 'Your Button', style: { color: 'red', }, click: function (...args) { console.info('click', args); }, mounted: function (...args) { console.info('mounted', args); }, }); // Get the Element of control by name console.info(art.controls['button1']); ``` ## Removal
▶ Run Code
```js{21} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', controls: [ { name: 'button1', index: 10, position: 'right', html: 'Your Button', tooltip: 'Your Button', style: { color: 'red', }, } ] }); art.on('ready', () => { setTimeout(() => { // Delete the control by name art.controls.remove('button1'); }, 3000); }); ``` ## Updating
▶ Run Code
```js{26-40} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', controls: [ { name: 'button1', index: 10, position: 'right', html: 'Subtitle', selector: [ { default: true, html: 'subtitle 01', }, { html: 'subtitle 02', }, ], } ] }); art.on('ready', () => { setTimeout(() => { // Update the control by name art.controls.update({ name: 'button1', index: 10, position: 'right', html: 'New Subtitle', selector: [ { default: true, html: 'new subtitle 01', }, { html: 'new subtitle 02', }, ], }); }, 3000); }); ``` ===== packages/artplayer-vitepress/docs/en/component/layers.md ===== # Layers ## Configuration | Property | Type | Description | | --------- | ------------------- | ------------------------------------ | | `disable` | `Boolean` | Whether to disable the component | | `name` | `String` | Unique component name for CSS class | | `index` | `Number` | Component index for display priority | | `html` | `String`, `Element` | Component DOM element | | `style` | `Object` | Component style object | | `click` | `Function` | Component click event | | `mounted` | `Function` | Triggered after component mount | | `tooltip` | `String` | Component tooltip text | ## Creation
▶ Run Code
```js{5-22} var img = '/assets/sample/layer.png'; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', layers: [ { name: 'potser', html: ``, tooltip: 'Potser Tip', style: { position: 'absolute', top: '50px', right: '50px', }, click: function (...args) { console.info('click', args); }, mounted: function (...args) { console.info('mounted', args); }, }, ], }); // Get the Element of layer by name console.info(art.layers['potser']); ``` ## Addition
▶ Run Code
```js{7-22} var img = '/assets/sample/layer.png'; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); art.layers.add({ name: 'potser', html: ``, tooltip: 'Potser Tip', style: { position: 'absolute', top: '50px', right: '50px', }, click: function (...args) { console.info('click', args); }, mounted: function (...args) { console.info('mounted', args); }, }); // Get the Element of layer by name console.info(art.layers['potser']); ``` ## Removal
▶ Run Code
```js{21} var img = '/assets/sample/layer.png'; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', layers: [ { name: 'potser', html: ``, style: { position: 'absolute', top: '50px', right: '50px', }, }, ], }); art.on('ready', () => { setTimeout(() => { // Delete the layer by name art.layers.remove('potser'); }, 3000); }); ``` ## Update
▶ Run Code
```js{21-29} var img = '/assets/sample/layer.png'; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', layers: [ { name: 'potser', html: ``, style: { position: 'absolute', top: '50px', right: '50px', }, }, ], }); art.on('ready', () => { setTimeout(() => { // Update the layer by name art.layers.update({ name: 'potser', html: ``, style: { position: 'absolute', top: '50px', left: '50px', }, }); }, 3000); }); ``` ===== packages/artplayer-vitepress/docs/en/component/setting.md ===== # Settings Panel ## Built-in First, you need to open the settings panel. It comes with four built-in items: `flip`, `playbackRate`, `aspectRatio`, `subtitleOffset`.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, flip: true, playbackRate: true, aspectRatio: true, subtitleOffset: true, }); ``` ## Create - Button | Property | Type | Description | | ---------- | ------------------- | -------------------- | | `html` | `String`, `Element` | The DOM element | | `icon` | `String`, `Element` | The icon element | | `onClick` | `Function` | The click event | | `width` | `Number` | The list width | | `tooltip` | `String` | The tooltip text |
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, settings: [ { html: 'Button', icon: '', tooltip: 'tooltip', onClick(item, $dom, event) { console.info(item, $dom, event); return 'new tooltip'; }, }, ], }); ``` ## Create - Selection List | Property | Type | Description | | ---------- | ------------------- | -------------------- | | `html` | `String`, `Element` | The DOM element | | `icon` | `String`, `Element` | The icon element | | `selector` | `Array` | The list of elements | | `onSelect` | `Function` | The click event | | `width` | `Number` | The list width | | `tooltip` | `String` | The tooltip text |
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, settings: [ { html: 'Subtitle', width: 250, tooltip: 'Subtitle 01', selector: [ { default: true, html: 'Subtitle 01', url: '/assets/sample/subtitle.srt?id=1', }, { html: 'Subtitle 02', url: '/assets/sample/subtitle.srt?id=2', }, ], onSelect: function (item, $dom, event) { console.info(item, $dom, event); art.subtitle.url = item.url; return item.html; }, }, { html: 'Quality', width: 150, tooltip: '1080P', selector: [ { default: true, html: '1080P', url: '/assets/sample/video.mp4?id=1080', }, { html: '720P', url: '/assets/sample/video.mp4?id=720', }, { html: '360P', url: '/assets/sample/video.mp4?id=360', }, ], onSelect: function (item, $dom, event) { console.info(item, $dom, event); art.switchQuality(item.url, item.html); return item.html; }, }, ], }); ``` ## Create - Nested List
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, settings: [ { html: 'Multi-level', selector: [ { html: 'Setting 01', width: 150, selector: [ { html: 'Setting 01 - 01', }, { html: 'Setting 01 - 02', }, ], onSelect: function (item, $dom, event) { console.info(item, $dom, event); return item.html; }, }, { html: 'Setting 02', width: 150, selector: [ { html: 'Setting 02 - 01', }, { html: 'Setting 02 - 02', }, ], onSelect: function (item, $dom, event) { console.info(item, $dom, event); return item.html; }, }, ], }, ], }); ``` ## Create - Toggle Button | Property | Type | Description | | ---------- | ------------------- | -------------------------- | | `html` | `String`, `Element` | DOM element for the item | | `icon` | `String`, `Element` | Icon for the item | | `switch` | `Boolean` | Default state of the button | | `onSwitch` | `Function` | Button toggle event | | `tooltip` | `String` | Tooltip text |
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, settings: [ { html: 'PIP Mode', tooltip: 'Close', icon: '', switch: false, onSwitch: function (item, $dom, event) { console.info(item, $dom, event); const nextState = !item.switch; art.pip = nextState; item.tooltip = nextState ? 'Open' : 'Close'; return nextState; }, }, ], }); ``` ## Create - Range Slider | Property | Type | Description | | ---------- | ------------------- | -------------------------- | | `html` | `String`, `Element` | DOM element for the item | | `icon` | `String`, `Element` | Icon for the item | | `range` | `Array` | Default state array | | `onRange` | `Function` | Event triggered on completion | | `onChange` | `Function` | Event triggered on change | | `tooltip` | `String` | Tooltip text | ```js const range = [5, 1, 10, 1]; const value = range[0]; const min = range[1]; const max = range[2]; const step = range[3]; ```
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, settings: [ { html: 'Slider', tooltip: '5x', icon: '', range: [5, 1, 10, 1], onChange: function (item, $dom, event) { console.info(item, $dom, event); return item.range[0] + 'x'; }, }, ], }); ``` ## Add
▶ Run Code
```js{9-14} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, }); art.setting.show = true; art.setting.add({ html: 'Slider', tooltip: '5x', icon: '', range: [5, 1, 10, 1], }); ``` ## Remove
▶ Run Code
```js{22} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, flip: true, settings: [ { name: 'slider', html: 'Slider', tooltip: '5x', icon: '', range: [5, 1, 10, 1], }, ], }); art.setting.show = true; art.on('ready', () => { setTimeout(() => { // Delete the setting by name art.setting.remove('slider'); }, 3000); }); ``` ## Update
▶ Run Code
```js{21-27} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, settings: [ { name: 'slider', html: 'Slider', tooltip: '5x', icon: '', range: [5, 1, 10, 1], }, ], }); art.setting.show = true; art.on('ready', () => { setTimeout(() => { // Update the setting by name art.setting.update({ name: 'slider', html: 'PIP Mode', tooltip: 'Close', icon: '', switch: false, }); }, 3000); }); ``` ===== packages/artplayer-vitepress/docs/en/index.md ===== # Installation and Usage ## Installation ::: code-group ```bash [npm] npm install artplayer ``` ```bash [yarn] yarn add artplayer ``` ```bash [pnpm] pnpm add artplayer ``` ```bash [bun] bun add artplayer ``` ```html [script] ``` ::: ## `CDN` ::: code-group ```bash [jsdelivr.net] https://cdn.jsdelivr.net/npm/artplayer/dist/artplayer.js ``` ```bash [unpkg.com] https://unpkg.com/artplayer/dist/artplayer.js ``` ::: ## Usage ::: code-group ```html [index.html] ArtPlayer Demo
``` ::: ::: warning Note The player's dimensions depend on the dimensions of its `container`. Therefore, your `container` must have defined dimensions. ::: ::: tip See more usage examples at the following link [/example](https://github.com/zhw2590582/ArtPlayer/tree/master/example) ::: ## `Vue.js` ::: code-group ```vue [Artplayer.vue] ``` ```vue [app.vue] ``` ::: ::: warning Artplayer is not reactive: Directly modifying the `option` in `Vue.js` will not update the player. ::: ## `React.js` ::: code-group ```jsx [Artplayer.jsx] import Artplayer from 'artplayer' import { useEffect, useRef } from 'react' export default function Player({ option, getInstance, ...rest }) { const $container = useRef() useEffect(() => { const art = new Artplayer({ ...option, container: $container.current, }) if (typeof getInstance === 'function') { getInstance(art) } return () => art.destroy(false) }, []) return
} ``` ```jsx [app.jsx] import Artplayer from './Artplayer.jsx' function App() { return (
console.log(art)} />
) } export default App ``` ::: ::: warning Artplayer is not reactive: Directly modifying the `option` in `React.js` will not update the player. ::: ## TypeScript The `artplayer.d.ts` file is automatically imported when you import `Artplayer`. ### Vue.js ```vue{3} ``` ### React.js ```jsx{2} import Artplayer from 'artplayer'; const art = useRef(null); art.current = new Artplayer(); ``` ### Option You can also use the type for the options. ```ts{3} import Artplayer, { type Option } from 'artplayer'; const option: Option = { container: '.artplayer-app', url: './assets/sample/video.mp4', }; option.volume = 0.5; const art = new Artplayer(option); ``` ::: tip Full TypeScript Definitions [packages/artplayer/types](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer/types) ::: ## JavaScript Sometimes your `js` files may lose `TypeScript` type hints. In such cases, you can manually import the types. Variable: ```js{1-3} /** * @type {import("artplayer")} */ let art = null; ``` Parameter: ```js{1-3} /** * @param {import("artplayer")} art */ function getInstance(art) { // } ``` Property: ```js{4-6} export default { data() { return { /** * @type {import("artplayer")} */ art: null, } } } ``` Option: ```js{1-3} /** * @type {import("artplayer/types/option").Option} */ const option = { container: '.artplayer-app', url: './assets/sample/video.mp4', }; option.volume = 0.5; const art8 = new Artplayer(option); ``` ## Legacy Browsers The production build `artplayer.js` only supports the latest major version of `Chrome`: `last 1 Chrome version`. For legacy browsers, you can use the `artplayer.legacy.js` file, which is compatible down to: `IE 11`. ```js import Artplayer from 'artplayer/legacy' ``` ::: code-group ```bash [jsdelivr.net] https://cdn.jsdelivr.net/npm/artplayer/dist/artplayer.legacy.js ``` ```bash [unpkg.com] https://unpkg.com/artplayer/dist/artplayer.legacy.js ``` ::: ::: tip If you need to support even older browsers, modify the following configuration and build it yourself: Build configuration: [scripts/build.js](https://github.com/zhw2590582/ArtPlayer/blob/master/scripts/build.js#L29) Reference documentation: [browserslist](https://github.com/browserslist/browserslist#full-list) ::: ## ECMAScript Module ::: tip ESM Demo: [https://artplayer.org/esm.html](https://artplayer.org/esm.html) ::: Starting from version `5.2.6`, `artplayer` and all plugins also provide an `ESM` version in `mjs` format, such as: - `artplayer/dist/artplayer.mjs` - `artplayer-plugin-danmuku/dist/artplayer-plugin-danmuku.mjs` ```html ArtPlayer ESM with Import Map
``` ## Custom userAgent Currently, the detection of whether a device is mobile is not always accurate. Sometimes you may want to adjust the player's UI by changing the `userAgent`. Therefore, starting from version `5.2.4`, a global variable `globalThis.CUSTOM_USER_AGENT` has been added. ```html ArtPlayer Demo
``` ::: warning Note You need to modify it before importing the `Artplayer` dependency for it to take effect. ::: ===== packages/artplayer-vitepress/docs/en/plugin/audio-track.md ===== # Audio Track [中文](../../plugin/audio-track.md) Play a separate audio file in sync with a video. The plugin creates an `HTMLAudioElement` and follows the main video's playback, pause, position, volume and playback rate. It requires no additional SDK and does not add an audio-selection menu. This page describes the current refactor branch. Its lifecycle fixes and precise `/runtime` types are not yet published; an unpinned npm or CDN installation does not select this branch. ## Installation ```sh yarn add artplayer artplayer-plugin-audio-track ``` ```js import Artplayer from 'artplayer'; import artplayerPluginAudioTrack from 'artplayer-plugin-audio-track'; ``` For script tags, load ArtPlayer before the plugin's `dist/artplayer-plugin-audio-track.js`. The global is `artplayerPluginAudioTrack`. Pin dependency versions and supply an audio URL the browser can access and decode. ## Complete example This is the same code as the [online audio example](https://artplayer.org/?libs=./uncompiled/artplayer-plugin-audio-track/index.js&example=audio.track). The demo site supplies the media files and `.artplayer-app` container; replace both when integrating it into your application.
```js // npm i artplayer-plugin-audio-track // import artplayerPluginAudioTrack from 'artplayer-plugin-audio-track'; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/sprite-fight.mp4', plugins: [ artplayerPluginAudioTrack({ url: '/assets/sample/sprite-fight.aac', offset: 0, sync: 0.3, }), ], }); ``` ## Options and synchronization `artplayerPluginAudioTrack(option)` returns a plugin factory. The options object is required. | Field | Type and default | Behavior | | --- | --- | --- | | `url` | Required `string` | Separate audio URL. An empty string at construction leaves the source unloaded. | | `offset` | `number`, default `0` | Target audio time is video time plus this value, in seconds. A positive offset reads further ahead in the audio file. | | `sync` | `number`, default `0.3` | Adjust audio time only when its absolute difference from the target is strictly greater than this threshold, in seconds. | For example, video time 10 with offset 0.25 targets audio time 10.25. This corrects media-time drift; it is not a sample-accurate audio clock. Use finite, reasonable offsets and a nonnegative threshold. Negative targets or targets beyond the audio duration depend on browser media behavior; the plugin adds no delayed start, looping or silence padding. Playback, completed seeking and playback recovery synchronize the track. Ordinary playing timeupdate events also correct drift. Buffering, source emptying, native pause, starting a seek and reaching the video's end pause the separate audio. It resumes when the main video is playing and ready to recover; canplay alone does not start audio for a paused video. ## Result and updates After installation, access the result at `art.plugins.artplayerPluginAudioTrack`: | Member | Behavior | | --- | --- | | `name` | Always `artplayerPluginAudioTrack`. | | `audio` | The actual `HTMLAudioElement`; source updates preserve its identity. | | `update(option)` | Synchronously updates selected fields and returns `undefined`, not a loading Promise. | ```js const track = art.plugins.artplayerPluginAudioTrack; track.update({ offset: 0.25, sync: 0.1 }); track.update({ url: '/audio/another-language.m4a' }); ``` Changing offset or sync does not immediately force a seek; the next synchronization event uses the new values. Only a different, nonempty URL replaces the source. Reusing the same URL does not reload it, and an empty URL is not a stop or clear command. Replacing a source while the main video is playing attempts playback; observe the exposed audio element for actual loading, decoding and errors. `art.switchUrl()` changes only the main video. Your application must keep video and audio sources paired and select the new audio with `track.update()`. Use native media events when you need to wait for readiness; `await track.update(...)` does not wait for loading. ## Volume, playback failure and destruction The plugin does not remove the video's original sound. Use a video source without its own audio track if the separate track should provide the only sound. Player volume, mute and playback rate also apply to the separate audio. Setting `art.muted = true` mutes both; it cannot selectively mute only the main video. Browser playback policies still apply. While the instance is active, a rejected `audio.play()` is reported through `console.warn`; it does not become a rejection from update. Successful main-video playback does not prove that the separate audio is audible. Applications can observe native playing/error events on the audio element. Destroying ArtPlayer removes plugin subscriptions, pauses audio, removes its src attribute and releases media loading. A retained result still points to the same element, but later update calls no longer reload or play it. Your application remains responsible for listeners it adds to audio. There is no separate plugin destroy method to call. ## TypeScript The root and `/legacy` entries preserve the old `Result.update(Option)` declaration, including its required URL, to retain parameter extraction and function-assignment behavior. Runtime updates already support partial options. Use `/runtime` for accurate partial-update types over the same implementation: ```ts import Artplayer from 'artplayer'; import audioTrack from 'artplayer-plugin-audio-track/runtime'; const installTrack = audioTrack({ url: '/audio/dialogue.m4a' }); const art = new Artplayer({ container: '.artplayer-app', url: '/video/silent.mp4', plugins: [(player) => { const track = installTrack(player); track.update({ offset: 0.25 }); return track; }], }); ``` Named types include `Option`, `UpdateOption`, the old `Result`, `RuntimeResult` and `RuntimeFactory`. The online editor's default global retains legacy inference too. To select precise update typing, explicitly use `artplayerPluginAudioTrack as artplayerPluginAudioTrack.RuntimeFactory`. This does not create a second plugin implementation. Actual desktop tests cover audio/video playback, pause, seeking, updates and destruction. They do not establish support for every mobile device, proxy player, audio format or long-running synchronization combination. Check browser decoding capabilities and the project's validation records for the applicable scope. ===== packages/artplayer-vitepress/docs/en/plugin/danmuku.md ===== # Danmuku [中文说明](../../plugin/danmuku.md) Display timed comments over the video, with an input panel, display settings and an optional heatmap. This guide describes the current refactor branch. The `/runtime` entrypoint and refactor fixes have not yet been published to npm; unversioned CDN links still load the published release. ## Demo [Open the full example](https://artplayer.org/?libs=./uncompiled/artplayer-plugin-danmuku/index.js&example=danmuku). Run Code examples below use the site's local plugin build and sample media. In your application, use your own container and media URLs. ## Installation ::: code-group ```sh [npm] npm install artplayer artplayer-plugin-danmuku ``` ```sh [yarn] yarn add artplayer artplayer-plugin-danmuku ``` ```sh [pnpm] pnpm add artplayer artplayer-plugin-danmuku ``` ```html [script] ``` ::: JavaScript projects can import the default factory from `artplayer-plugin-danmuku`. Script builds expose `artplayerPluginDanmuku`; pass its result to the player's `plugins` array. ## CDN ::: code-group ```text [jsDelivr] https://cdn.jsdelivr.net/npm/artplayer-plugin-danmuku/dist/artplayer-plugin-danmuku.js ``` ```text [unpkg] https://unpkg.com/artplayer-plugin-danmuku/dist/artplayer-plugin-danmuku.js ``` ::: ## Comment structure Only `text` is required. Leading and trailing whitespace is removed; empty comments are ignored. ```js ({ text: 'Hello!', time: 10, // Seconds; omitted time defaults to currentTime + 0.5 mode: 0, // 0: scrolling, 1: top, 2: bottom; defaults to option.mode color: '#FFFFFF', // Defaults to option.color border: false, style: {}, // CSS properties for this comment }); ``` Explicit `time: 0` is preserved. Negative times are clamped to zero. Other than 0, 1 and 2, comment modes are ignored. ## All options Pass an option object to the factory. At runtime, `{}` is valid and all fields have defaults. The historical root declarations still require `danmuku`; existing TypeScript projects can keep providing it. See [TypeScript](#typescript) for accurate declarations. ```js ({ danmuku: [], // Array, XML URL, Promise of an array, or function returning an array/Promise speed: 5, // Display duration in seconds, clamped to 1–10 margin: [10, '25%'], // Top/bottom spacing: pixels or percentages opacity: 1, // Clamped to 0–1 color: '#FFFFFF', // Default comment color mode: 0, // Default comment mode modes: [0, 1, 2], // Visible modes fontSize: 25, // Pixels or a percentage of player height antiOverlap: true, synchronousPlayback: false, // Follow video playbackRate when enabled mount: undefined, // Defaults to the center of the player controls heatmap: false, // Enable at construction: true or a heatmap options object width: 512, // Below this width, the default input panel moves below the player points: [], // Stored option; use the points event to draw custom data filter: () => true, // Synchronous; do not return a Promise beforeEmit: () => true, // Input-panel submissions only; may return a Promise beforeVisible: () => true, // Called before display; may return a Promise visible: true, emitter: true, // Show the input panel's sending UI maxLength: 200, // Input length, clamped to 1–1000 lockTime: 5, // Seconds between input-panel submissions, clamped to 1–60 theme: 'dark', // 'dark' or 'light' for an external mount OPACITY: {}, FONT_SIZE: {}, MARGIN: {}, SPEED: {}, COLOR: [], }); ``` `OPACITY`, `FONT_SIZE`, `MARGIN` and `SPEED` override slider definitions with `min`, `max` and `steps`. Each step can contain `name`, `value`, `hide` and `show`; margin values are pairs such as `[10, '50%']`. `COLOR` replaces the palette with an array of CSS color strings; an empty array uses the built-in palette. ## Array, XML and asynchronous input XML input uses Bilibili's comment format. Fetching a cross-origin XML URL requires that server to allow browser access. An input function runs without the option object as its receiver. It may return an array directly or asynchronously.
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', plugins: [ artplayerPluginDanmuku({ danmuku: [{ text: 'Hello from an array', time: 1 }], // Alternatives: // danmuku: '/assets/sample/danmuku.xml', // danmuku: Promise.resolve([{ text: 'From a Promise', time: 1 }]), // danmuku: async () => [{ text: 'From a function', time: 1 }], }), ], }); ``` ## Lifecycle callbacks Input-panel submissions run `beforeEmit → filter → beforeVisible → artplayerPluginDanmuku:visible`. Loaded comments and direct `emit` calls run `filter → beforeVisible → artplayerPluginDanmuku:visible`. This describes accepted comments; callbacks can reject them, and scheduling still requires playback and an available track. | Callback | Input | Acceptance | | --- | --- | --- | | `beforeEmit` | Input-panel comment | Only strict `true`, or a Promise resolving to `true`, sends it | | `filter` | Comment with time, mode, color and style filled in | A synchronous truthy result adds it to the queue | | `beforeVisible` | Queue item | A truthy result, including an awaited result, permits display | Normal functions receive the current option object as `this` for all three callbacks. Arrow functions retain their lexical `this`. `emit()` does not call `beforeEmit`: perform application validation before calling it when needed. `beforeEmit` failures are logged in the console and leave the input available for another attempt. An asynchronous `beforeVisible` rejection emits `artplayerPluginDanmuku:error` once for that item in the current run; other items continue. Pause/resume, reset or replacing the callback permits a retry if the item is still eligible by time. Pausing, seeking, hiding, resetting or destroying cancels unfinished visibility preparation. ## Methods and state The registered plugin is available synchronously as `art.plugins.artplayerPluginDanmuku`. | Member | Behavior and return value | | --- | --- | | `emit(comment)` | Processes one comment for the queue; returns a Promise | | `load()` | Reads `option.danmuku` and replaces the queue; returns a Promise | | `load(input)` | Appends comments from the input; returns a Promise | | `config(partialOption)` | Synchronously merges configuration | | `hide()` / `show()` | Synchronously hides or shows the comment layer | | `reset()` | Clears displayed comments and returns queue items to waiting; does not delete the queue | | `mount(target)` | Moves the panel to an existing element or selector; returns `undefined` | | `option` | Live current configuration; use `config()` for validated updates | | `isHide` | Read-only live visibility state: `true` when hidden | | `isStop` | Read-only live stopped state; distinct from visibility and not a media-readiness signal | `emit/load` Promises resolve to the internal Danmuku owner. `config/hide/show/reset` return that same owner synchronously. The owner is **different from the registered plugin facade**. Keep using the registered facade for subsequent commands. Awaiting `emit()` means queue processing has finished, not that the comment has appeared. ### Loading and configuration Changing `config({ danmuku: input })` does not load the new input. Follow it with `load()` to replace the queue. Input-read failures leave the existing queue intact; failures while filtering individual rows do not guarantee an atomic rollback of the entire batch. Independent append operations do not cancel one another. A newer replacement cancels an unfinished older replacement. Destroy cancels pending loads. Cancelled Promises resolve to the owner without a late `loaded` or `error` event. Fetch and response-text failures emit `artplayerPluginDanmuku:error` and reject the corresponding public `load()` Promise. Handle rejection with `await`/`try...catch` or `.catch(...)`. Initial automatic loading observes rejection and logs a warning. Invalid configuration leaves the current option intact. Use `mount(target)` to move the panel; changing `option.mount` through `config()` does not perform a mount. Enable heatmap when constructing the plugin; `config({ heatmap: true })` does not create it later.
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', plugins: [artplayerPluginDanmuku({ danmuku: [], emitter: false })], }); async function updateComments() { var plugin = art.plugins.artplayerPluginDanmuku; plugin.config({ danmuku: [{ text: 'Replacement', time: 1 }] }); await plugin.load(); await plugin.load([{ text: 'Appended', time: 2 }]); await plugin.emit({ text: 'Scheduled from the current time' }); plugin.hide(); console.info('Hidden:', plugin.isHide); plugin.show(); plugin.reset(); } updateComments().catch(console.error); ``` ## External mount Create a separate mount element before constructing the plugin. The panel moves into the controls during player fullscreen or web fullscreen and returns to its configured mount on exit. Use `theme: 'light'` on a light background. The live `mount(target)` method requires a valid target; omitting its argument does not select the default. Destroy releases the plugin panel; the application owns any container it created.
▶ Run Code
```js var $danmu = document.createElement('div'); document.querySelector('.artplayer-app').after($danmu); var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', fullscreenWeb: true, plugins: [artplayerPluginDanmuku({ danmuku: [{ text: 'External input panel', time: 1 }], mount: $danmu, theme: 'dark', })], }); art.on('destroy', () => $danmu.remove()); // Move it later with art.plugins.artplayerPluginDanmuku.mount(otherElement). ``` ## Heatmap Set `heatmap: true` at construction to sample the queue automatically. A live stream does not draw a heatmap. Dense automatic curves now fit in the bottom quarter of the chart instead of covering the video (issue #958). Explicit finite `yMin` or `yMax` and custom points retain their coordinate mapping. An object can set `xMin`, `xMax`, `yMin`, `yMax`, `scale`, `opacity`, `minHeight`, `sampling`, `smoothing` and `flattening`. Defaults are `xMin: 0`, `xMax: chartWidth`, `yMin: 0`, `yMax: 128`, `scale: 0.25`, `opacity: 0.2`, `minHeight: floor(chartHeight * 0.05)`, `sampling: max(1, floor(chartWidth / 100))`, `smoothing: 0.2`, `flattening: 0.2`. Send `art.emit('artplayerPluginDanmuku:points', points)` to draw custom `[x, value]` pairs. The default x-axis uses chart pixels, not seconds. Set `xMin/xMax` explicitly if supplying another coordinate range. Rendering mutates the inner point arrays for historical compatibility: copy each pair if reusing the original data. The stored `points` option does not draw custom data. A resize or successful load redraws the automatic curve, so resend custom data after those events when needed.
▶ Run Code
```js var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', plugins: [artplayerPluginDanmuku({ danmuku: [{ text: 'Heatmap example', time: 1 }], heatmap: true, })], }); var points = [[0, 5], [0.25, 12], [0.5, 30], [0.75, 10], [1, 5]]; function drawPoints() { var width = art.controls.heatmap.offsetWidth; art.emit('artplayerPluginDanmuku:points', points.map(([ratio, value]) => [ratio * width, value])); } art.on('ready', drawPoints); art.on('resize', drawPoints); art.on('artplayerPluginDanmuku:loaded', drawPoints); ``` ## Events Subscribe with `art.on(name, callback)` and remove subscriptions with `art.off(name, callback)`. | Event | Payload / meaning | | --- | --- | | `artplayerPluginDanmuku:visible` | Queue item; its `$ref` is the displayed element | | `artplayerPluginDanmuku:loaded` | Current full queue after a successful load, including appends | | `artplayerPluginDanmuku:error` | Original error from loading or scheduling; handle public Promise rejections separately | | `artplayerPluginDanmuku:config` | Current configuration | | `artplayerPluginDanmuku:start` | No payload; scheduling starts | | `artplayerPluginDanmuku:stop` | No payload; scheduling stops | | `artplayerPluginDanmuku:hide` | No payload; layer hidden | | `artplayerPluginDanmuku:show` | No payload; layer shown | | `artplayerPluginDanmuku:reset` | No payload; displayed items reset | | `artplayerPluginDanmuku:destroy` | No payload; plugin destroyed | | `artplayerPluginDanmuku:points` | Application-sent custom points for the heatmap | Events are not replayed to later listeners. In particular, an initially empty array can finish loading during construction. Subscribe before invoking a later `load()` if you need to observe its completion event. Use `$ref.textContent` when adding text in a `visible` handler. ## TypeScript The root and `/legacy` entrypoints keep the npm 5.3.0 declaration shapes for compatibility, including historical inaccuracies about return values. The current branch adds `/runtime` for accurate types while loading the same runtime factory: ```ts import Artplayer from 'artplayer'; import danmuku from 'artplayer-plugin-danmuku/runtime'; import type { RuntimeOption, Point, EventMap } from 'artplayer-plugin-danmuku/runtime'; const option: RuntimeOption = { danmuku: [], heatmap: true }; const points: Point[] = [[0, 5], [100, 10]]; const onError = (...[error]: EventMap['artplayerPluginDanmuku:error']) => console.error(error); const art = new Artplayer({ container: '#player', url: '/video.mp4', plugins: [danmuku(option)] }); art.on('artplayerPluginDanmuku:error', onError); ``` The explicit `EventMap` describes payloads; it does not augment the core's historical event declarations automatically. The factory also exposes the existing `icons` object for customization. Package `README.md` and `ARCHITECTURE.md` describe module ownership, maintenance commands and remaining device/combination validation. ===== packages/artplayer-vitepress/docs/en/plugin/dash-control.md ===== # DASH Control [中文说明](../../plugin/dash-control.md) Add video quality and audio-track menus to a dash.js player. You create and attach the SDK instance at `art.dash`; the plugin controls that instance and releases its own menus and listeners. This guide describes the current refactor branch. Its SDK adaptation, automatic refresh and lifecycle fixes have not yet been published. An unversioned npm/CDN install still uses the published release. ## Installation ```sh yarn add artplayer dashjs artplayer-plugin-dash-control ``` ```js import Artplayer from 'artplayer'; import dashjs from 'dashjs'; import artplayerPluginDashControl from 'artplayer-plugin-dash-control'; ``` For script tags, load ArtPlayer, dash.js and `dist/artplayer-plugin-dash-control.js` before setup. The plugin global is `artplayerPluginDashControl`. Pin your dependency versions and use a browser-accessible MPD and segments. ## Complete example The example matches the [online DASH example](https://artplayer.org/?libs=https://cdnjs.cloudflare.com/ajax/libs/dashjs/5.2.1/modern/umd/dash.all.min.js%0A./uncompiled/artplayer-plugin-dash-control/index.js&example=dash.control). Replace the site's container and media URL in your application.
```js // npm i dashjs // npm i artplayer-plugin-dash-control // import dashjs from 'dashjs'; // import artplayerPluginDashControl from 'artplayer-plugin-dash-control'; const useDash = dashjs.supportsMediaSource() let dash function destroyDash() { const previous = dash dash = undefined if (previous) previous.destroy() } const art = new Artplayer({ container: '.artplayer-app', url: 'https://media.axprod.net/TestVectors/v7-Clear/Manifest_1080p.mpd', setting: true, plugins: useDash ? [ artplayerPluginDashControl({ quality: { // Show quality choices in the controls control: true, // Show quality choices in settings setting: true, // Get the quality name from level getName: level => `${level.height}P`, // I18n title: 'Quality', auto: 'Auto', }, audio: { // Show audios in control control: true, // Show audios in setting setting: true, // Get the audio name from track getName: track => track.lang?.toUpperCase() || String(track.id ?? 'Audio'), // I18n title: 'Audio', auto: 'Auto', }, }), ] : [], customType: { mpd: function playMpd(video, url, art) { destroyDash() if (useDash) { dash = dashjs.MediaPlayer().create() art.dash = dash dash.initialize(video, url, art.option.autoplay) } else { art.notice.show = 'Unsupported playback format: mpd' } }, }, }) art.on('destroy', destroyDash) ``` The example chooses its SDK capability path once per player. If dash.js cannot use MediaSource, it displays the existing unsupported-format notice without creating an SDK or installing its controls. This example does not provide a native DASH fallback. ## Configuration `artplayerPluginDashControl(option?)` synchronously returns a plugin factory. Both `quality` and `audio` accept: | Field | Meaning and default | | --- | --- | | `control` | Display a bottom control; omitted means hidden. | | `setting` | Display a settings entry; omitted means hidden. Also enable the player's `setting: true`. | | `title` | Menu title, default `Quality` or `Audio`. | | `auto` | Fallback text, default `Auto`; quality also uses it for its automatic selection row. It does not create a synthetic audio track. | | `getName(item)` | Return a string from the original SDK level or track. It receives one argument, with no player receiver or index. | The default quality label is `level.height + 'p'`. Default audio labels use `track.lang` or `track.id`; metadata may be missing or null. A custom formatter should return a string fallback, as the complete example does. Empty title/Auto text uses the default. Equal text labels collapse into one displayed choice. Include bitrate or other metadata when several variants have the same height and should remain separate choices. A selected duplicate keeps the actual selected SDK key or track object. Empty track lists remove their menus. ## Quality and audio selection Manual quality selection disables video Auto switching, then selects the SDK quality. Auto enables video Auto switching without overwriting unrelated ABR settings. A synchronous menu selection does not mean buffering or decoding has completed. The plugin detects the SDK's available method family: | SDK interface | Quality list and selection | | --- | --- | | dash.js 4 style | `getBitrateInfoListFor('video')`, `getQualityFor('video')`, `setQualityFor('video', qualityIndex)` | | dash.js 5 style | `getRepresentationsByType('video')`, `getCurrentRepresentationForType('video')`, `setRepresentationForTypeById('video', id)` | For the representation interface, selection uses the representation ID, including numeric zero. Do not substitute the index of a filtered array. You do not need to configure a version switch in the plugin. Audio selection calls `setCurrentTrack()` with the original SDK track object. It matches the current track by object identity or an unambiguous combination of available id/index/lang fields. There is no extra Auto audio row. ## Refresh after external changes Player `ready`/`restart` and SDK quality, track and stream events refresh menus. SDK event refreshes are coalesced after the current synchronous selection. Unchanged playback-time events do not redraw menus; they can detect an external Auto-setting change. When changing SDK configuration while paused without a subsequent SDK event, refresh explicitly: ```js art.plugins.artplayerPluginDashControl.update(); ``` `update()` is synchronous and returns `undefined`. It requires `art.dash` to be attached to the player's video and can throw if that contract is not met. Assigning a different `art.dash` alone does not subscribe to it immediately; call `update()` or use the normal ready/restart flow after attachment. Automatic refresh preserves an open, plugin-owned quality or audio settings panel. Explicit `update()` keeps its existing rebuild behavior. Reserve `dash-quality` and `dash-audio` for the plugin's menu names. If an asynchronous SDK getter or formatter fails, the plugin warns, stops that observation and clears its menus. Fix the formatter/SDK state and call `update()` to recover. Explicit update and synchronous selection errors keep their normal throwing behavior. ## SDK ownership and source switching Use the existing player `switchUrl()` or `switchQuality()` and handle its Promise. The complete example destroys the replaced SDK, assigns the new instance before initialization, and keeps one final player cleanup listener. It does not accumulate a new destroy listener on every load or destroy replaced engines again at the end. The plugin does not own your SDK: it never calls `dash.destroy()`, changes the manifest URL or removes listeners belonging to other consumers. Retained callbacks from old menus become inactive after replacement or player destruction. Your application remains responsible for DRM, SDK errors, autoplay decisions and any asynchronous SDK shutdown policy its integration requires. ## TypeScript Default callback types include quality height/width/ID/bitrate and nullable audio id/index/lang. Use the generic factory for more specific metadata. This example declares only the fields it uses and does not require importing SDK declarations: ```ts import dashControl from 'artplayer-plugin-dash-control'; interface Level { height: number; bitrateInKbit?: number } interface Track { id?: string | number | null; lang?: string | null } const plugin = dashControl({ quality: { control: true, getName: level => level.height + 'p', }, audio: { setting: true, getName: track => track.lang?.toUpperCase() || String(track.id ?? 'Audio'), }, }); ``` `Option`, `Config`, `QualityLevel`, `AudioTrack` and `Result` are exported from the root. Root and legacy paths remain available. If using actual SDK declarations, dash.js 4.5.2 exposes `BitrateInfo` for quality; 5.2.1 uses `Representation`. Its declarations have different compiler/module-resolution requirements, so test your actual SDK and TypeScript combination. Describe the externally attached `art.dash` in your application's integration types. ## Validation scope The refactor tests fixed dash.js 4.5.2 and 5.2.1 with local adaptive media and old/new core combinations. Those are tested points, not a new blanket support range. The plugin includes a targeted 4.5.2 paused-seek recovery for stale empty-buffer metrics while preserving the caller's SDK settings and media time. Windows Playwright WebKit lacks the MSE path used by these tests; it is not Safari/device playback acceptance. Test your own MPDs, DRM and target devices before adopting the unpublished refactor. ===== packages/artplayer-vitepress/docs/en/plugin/hls-control.md ===== # HLS Control [中文说明](../../plugin/hls-control.md) Add quality and audio-track menus to an Hls.js player. This plugin controls the Hls.js instance you provide at `art.hls`; it does not download, create or destroy the SDK. This guide describes the current refactor branch. The automatic refresh and lifecycle fixes described here have not yet been published. An unversioned npm/CDN install still uses the published release. ## Installation ```sh yarn add artplayer hls.js artplayer-plugin-hls-control ``` ```js import Artplayer from 'artplayer'; import Hls from 'hls.js'; import artplayerPluginHlsControl from 'artplayer-plugin-hls-control'; ``` For script tags, load ArtPlayer, Hls.js and the plugin's `dist/artplayer-plugin-hls-control.js` before running your setup. The plugin global is `artplayerPluginHlsControl`. Pin versions in your application and use media URLs that permit browser access. ## Complete example The example uses the site's player container and the same source as the [online HLS example](https://artplayer.org/?libs=https://cdnjs.cloudflare.com/ajax/libs/hls.js/1.5.17/hls.min.js%0A./uncompiled/artplayer-plugin-hls-control/index.js&example=hls.control). Replace the container and stream URL in your application.
```js // npm i hls.js // npm i artplayer-plugin-hls-control // import Hls from 'hls.js'; // import artplayerPluginHlsControl from 'artplayer-plugin-hls-control'; const useHls = Hls.isSupported() let hls function destroyHls() { const previous = hls hls = undefined if (previous) previous.destroy() } const art = new Artplayer({ container: '.artplayer-app', url: 'https://playertest.longtailvideo.com/adaptive/elephants_dream_v4/index.m3u8', setting: true, plugins: useHls ? [ artplayerPluginHlsControl({ quality: { // Show quality choices in the controls control: true, // Show quality choices in settings setting: true, // Get the quality name from level getName: level => `${level.height}P`, // I18n title: 'Quality', auto: 'Auto', }, audio: { // Show audios in control control: true, // Show audios in setting setting: true, // Get the audio name from track getName: track => track.name || track.lang || 'Audio', // I18n title: 'Audio', auto: 'Auto', }, }), ] : [], customType: { m3u8: function playM3u8(video, url, art) { destroyHls() if (useHls) { hls = new Hls() art.hls = hls hls.loadSource(url) hls.attachMedia(video) } else if (video.canPlayType('application/vnd.apple.mpegurl')) { video.src = url } else { art.notice.show = 'Unsupported playback format: m3u8' } }, }, }) art.on('destroy', destroyHls) ``` Only install the control plugin when Hls.js is supported. If the browser instead plays HLS natively, the example assigns `video.src` without installing a plugin that requires `art.hls`. Native quality/audio selection is not supplied by this plugin. Keep `useHls` fixed for that player instance; recreate the player if the playback integration changes. ## Configuration `artplayerPluginHlsControl(option?)` returns a synchronous plugin factory. Both `quality` and `audio` accept these fields: | Field | Meaning and default | | --- | --- | | `control` | Show the bottom control; omitted means hidden. | | `setting` | Show the settings entry; omitted means hidden. Enable the player's `setting: true` as well. | | `title` | Menu title; quality defaults to `Quality`, audio to `Audio`. | | `auto` | Fallback text, default `Auto`. Quality also uses it for its Auto option. Audio does not gain a synthetic Auto track. | | `getName(item, index?)` | Return a string from the original SDK level or track. The current-label call omits `index`; list calls include it. | Without a quality formatter, labels use `level.name` or `level.height + 'P'`. Audio labels use `track.name`, `track.lang`, then `track.language`. Empty titles/Auto text fall back to their defaults. Give formatters a string fallback when your source lacks metadata. The formatter is a plain callback; it does not receive the player as `this`. Avoid using its optional index as a required field. Equal labels collapse into one displayed choice, so include bitrate or other distinguishing metadata when separate variants have the same height. Empty track lists remove their menus. Choosing a quality writes `hls.currentLevel`; Auto writes `-1`. The selected label reflects automatic mode when `autoLevelEnabled` is true. Choosing audio writes `hls.audioTrack` with the SDK track ID. A menu selection is synchronous and does not mean the new stream has finished buffering or decoding. ## Refresh after external changes The plugin updates on player `ready` and `restart`. When the SDK provides its event API, manifest, level, audio and destruction events also refresh or clear the menus. Current SDK state determines the selected choice. After attaching a replacement instance to the same video and assigning `art.hls`, use the existing synchronous method when an immediate refresh is needed: ```js art.plugins.artplayerPluginHlsControl.update(); ``` `update()` returns `undefined`; it is not a Promise. Calling it without an attached Hls.js instance can throw. SDK-like integrations without supported event hooks must call it when their state changes. Reserve menu names `hls-quality` and `hls-audio` for this plugin. ## SDK ownership and source switching Use the player's existing `switchUrl()` or `switchQuality()` for source changes and handle the returned Promise. The example's custom loader destroys the previous SDK before creating the next one, updates `art.hls`, and keeps one final cleanup listener per player. Each instance is destroyed once. Do not add a new player `destroy` listener on every load while also destroying replaced instances yourself. The control plugin releases its own SDK subscriptions and makes retained menu callbacks inert after replacement or player destruction. It does not destroy the SDK, remove other consumers' SDK listeners, or implement Hls.js error recovery. Your application remains responsible for SDK fatal errors and playback policy. ## TypeScript The default callback types include level height/name and audio id/name/language fields. Applications can specify their actual SDK metadata types through the existing generic factory. The example below uses only fields it needs and works without importing Hls.js declarations: ```ts import hlsControl from 'artplayer-plugin-hls-control'; interface Level { height: number; bitrate: number } interface Track { id: number; name: string; lang?: string } const plugin = hlsControl({ quality: { control: true, getName: level => level.height + 'p / ' + level.bitrate, }, audio: { setting: true, getName: track => track.name || track.lang || 'Audio', }, }); ``` Public `Option`, `Config`, `QualityLevel`, `AudioTrack` and `Result` types are exported from the root entry. The root and legacy import paths remain available. The types do not pretend every ArtPlayer instance already owns an Hls.js engine; describe `art.hls` in your application's integration types. ## Validation scope The refactor tests Hls.js 1.5.17 and 1.7.2 with local media and real workers; these are tested points, not a newly declared supported range. Firefox grouped-stream crashes and a separate switching stall remain under investigation. Windows Playwright WebKit lacks the MSE path used in those tests; it does not establish Safari/iOS native-HLS acceptance. Verify your actual streams and target devices before adopting the unpublished refactor. ===== packages/artplayer-vitepress/docs/en/plugin/vtt-thumbnail.md ===== # VTT Thumbnail [中文](../../plugin/vtt-thumbnail.md) Load a WebVTT thumbnail index and show the selected sprite region when hovering over the progress bar. Generate the index and images beforehand; this plugin does not scan the video or require another SDK. This page describes the current refactor branch. Parser and lifecycle fixes and the precise `/runtime` types are not published yet. An unpinned npm or CDN installation is not evidence of this branch's behavior. ## Installation ```sh yarn add artplayer artplayer-plugin-vtt-thumbnail ``` ```js import Artplayer from 'artplayer'; import artplayerPluginVttThumbnail from 'artplayer-plugin-vtt-thumbnail'; ``` For script loading, load ArtPlayer first, followed by `dist/artplayer-plugin-vtt-thumbnail.js`. The global is `artplayerPluginVttThumbnail`. Pin dependency versions and make the VTT and images accessible. Cross-origin VTT requests require appropriate server CORS headers. ## Complete example This is the exact code from the [online thumbnail example](https://artplayer.org/?libs=./uncompiled/artplayer-plugin-vtt-thumbnail/index.js&example=vtt.thumbnail). The demo site supplies the media and `.artplayer-app` container; replace them in your application.
```js // npm i artplayer-plugin-vtt-thumbnail // import artplayerPluginVttThumbnail from 'artplayer-plugin-vtt-thumbnail'; const art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/bbb-video.mp4', plugins: [ artplayerPluginVttThumbnail({ vtt: '/assets/sample/bbb-thumbnails.vtt', }), ], }) ``` ## Options The options object passed to `artplayerPluginVttThumbnail(option)` is required. | Field | Type | Behavior | | --- | --- | --- | | `vtt` | `string`, optional in the declaration | VTT file URL. Supply a valid URL in practice: omission fetches an empty URL, meaning the current page, rather than disabling the plugin. | | `style` | Optional `Partial` | Initial inline styles on the thumbnail control, such as `borderRadius: '4px'`. | Rendering updates display, width, height, left, backgroundImage and backgroundPosition. Initial styles cannot permanently override these properties. Each cue supplies the crop dimensions; the plugin does not automatically scale the sprite. ## Index format and image paths ```text WEBVTT 00:00.000 --> 00:05.000 bbb-sprite.jpg#xywh=0,0,128,72 00:05.000 --> 00:10.000 bbb-sprite.jpg#xywh=128,0,128,72 ``` The four values `x,y,w,h` are the left position, top position, width and height within the image, in pixels. x/y must be nonnegative and w/h positive; all four must be finite numbers. Each cue has one image URL line with a crop fragment. Ordinary subtitle text is not a thumbnail index. Relative images are joined to the directory of the **supplied VTT URL**. For example, `bbb-sprite.jpg` inside `/assets/sample/bbb-thumbnails.vtt` becomes `/assets/sample/bbb-sprite.jpg`. Root-relative URLs and full URLs with supported protocols are kept as supplied. The directory is not recalculated from a redirected HTTP response URL. Prefer explicit image URLs when redirects or complex relative paths are involved. The parser supports a BOM, common line endings, optional cue identifiers and timing settings, and skips NOTE, STYLE and REGION blocks. It is a thumbnail index parser, not a complete WebVTT subtitle layout engine. ## Timing and display boundaries For historical compatibility, start and end times are rounded down to whole seconds. Both interval endpoints are included, and the first matching cue in file order wins. At exactly 5 seconds in the example above, the first image still applies; the second appears after 5 seconds. Do not assume millisecond precision or exclusive end times. Desktop hover selects a cue using the progress percentage multiplied by the video duration. Gaps hide the preview, and previews near the edges are aligned inward. The mobile path responds to progress dragging with an input event and hides about 500ms after the last drag update. Desktop coverage does not establish real touch-device support. ## Asynchronous registration, errors and cleanup Registration fetches and parses the VTT and actually returns a Promise. Its success result contains only `name: 'artplayerPluginVttThumbnail'`. Installation through the constructor's plugins array is asynchronous; do not assume that the result is registered immediately after construction. To wait explicitly and handle request or parse errors, call `art.plugins.add()` once after constructing the player: ```ts import Artplayer from 'artplayer'; import thumbnails from 'artplayer-plugin-vtt-thumbnail/runtime'; const art = new Artplayer({ container: '.artplayer-app', url: '/video/movie.mp4', }); async function installThumbnails() { try { const result = await art.plugins.add(thumbnails({ vtt: '/video/movie.vtt' })); console.log(result.name); } catch (error) { console.error('Unable to load thumbnails', error); } } void installThumbnails(); ``` Request and format errors reject registration; format errors include a line number. Registration completion establishes that the VTT was parsed and the control created, not that every image has decoded. Images load when the browser displays them; a later image failure does not reject an already settled registration Promise. There is no update, reload or independent destroy method. Switching the main video does not refetch the VTT. For a different video and thumbnail set, you can destroy and recreate the player. Removing a control is not a complete uninstall; repeated installation is not an update API. Destroying the player cancels outstanding requests where AbortController is available, settles canceled registration, removes owned listeners and timers, and removes the control only if this installation still owns it. Cancellation still returns the name object, so the name alone does not prove an image is available. Late requests cannot remount the interface. ## TypeScript compatibility The root and `/legacy` entrances preserve the latest published 1.1.0 synchronous return declaration and replacement-function shape, although registration is asynchronous at runtime. The `/runtime` entrance above uses the same JavaScript implementation and accurately declares the Promise and runtime `.default` self-alias. It also exposes `Option`, `Result`, `Factory` and `RuntimeFactory` types. The older 1.0.x `export =` shape cannot preserve the same type extraction as the 1.1.0 default export. TypeScript consumers relying on those earlier CommonJS declarations should migrate to `/runtime`. NodeNext ESM consumers should also prefer this entrance to avoid the historical namespace shape retained by the root. Legal older JavaScript calls and distribution file entrances remain available. Browser checks cover cropping and cleanup with published and candidate cores. Complete mobile, plugin combination and release-artifact acceptance remains tracked separately. ===== packages/artplayer-vitepress/docs/en/start/i18n.md ===== # Language Settings ::: danger Due to the increasing number of bundled multilingual resources, starting from version `5.1.0`, the core `artplayer.js` code will no longer bundle any languages other than `Simplified Chinese` and `English`. You will need to manually import any other languages you require. ::: :::warning When a language cannot be matched, English will be displayed by default. For i18n syntax reference, see: [artplayer/types/i18n.d.ts](https://github.com/zhw2590582/ArtPlayer/blob/master/packages/artplayer/types/i18n.d.ts) ::: ## Default Languages The default languages are: `en`, `zh-cn`. No manual import is required. ```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', lang: 'zh-cn', // or 'en' }); ``` ## Importing Languages Language files before bundling are located at: `artplayer/src/i18n/*.js`. Contributions for new languages are welcome. Bundled language files are located at: `artplayer/dist/i18n/*.js` ::: code-group ```js [import] import id from 'artplayer/i18n/id'; import zhTw from 'artplayer/i18n/zh-tw'; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', i18n: { id: id, 'zh-tw': zhTw, }, lang: 'zh-tw', }); ``` ```js [script] var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', i18n: { id: window['artplayer-i18n-id'], 'zh-tw': window['artplayer-i18n-zh-tw'], }, lang: 'zh-tw', }); ``` ::: ## Adding a New Language ```js{4-9} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', lang: 'your-lang', i18n: { 'your-lang': { Play: 'Your Play' }, }, }); ``` ## Modifying a Language ```js import zhTw from 'artplayer/i18n/zh-tw'; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', i18n: { // Change the default language 'zh-cn': { Play: 'Your Play' }, // Change the imported language 'zh-tw': { ...zhTw, Play: 'Your Play' }, }, }); ``` ===== packages/artplayer-vitepress/docs/en/start/option.md ===== # Basic Options ## `container` - Type: `String, Element` - Default: `#artplayer` The `DOM` container where the player is mounted.
▶ Run Code
```js{2} var art = new Artplayer({ container: '.artplayer-app', // container: document.querySelector('.artplayer-app'), url: '/assets/sample/video.mp4', }); ``` You may need to set the size of the container element, for example: ```css{2-3} .artplayer-app { width: 400px; height: 300px; } ``` Or use `aspect-ratio`: ```css{2} .artplayer-app { aspect-ratio: 16/9; } ``` :::warning Note Among all options, only `container` is required. ::: ## `url` - Type: `String` - Default: `''` The video source URL.
▶ Run Code
```js{3} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', }); ``` Sometimes the `url` is not known immediately. In such cases, you can set the `url` asynchronously.
▶ Run Code
```js{6} var art = new Artplayer({ container: '.artplayer-app', }); setTimeout(() => { art.url = '/assets/sample/video.mp4'; }, 1000); ``` :::warning Note By default, three video file formats are supported: `.mp4`, `.ogg`, `.webm`. To play other formats like `.m3u8` or `.flv`, please refer to the `Third-party Libraries` section on the left. ::: ## `id` - Type: `String` - Default: `''` The unique identifier for the player. Currently used only for playback memory `autoplayback`.
▶ Run Code
```js{2} var art = new Artplayer({ id: 'your-url-id', container: '.artplayer-app', url: '/assets/sample/video.mp4', }); ``` ## `onReady` - Type: `Function` - Default: `undefined` The constructor accepts a function as the second parameter. This function is triggered when the player is successfully initialized and the video is ready to play, similar to the `ready` event.
▶ Run Code
```js{7-9} var art = new Artplayer( { container: '.artplayer-app', url: '/assets/sample/video.mp4', muted: true, }, function onReady(art) { this.play() }, ); ``` Equivalent to: ```js{7-9} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', muted: true, }); art.on('ready', () => { art.play(); }); ``` :::warning Note Inside the callback function, `this` refers to the player instance. However, if an arrow function is used for the callback, `this` will not point to the player instance. ::: ## `poster` - Type: `String` - Default: `''` The video poster image, which only appears when the player is initialized and not yet playing.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', poster: '/assets/sample/poster.jpg', }); ``` ## `theme` - Type: `String` - Default: `#f00` The player's theme color, currently used for the `progress bar` and `highlighted elements`.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', theme: '#ffad00', }); ``` ## `volume` - Type: `Number` - Default: `0.7` The player's default volume.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', volume: 0.5, }); ``` :::warning Note The player caches the last volume setting. Upon the next initialization (e.g., page refresh), the player will read this cached value. ::: ## `isLive` - Type: `Boolean` - Default: `false` Enable live streaming mode. This will hide the progress bar and playback time.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', isLive: true, }); ``` ## `muted` - Type: `Boolean` - Default: `false` Whether to start muted by default.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', muted: true, }); ``` ## `autoplay` - Type: `Boolean` - Default: `false` Whether to autoplay.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', autoplay: true, muted: true, }); ``` :::warning Note If you want the video to autoplay immediately upon page load, `muted` must be set to `true`. For more information, please read [Autoplay Policy Changes](https://developers.google.com/web/updates/2017/09/autoplay-policy-changes). ::: ## `autoSize` - Type: `Boolean` - Default: `false` By default, the player's dimensions fill the entire `container`, often resulting in black bars. This option automatically adjusts the player size to hide black bars, similar to `css`'s `object-fit: cover;`.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', autoSize: true, }); ``` ## `autoMini` - Type: `Boolean` - Default: `false` Automatically enters `Mini Player` mode when the player scrolls out of the browser viewport.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', autoMini: true, }); ``` ## `loop` - Type: `Boolean` - Default: `false` Whether to loop playback.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', loop: true, }); ``` ## `flip` - Type: `Boolean` - Default: `false` Whether to display the video flip function. Currently only appears in the `Settings Panel` and `Context Menu`.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', flip: true, setting: true, }); ``` ## `playbackRate` - Type: `Boolean` - Default: `false` Whether to display the video playback speed function. It will appear in the `Settings Panel` and `Context Menu`.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', playbackRate: true, setting: true, }); ``` ## `aspectRatio` - Type: `Boolean` - Default: `false` Whether to display the video aspect ratio function. It will appear in the `Settings Panel` and `Context Menu`.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', aspectRatio: true, setting: true, }); ``` ## `screenshot` - Type: `Boolean` - Default: `false` Whether to display the `Screenshot` function in the bottom control bar.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', screenshot: true, }); ``` :::warning Note Due to browser security mechanisms, screenshotting may fail if the video source URL is cross-origin with the website. ::: ## `setting` - Type: `Boolean` - Default: `false` Whether to display the toggle button for the `Settings Panel` in the bottom control bar.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, }); ``` ## `hotkey` - Type: `Boolean` - Default: `true` Whether to use hotkeys.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', hotkey: true, }); ``` | Hotkey | Description | | ------- | -------------------- | | `↑` | Increase volume | | `↓` | Decrease volume | | `←` | Seek forward | | `→` | Seek backward | | `space` | Toggle play/pause | :::warning Note These hotkeys only take effect after the player gains focus (e.g., after clicking on the player). ::: ## `pip` - Type: `Boolean` - Default: `false` Whether to display the `Picture-in-Picture` toggle button in the bottom control bar.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', pip: true, }); ``` ## `mutex` - Type: `Boolean` - Default: `true` If multiple players exist on the page simultaneously, whether only one player is allowed to play at a time.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', mutex: true, }); ``` ## `backdrop` - Type: `Boolean` - Default: `true` Whether to enable the backdrop blur effect for the player UI. When enabled, overlays such as the settings panel, context menu, and volume bar will apply a `backdrop-filter` frosted glass effect for a more transparent look. However, this may cause performance or compatibility issues on some low-performance devices or older browsers.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', backdrop: false, // Disable frosted glass effect }); ``` ## `fullscreen` - Type: `Boolean` - Default: `false` Whether to display the player `Window Fullscreen` button in the bottom control bar.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', fullscreen: true, }); ``` ## `fullscreenWeb` - Type: `Boolean` - Default: `false` Whether to display the player `Web Fullscreen` button in the bottom control bar.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', fullscreenWeb: true, }); ``` ## `subtitleOffset` - Type: `Boolean` - Default: `false` Subtitle time offset, ranging from `[-5s, 5s]`. Appears in the `Settings Panel`.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', subtitleOffset: true, subtitle: { url: '/assets/sample/subtitle.srt', }, setting: true, }); ``` ## `miniProgressBar` - Type: `Boolean` - Default: `false` A mini progress bar that only appears when the player loses focus and is playing.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', miniProgressBar: true, }); ``` ## `useSSR` - Type: `Boolean` - Default: `false` Whether to use SSR (Server-Side Rendering) mount mode. Useful if you want to pre-render the player's required HTML before the player is mounted. You can access the player's required HTML via `Artplayer.html`.
▶ Run Code
```js{7} var $container = document.querySelector('.artplayer-app'); $container.innerHTML = Artplayer.html; var art = new Artplayer({ container: $container, url: '/assets/sample/video.mp4', useSSR: true, }); ``` ## `playsInline` - Type: `Boolean` - Default: `true` Whether to use `playsInline` mode on mobile devices.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', playsInline: true, }); ``` ## `layers` - Type: `Array` - Default: `[]` Initialize custom layers.
▶ Run Code
```js{5-23} var img = '/assets/sample/layer.png'; var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', layers: [ { name: 'potser', html: ``, style: { position: 'absolute', top: '20px', right: '20px', opacity: '.9', }, click: function (...args) { console.info('click', args); art.layers.show = false; }, mounted: function (...args) { console.info('mounted', args); }, }, ], }); ``` :::warning For `Component Configuration`, please refer to: [/component/layers.html](/component/layers.html) ::: ## `settings` - Type: `Array` - Default: `[]` Initialize custom settings panels.
▶ Run Code
```js{5-34} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', setting: true, settings: [ { html: 'setting01', selector: [ { html: 'setting01-01', }, { html: 'setting01-02', }, ], onSelect: function (...args) { console.info(args); }, }, { html: 'setting02', selector: [ { html: 'setting02-01', }, { html: 'setting02-02', }, ], onSelect: function (...args) { console.info(args); }, }, ], }); ``` :::warning For `Settings Panel`, please refer to: [/component/setting.html](/component/setting.html) ::: ## `contextmenu` - Type: `Array` - Default: `[]` Initialize custom context menus.
▶ Run Code
```js{4-12} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', contextmenu: [ { html: 'your-menu', click: function (...args) { console.info('click', args); art.contextmenu.show = false; }, }, ], }); ``` :::warning For `Component Configuration`, please refer to: [/component/contextmenu.html](/component/contextmenu.html) ::: ## `controls` - Type: `Array` - Default: `[]` Initialize custom bottom control bar.
▶ Run Code
```js{4-16} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', controls: [ { position: 'left', html: 'your-control', tooltip: 'Your Control', style: { color: 'green', }, click: function (...args) { console.info('click', args); }, }, ], }); ``` :::warning For `Component Configuration`, please refer to the following address: [/component/controls.html](/component/controls.html) ::: ## `quality` - Type: `Array` - Default: `[]` Whether to display the `Quality Selection` list in the bottom control bar. | Property | Type | Description | | --------- | --------- | ---------------- | | `default` | `Boolean` | Default quality | | `html` | `String` | Quality name | | `url` | `String` | Quality URL |
▶ Run Code
```js{4-14} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', quality: [ { default: true, html: 'SD 480P', url: '/assets/sample/video.mp4', }, { html: 'HD 720P', url: '/assets/sample/video.mp4', }, ], }); ``` ## `highlight` - Type: `Array` - Default: `[]` Display `Highlight Information` on the progress bar. | Property | Type | Description | | -------- | -------- | ------------------------------- | | `time` | `Number` | Highlight time (in seconds) | | `text` | `String` | Highlight text |
▶ Run Code
```js{4-25} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', highlight: [ { time: 60, text: 'One more chance', }, { time: 120, text: '谁でもいいはずなのに', }, { time: 180, text: '夏の想い出がまわる', }, { time: 240, text: 'こんなとこにあるはずもないのに', }, { time: 300, text: '--终わり--', }, ], }); ``` ## `plugins` - Type: `Array` - Default: `[]` Initialize custom `plugins`.
▶ Run Code
```js{15} function myPlugin(art) { console.info(art); return { name: 'myPlugin', something: 'something', doSomething: function () { console.info('doSomething'); }, }; } var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', plugins: [myPlugin], }); ``` ## `thumbnails` - Type: `Object` - Default: `{}` Set `Preview Thumbnails` on the progress bar. | Property | Type | Description | | -------- | -------- | -------------------------- | | `url` | `String` | Thumbnail image URL | | `number` | `Number` | Number of thumbnails | | `column` | `Number` | Number of thumbnail columns| | `width` | `Number` | Thumbnail width | | `height` | `Number` | Thumbnail height | | `scale` | `Number` | Thumbnail scale |
▶ Run Code
```js{4-8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', thumbnails: { url: '/assets/sample/thumbnails.png', number: 60, column: 10, }, }); ``` :::warning Generate Thumbnails Online [artplayer-tool-thumbnail](https://artplayer.org/?libs=./uncompiled/artplayer-tool-thumbnail/index.js&example=thumbnail) ::: ## `subtitle` - Type: `Object` - Default: `{}` Set video subtitles. Supported subtitle formats: `vtt`, `srt`, `ass`. | Property | Type | Description | | ----------- | ---------- | ------------------------------------------------ | | `name` | `String` | Subtitle name | | `url` | `String` | Subtitle URL | | `type` | `String` | Subtitle type, options: `vtt`, `srt`, `ass` | | `style` | `Object` | Subtitle style | | `encoding` | `String` | Subtitle encoding, default `utf-8` | | `escape` | `Boolean` | Whether to escape `html` tags, default `true` | | `onVttLoad` | `Function` | Function for modifying `vtt` text |
▶ Run Code
```js{4-12} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', subtitle: { url: '/assets/sample/subtitle.srt', type: 'srt', encoding: 'utf-8', escape: true, style: { color: '#03A9F4', 'font-size': '30px', }, }, }); ``` ## `moreVideoAttr` - Type: `Object` - Default: `{'controls': false, 'preload': 'metadata'}` (In Safari, it will automatically adjust to `preload: 'auto'` for better loading experience.) More video attributes. These attributes will be written directly into the video element.
▶ Run Code
```js{4-7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', moreVideoAttr: { 'webkit-playsinline': true, playsInline: true, }, }); ``` ## `icons` - Type: `Object` - Default: `{}` Used to replace default icons. Supports `Html` strings and `HTMLElement`.
▶ Run Code
```js{4-7} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', icons: { loading: '', state: '', }, }); ``` :::warning All Icon Definitions [artplayer/types/icons.d.ts](https://github.com/zhw2590582/ArtPlayer/blob/master/packages/artplayer/types/icons.d.ts) ::: ## `type` - Type: `String` - Default: `''` Used to specify the video format. It needs to be used together with `customType`. By default, the video format is determined by the suffix of the video URL (e.g., `.m3u8`, `.mkv`, `.ts`). However, sometimes the video URL may not have the correct suffix, so it needs to be explicitly specified.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.m3u8', type: 'm3u8', }); ``` :::warning Suffix Recognition The player can only parse suffixes like this: `/assets/sample/video.m3u8` But cannot parse suffixes like this: `/assets/sample/video?type=m3u8` Therefore, if you use `customType`, it's best to also specify the `type`. ::: ## `customType` - Type: `Object` - Default: `{}` Matches based on the video's `type` and delegates video decoding to third-party programs for processing. The processing function can receive three parameters: - `video`: The video `DOM` element - `url`: The video URL - `art`: The current instance
▶ Run Code
```js{4-8} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.m3u8', customType: { m3u8: function (video, url, art) { // }, }, }); ``` ## `lang` - Type: `String` - Default: `navigator.language.toLowerCase()` The default display language. Currently supported: `en`, `zh-cn`.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', lang: 'en', }); ``` :::warning More Language Settings [/start/i18n.html](/start/i18n.html) ::: ## `i18n` - Type: `Object` - Default: `{}` Custom `i18n` configuration. This configuration will be deeply merged with the built-in `i18n`. Add your language:
▶ Run Code
```js{4-9} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', lang: 'your-lang', i18n: { 'your-lang': { Play: 'Your Play' }, }, }); ``` Modify an existing language:
▶ Run Code
```js{4-11} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', i18n: { 'zh-cn': { Play: 'Your Play' }, 'zh-tw': { Play: 'Your Play' }, }, }); ``` :::warning More Language Settings [/start/i18n.html](/start/i18n.html) ::: ## `lock` - Type: `Boolean` - Default: `false` Whether to display a `lock button` on mobile devices to hide the bottom `control bar`.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', lock: true, }); ``` ## `gesture` - Type: `Boolean` - Default: `true` Whether to enable gesture events on the video element on mobile devices.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', gesture: false, }); ``` ## `fastForward` - Type: `Boolean` - Default: `false` Whether to add a long-press video fast-forward feature on mobile devices.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', fastForward: true, }); ``` ## `autoPlayback` - Type: `Boolean` - Default: `false` Whether to use the automatic `playback feature`.
▶ Run Code
```js{4-5} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', id: 'your-url-id', autoPlayback: true, }); ``` :::warning Note Because the player uses the `url` as the `key` to cache playback progress by default. However, if the `url` for the same video is different, then you need to use `id` to identify the unique `key` for the video. ::: ## `autoOrientation` - Type: `Boolean` - Default: `false` Whether to rotate the player in fullscreen mode on mobile web, based on the video dimensions and viewport dimensions.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', autoOrientation: true, }); ``` ## `airplay` - Type: `Boolean` - Default: `false` Whether to display the `airplay` button. Currently, only some browsers support this feature.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', airplay: true, }); ``` ## `cssVar` - Type: `Object` - Default: `{}` Used to modify the built-in CSS variables.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', cssVar: { // }, }); ``` :::warning Reference for `cssVar` Syntax [artplayer/types/cssVar.d.ts](https://github.com/zhw2590582/ArtPlayer/blob/master/packages/artplayer/types/cssVar.d.ts) ::: ## `proxy` - Type: `function` - Default: `undefined` The function can return a third-party `HTMLCanvasElement` or `HTMLVideoElement`. For example, it can proxy an existing `video` DOM element.
▶ Run Code
```js{4} var art = new Artplayer({ container: '.artplayer-app', url: '/assets/sample/video.mp4', proxy: () => document.createElement('video') }); ``` ===== Type Definitions Overview ===== ===== docs/assets/ts/artplayer-plugin-ads.d.ts ===== // Generated from the package public declaration by yarn build:ts. Do not edit. /* eslint-disable ts/no-redeclare -- Callable and public type namespace intentionally merge. */ declare namespace artplayerPluginAds { interface Translations { close: string countdown: string detail: string canBeClosed: string } /** Implemented options. Video takes precedence over HTML. */ interface Option { html?: string video?: string url?: string /** Seconds before the close button becomes available. @default 5 */ playDuration?: number /** Total advertisement duration in seconds. @default 10 */ totalDuration?: number /** Initial ad-video mute state. @default false */ muted?: boolean /** All four fields replace the default translation object together. */ i18n?: Translations } /** Historical published declaration. String durations still fail runtime validation. */ interface LegacyOption extends Omit { /** @deprecated Incorrect in the old declaration; use a numeric duration. */ totalDuration?: string } /** Historical unpublished workspace declaration; these fields are not runtime aliases. */ interface WorkspaceOption extends Option { /** @deprecated Ignored by the runtime. Use html or video instead. */ source: string /** @deprecated Ignored by the runtime. Images are supplied through html. */ type: 'video' | 'image' | 'html' } /** Input acceptance for both historical declaration families. */ interface CompatOption extends Omit { /** @deprecated The string branch exists for old types only and is rejected at runtime. */ totalDuration?: number | string /** @deprecated Ignored by the runtime. Use html or video instead. */ source?: string /** @deprecated Ignored by the runtime. Images are supplied through html. */ type?: 'video' | 'image' | 'html' } interface Result { name: 'artplayerPluginAds' /** Complete once; before initialization this cancels the pending preroll. */ skip: () => void /** Pause only the countdown, leaving ad video playback unchanged. */ pause: () => void /** Resume only the countdown without adding extra timers. */ play: () => void } interface Callable { (option?: Option): (art: Artplayer) => Result /** @deprecated Compatibility with erroneous old string-duration declarations only. */ (option: LegacyOption): (art: Artplayer) => Result (option: WorkspaceOption): (art: Artplayer) => Result (option?: CompatOption): (art: Artplayer) => Result /** Required final signature keeps Parameters extraction free of top-level undefined. */ (option: CompatOption): (art: Artplayer) => Result } interface Factory extends Callable { /** Same function; supports historical require(package).default calls. */ readonly default: Callable } interface RuntimeCallable { (option?: Option): (art: Artplayer) => Result (option: Option): (art: Artplayer) => Result } /** Accurate typing for the identical implementation at /runtime. */ interface RuntimeFactory extends RuntimeCallable { readonly default: RuntimeCallable } } declare const artplayerPluginAds: artplayerPluginAds.Factory export = artplayerPluginAds export as namespace artplayerPluginAds; ===== docs/assets/ts/artplayer-plugin-ambilight.d.ts ===== // Generated from the package public declaration by yarn build:ts. Do not edit. /* eslint-disable ts/no-redeclare -- Callable and public type namespace intentionally merge. */ declare namespace artplayerPluginAmbilightDefinitions { export interface Option { /** CSS blur radius. @default '50px' */ blur?: string /** Grid cell opacity. @default 0.5 */ opacity?: number /** Maximum sampling frequency in frames per second. @default 10 */ frequency?: number /** Historical input retained for compatibility; runtime uses a fixed z-index of 9. */ zIndex?: number /** Background color transition duration in seconds. @default 0.3 */ duration?: number } export interface Result { name: 'artplayerPluginAmbilight' /** Start sampling; does nothing after the player is destroyed. */ start: () => void /** Stop sampling while retaining the last colors. */ stop: () => void } /** Published 1.1.0 factory shape; the options argument remains required. */ export type Callable = (option: Option) => (art: Artplayer) => Result export type Factory = Callable /** Accurate optional invocation and CommonJS self alias, exposed by /runtime. */ export interface RuntimeFactory { (option?: Option): (art: Artplayer) => Result readonly default: RuntimeFactory } export const artplayerPluginAmbilight: (option: Option) => (art: Artplayer) => Result } declare const artplayerPluginAmbilight: typeof artplayerPluginAmbilightDefinitions.artplayerPluginAmbilight declare namespace artplayerPluginAmbilight { export type Option = artplayerPluginAmbilightDefinitions.Option export type Result = artplayerPluginAmbilightDefinitions.Result export type Callable = artplayerPluginAmbilightDefinitions.Callable export type Factory = artplayerPluginAmbilightDefinitions.Factory export type RuntimeFactory = artplayerPluginAmbilightDefinitions.RuntimeFactory } export = artplayerPluginAmbilight export as namespace artplayerPluginAmbilight; ===== docs/assets/ts/artplayer-plugin-asr.d.ts ===== // Generated from the package public declaration by yarn build:ts. Do not edit. /* eslint-disable ts/no-redeclare -- Callable and public type namespace intentionally merge. */ declare namespace artplayerPluginAsrDefinitions { export interface AudioChunk { pcm: ArrayBuffer wav: ArrayBuffer } export interface AsrPluginOption { length?: number interval?: number sampleRate?: number autoHideTimeout?: number onAudioChunk?: (chunk: AudioChunk) => void | Promise } export interface AsrPluginInstance { name: 'artplayerPluginAsr' stop: () => void hide: () => void append: (subtitle: string) => void } /** Historical factory shape, including void stop and callback results. */ export type Factory = (option?: AsrPluginOption) => (art: Artplayer) => AsrPluginInstance /** Accurate asynchronous view available through the /runtime entry. */ export interface RuntimeOption extends Omit { /** Capture the media stream without taking ownership of its playback route. */ audioInput?: { type: 'capture' } onAudioChunk?: (chunk: AudioChunk) => string | void | null | Promise } export interface RuntimeResult extends Omit { stop: () => Promise } export interface RuntimeFactory { (option?: RuntimeOption): (art: Artplayer) => RuntimeResult readonly default: RuntimeFactory } export function artplayerPluginAsr(option?: AsrPluginOption): (art: Artplayer) => AsrPluginInstance } declare const artplayerPluginAsr: typeof artplayerPluginAsrDefinitions.artplayerPluginAsr declare namespace artplayerPluginAsr { export type AudioChunk = artplayerPluginAsrDefinitions.AudioChunk export type AsrPluginOption = artplayerPluginAsrDefinitions.AsrPluginOption export type AsrPluginInstance = artplayerPluginAsrDefinitions.AsrPluginInstance export type Factory = artplayerPluginAsrDefinitions.Factory export type RuntimeOption = artplayerPluginAsrDefinitions.RuntimeOption export type RuntimeResult = artplayerPluginAsrDefinitions.RuntimeResult export type RuntimeFactory = artplayerPluginAsrDefinitions.RuntimeFactory } export = artplayerPluginAsr export as namespace artplayerPluginAsr; ===== docs/assets/ts/artplayer-plugin-audio-track.d.ts ===== // Generated from the package public declaration by yarn build:ts. Do not edit. /* eslint-disable ts/no-redeclare -- Callable and public type namespace intentionally merge. */ declare namespace artplayerPluginAudioTrackDefinitions { export interface Option { /** * Audio track URL */ url: string /** * Time offset in seconds between video and audio * Positive value means audio plays ahead of video * Negative value means audio plays behind video * @default 0 */ offset?: number /** * Synchronization threshold in seconds * @default 0.3 */ sync?: number } export type UpdateOption = Partial