update docs

This commit is contained in:
Harvey Zack committed 2023-01-14 18:39:52 +08:00
1 parent 8b515906f5
commit d696e817cf
17 files changed
+5006 -4

No files matched your search

@@ -0,0 +1,498 @@
# 高级属性
这里的 `高级属性` 是指挂载在 `实例` 的 `二级属性`,比较少用
## `option`
播放器的选项
<div className="run-code">▶ Run Code</div>
```js
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
console.info(art.option);
```
:::warning 提示
假如直接修改这个 `option` 对象,播放器不会马上做出响应
:::
## `whitelist`
管理移动设备的白名单功能,只有一个属性 `state` 返回是否启用播放器功能
<div className="run-code">▶ Run Code</div>
```js
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
whitelist: [(ua) => /iPhone/gi.test(ua)],
});
console.info(art.whitelist.state);
```
:::warning 提示
在上面这个例子中,当使用 `iPhone` 访问播放器时,`art.whitelist.state` 会返回 `false`,即使用原生的播放器,而不是 `Artplayer` 播放器
:::
## `template`
管理播放器所有的 `DOM` 元素
<div className="run-code">▶ Run Code</div>
```js
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
console.info(art.template);
console.info(art.template.$video);
```
:::warning 提示
为了方便区别 `DOM` 元素和普通对象,播放器里的所有 `DOM` 元素都是以 `$` 开头命名的
这是所有 `DOM` 元素的定义:[artplayer/types/template.d.ts](https://github.com/zhw2590582/ArtPlayer/blob/master/packages/artplayer/types/template.d.ts)
:::
## `events`
管理播放器所有的 `DOM` 事件,实质上是代理了 `addEventListener` 和 `removeEventListener`, 当使用以下方法来处理事件,播放器销毁时也会自动销毁该事件
- `proxy` 方法用于代理 `DOM` 事件
- `hover` 方法用于代理自定义的 `hover` 事件
- `loadImg` 方法用于监听图片的 `load` 加载事件
<div className="run-code">▶ Run Code</div>
```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);
});
art.events.loadImg('/assets/sample/poster.jpg').then(img => {
console.info('loadImg', img);
});
```
:::warning 提示
假如你需要一些 `DOM` 事件只存在于播放器的生命周期上时,强烈建议使用这些函数,以避免造成内存泄漏
:::
## `storage`
管理播放器的本地存储
- `name` 属性用于设置缓存的 `key`
- `set` 方法用于设置缓存
- `get` 方法用于获取缓存
- `del` 方法用于删除缓存
- `clear` 方法用于清空缓存
<div className="run-code">▶ Run Code</div>
```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 提示
默认所有播放器实例都是共享同一个 `localStorage` 的,而且默认的 `key` 是 `artplayer_settings`
如果你想不同的播放器使用不同的 `localStorage`,你可以修改 `art.storage.name` 即可
:::
<div className="run-code">▶ Run Code</div>
```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`
管理播放器所有的 `svg` 图标
<div className="run-code">▶ Run Code</div>
```js
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
console.info(art.icons.loading);
```
:::warning 这是所有图标的定义:
[artplayer/types/icons.d.ts](https://github.com/zhw2590582/ArtPlayer/blob/master/packages/artplayer/types/icons.d.ts)
:::
## `i18n`
管理播放器的 `i18n`
- `get` 方法用于获取 `i18n` 的值
- `update` 方法用于更新 `i18n` 对象
<div className="run-code">▶ Run Code</div>
```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
使用 `art.i18n.update` 只能更新实例化之后的 `i18n`,假如想在实例化之前更新 `i18n`,请使用基础选项的 `i18n` 来更新
:::
## `notice`
管理播放器的提示语,只有一个 `show` 属性用于显示提示语
<div className="run-code">▶ Run Code</div>
```js
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('ready', () => {
art.notice.show = 'Video Ready To Play';
})
```
:::warning
如果想马上隐藏 `notice` 的显示:`art.notice.show = '';`
:::
## `layers`
管理播放器的层
- `add` 方法用于动态添加层
- `show` 属性用于设置是否显示全部层
- `toggle` 属性用于切换是否显示全部层
<div className="run-code">▶ Run Code</div>
```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 `组件配置` 请参考以下地址:
[/start/component.html](/start/component.html)
:::
## `controls`
管理播放器的控制器
- `add` 方法用于动态添加控制器
- `show` 属性用于设置是否显示全部控制器
- `toggle` 属性用于切换是否显示全部控制器
<div className="run-code">▶ Run Code</div>
```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 `组件配置` 请参考以下地址:
[/start/component.html](/start/component.html)
:::
## `contextmenu`
管理播放器的右键菜单
- `add` 方法用于动态添加菜单
- `show` 属性用于设置是否显示全部菜单
- `toggle` 属性用于切换是否显示全部菜单
<div className="run-code">▶ Run Code</div>
```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 `组件配置` 请参考以下地址:
[/start/component.html](/start/component.html)
:::
## `subtitle`
管理播放器的字幕功能
- `url` 属性设置和返回当前字幕地址
- `style` 方法设置当前字幕的样式
- `switch` 方法设置当前字幕地址和选项
<div className="run-code">▶ Run Code</div>
```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',
});
});
```
## `loading`
管理播放器的加载层
- `show` 属性用于设置是否显示加载层
- `toggle` 属性用于切换是否显示加载层
<div className="run-code">▶ Run Code</div>
```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`
管理播放器的快捷键功能
- `add` 方法用于添加快捷键
- `remove` 方法用于删除快捷键
<div className="run-code">▶ Run Code</div>
```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 提示
只在播放器获得焦点后(如点击了播放器后),这些快捷键才会生效
:::
## `mask`
管理播放器的遮罩层
- `show` 属性用于设置是否显示遮罩层
- `toggle` 属性用于切换是否显示遮罩层
<div className="run-code">▶ Run Code</div>
```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`
管理播放器的设置面板
- `add` 方法用于动态添加设置项
- `show` 属性用于设置是否显示全部设置项
- `toggle` 属性用于切换是否显示全部设置项
- `update` 方法动态更新设置项
<div className="run-code">▶ Run Code</div>
```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 `设置面板` 请参考以下地址
[/start/setting.html](/start/setting.html)
:::
## `plugins`
管理播放器的插件功能,只有一个方法 `add` 用于动态添加插件
<div className="run-code">▶ Run Code</div>
```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);
});
```
@@ -0,0 +1,212 @@
# 静态属性
这里的 `静态属性` 是指挂载在 `构造函数` 的 `一级属性`,非常少使用
:::warning 提示
有些属性是全大写的,说明这些属性是不稳定的,可能会在将来被更改
:::
## `instances`
返回全部播放器实例的数组,假如你想同时管理多个播放器的时候,可以用到该属性
<div className="run-code">▶ Run Code</div>
```js
console.info([...Artplayer.instances]);
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
console.info([...Artplayer.instances]);
```
## `version`
返回播放器的版本信息
<div className="run-code">▶ Run Code</div>
```js
console.info(Artplayer.version);
```
## `env`
返回播放器的环境变量
<div className="run-code">▶ Run Code</div>
```js
console.info(Artplayer.env);
```
## `build`
返回播放器的打包时间
<div className="run-code">▶ Run Code</div>
```js
console.info(Artplayer.build);
```
## `config`
返回视频的默认配置
<div className="run-code">▶ Run Code</div>
```js
console.info(Artplayer.config);
```
## `utils`
返回播放器的工具函数集合
<div className="run-code">▶ Run Code</div>
```js
console.info(Artplayer.utils);
```
:::warning 全部工具函数请参考以下地址:
[artplayer/types/utils.d.ts](https://github.com/zhw2590582/ArtPlayer/blob/master/packages/artplayer/types/utils.d.ts)
:::
## `scheme`
返回播放器选项的校验方案
<div className="run-code">▶ Run Code</div>
```js
console.info(Artplayer.scheme);
```
## `Emitter`
返回事件分发器的构造函数
<div className="run-code">▶ Run Code</div>
```js
console.info(Artplayer.Emitter);
```
## `validator`
返回选项的校验函数
<div className="run-code">▶ Run Code</div>
```js
console.info(Artplayer.validator);
```
## `kindOf`
返回类型检测的函数工具
<div className="run-code">▶ Run Code</div>
```js
console.info(Artplayer.kindOf);
```
## `html`
返回播放器所需的 `html` 字符串
<div className="run-code">▶ Run Code</div>
```js
console.info(Artplayer.html);
```
## `option`
返回播放器的默认选项
<div className="run-code">▶ Run Code</div>
```js
console.info(Artplayer.option);
```
## `DEBUG`
## `CONTEXTMENU`
## `NOTICE_TIME`
## `SETTING_WIDTH`
## `SETTING_ITEM_WIDTH`
## `SETTING_ITEM_HEIGHT`
## `INDICATOR_SIZE`
## `INDICATOR_SIZE_ICON`
## `INDICATOR_SIZE_MOBILE`
## `INDICATOR_SIZE_MOBILE_ICON`
## `VOLUME_PANEL_WIDTH`
## `VOLUME_HANDLE_WIDTH`
## `RESIZE_TIME`
## `SCROLL_TIME`
## `SCROLL_GAP`
## `AUTO_PLAYBACK_MAX`
## `AUTO_PLAYBACK_MIN`
## `AUTO_PLAYBACK_TIMEOUT`
## `RECONNECT_TIME_MAX`
## `RECONNECT_SLEEP_TIME`
## `CONTROL_HIDE_TIME`
## `DB_CLICE_TIME`
## `MOBILE_AUTO_PLAYBACKRATE`
## `MOBILE_AUTO_PLAYBACKRATE_TIME`
## `MOBILE_AUTO_ORIENTATION_TIME`
## `INFO_LOOP_TIME`
## `FAST_FORWARD_VALUE`
## `FAST_FORWARD_TIME`
## `TOUCH_MOVE_RATIO`
## `VOLUME_STEP`
## `SEEK_STEP`
## `PROGRESS_HEIGHT`
## `PLAYBACK_RATE`
## `ASPECT_RATIO`
## `FLIP`
@@ -0,0 +1,712 @@
# 实例事件
播放器的事件分为两种,一种视频的 `原生事件` (前缀 `video:`),另外一种是 `自定义事件`
监听事件:
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('video:canplay', () => {
console.info('video:canplay');
});
```
只监听一次事件:
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.once('video:canplay', () => {
console.info('video:canplay');
});
```
手动触发事件:
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.emit('focus');
```
移除事件:
<div className="run-code">▶ Run Code</div>
```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 全部事件请参考以下地址:
[artplayer/types/events.d.ts](https://github.com/zhw2590582/ArtPlayer/blob/master/packages/artplayer/types/events.d.ts)
:::
## `ready`
当播放器首次可以播放器时触发
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('ready', () => {
console.info('ready');
});
```
## `restart`
当播放器切换地址后并可以播放时触发
<div className="run-code">▶ Run Code</div>
```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', () => {
console.info('restart');
});
```
## `pause`
当播放器暂停时触发
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('pause', () => {
console.info('pause');
});
```
## `play`
当播放器播放时触发
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('play', () => {
console.info('play');
});
```
## `hotkey`
当播放器热键被按下时触发
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('hotkey', (event) => {
console.info('hotkey', event);
});
```
## `destroy`
当播放器销毁时触发
<div className="run-code">▶ Run Code</div>
```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');
});
```
## `url`
当视频地址变化时触发
<div className="run-code">▶ Run Code</div>
```js{10}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('ready', () => {
art.url = '/assets/sample/video.mp4?t=0'
});
art.on('url', (url) => {
console.info('url', url);
});
```
## `focus`
当播放器获得焦点时触发
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('focus', () => {
console.info('focus');
});
```
## `blur`
当播放器失去焦点时触发
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('blur', () => {
console.info('blur');
});
```
## `dblclick`
当播放器被双击时触发
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('dblclick', () => {
console.info('dblclick');
});
```
## `click`
当播放器被单击时触发
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('click', () => {
console.info('click');
});
```
## `error`
当播放器加载视频发生错误时触发
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/404.mp4',
});
art.on('error', (error, reconnectTime) => {
console.info(error, reconnectTime);
});
```
## `hover`
当播放器被鼠标移出或者移入时触发
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('hover', (state) => {
console.info('hover', state);
});
```
## `mousemove`
当播放器被鼠标经过时触发
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('mousemove', (event) => {
console.info('mousemove', event);
});
```
## `resize`
当播放器尺寸变化时触发
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('resize', () => {
console.info('resize');
});
```
## `view`
当播放器出现在视口时触发
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('view', (state) => {
console.info('view', state);
});
```
## `aspectRatio`
当播放器长宽比变化时触发
<div className="run-code">▶ Run Code</div>
```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`
当播放器自动设置高度时触发
<div className="run-code">▶ Run Code</div>
```js{10}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('ready', () => {
art.autoHeight = true;
});
art.on('autoHeight', (height) => {
console.info('autoHeight', height);
});
```
## `autoSize`
当播放器自动设置尺寸时触发
<div className="run-code">▶ Run Code</div>
```js{7}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
autoSize: true,
});
art.on('autoSize', () => {
console.info('autoSize');
});
```
## `flip`
当播放器发生翻转时触发
<div className="run-code">▶ Run Code</div>
```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`
当播放器发生窗口全屏时触发
<div className="run-code">▶ Run Code</div>
```js{7}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
fullscreen: true,
});
art.on('fullscreen', (state) => {
console.info('fullscreen', state);
});
```
## `fullscreenWeb`
当播放器发生网页全屏时触发
<div className="run-code">▶ Run Code</div>
```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`
当播放器进入迷你模式时触发
<div className="run-code">▶ Run Code</div>
```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`
当播放器进入画中画时触发
<div className="run-code">▶ Run Code</div>
```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`
当播放器被截图时触发
<div className="run-code">▶ Run Code</div>
```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`
当播放器发生时间跳转时触发
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('seek', (currentTime) => {
console.info('seek', currentTime);
});
```
## `subtitleOffset`
当播放器发生字幕偏移时触发
<div className="run-code">▶ Run Code</div>
```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);
});
```
## `subtitleUpdate`
当字幕更新时触发
<div className="run-code">▶ Run Code</div>
```js{9}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
subtitle: {
url: '/assets/sample/subtitle.srt',
},
});
art.on('subtitleUpdate', (text) => {
console.info('subtitleUpdate', text);
});
```
## `subtitleLoad`
当字幕加载时触发
<div className="run-code">▶ Run Code</div>
```js{9}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
subtitle: {
url: '/assets/sample/subtitle.srt',
},
});
art.on('subtitleLoad', (url) => {
console.info('subtitleLoad', url);
});
```
## `subtitleSwitch`
当字幕切换时触发
<div className="run-code">▶ Run Code</div>
```js{13}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
subtitle: {
url: '/assets/sample/subtitle.srt',
},
});
art.on('ready', () => {
art.subtitle.url = '/assets/sample/subtitle.ass';
});
art.on('subtitleSwitch', (url) => {
console.info('subtitleSwitch', url);
});
```
## `video:canplay`
浏览器可以播放媒体文件了,但估计没有足够的数据来支撑播放到结束,不必停下来进一步缓冲内容
## `video:canplaythrough`
浏览器估计它可以在不停止内容缓冲的情况下播放媒体直到结束
## `video:complete`
OfflineAudioContext 渲染完成
## `video:durationchange`
duration 属性的值改变时触发
## `video:emptied`
媒体内容变为空;例如,当这个 media 已经加载完成(或者部分加载完成),则发送此事件,并调用 load() 方法重新加载它
## `video:ended`
视频停止播放,因为 media 已经到达结束点
## `video:error`
获取媒体数据时出错,或者资源类型不是受支持的媒体格式
## `video:loadeddata`
media 中的首帧已经完成加载
## `video:loadedmetadata`
已加载元数据
## `video:pause`
播放已暂停
## `video:play`
播放已开始
## `video:playing`
由于缺乏数据而暂停或延迟后,播放准备开始
## `video:progress`
在浏览器加载资源时周期性触发
## `video:ratechange`
播放速率发生变化
## `video:seeked`
跳帧(seek)操作完成
## `video:seeking`
跳帧(seek)操作开始
## `video:stalled`
用户代理(user agent)正在尝试获取媒体数据,但数据意外未出现
## `video:suspend`
媒体数据加载已暂停
## `video:timeupdate`
currentTime 属性指定的时间发生变化
## `video:volumechange`
音量发生变化
## `video:waiting`
由于暂时缺少数据,播放已停止
@@ -0,0 +1,125 @@
# 编写插件
但你已经知道播放器的`属性`, `方法`和`事件`后,再编写插件是非常简单的事
可以在实例化的时候加载插件的函数
<div className="run-code">▶ Run Code</div>
```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);
});
```
可以在实例化之后再加载插件的函数
<div className="run-code">▶ Run Code</div>
```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);
});
```
例如我想写一个在视频暂停后,显示一个图片广告的插件
<div className="run-code">▶ Run Code</div>
```js
function adsPlugin(option) {
return (art) => {
art.layers.add({
name: 'ads',
html: `<img style="width: 100px" src="${option.url}">`,
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'
})
],
});
```
@@ -0,0 +1,910 @@
# 实例属性
这里的 `实例属性` 是指挂载在 `实例` 的 `一级属性`,比较常用
## `play`
- Type: `Function`
播放视频
<div className="run-code">▶ Run Code</div>
```js{8}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
muted: true,
});
art.on('ready', () => {
art.play();
});
```
## `pause`
- Type: `Function`
暂停视频
<div className="run-code">▶ Run Code</div>
```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`
切换视频的播放和暂停
<div className="run-code">▶ Run Code</div>
```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`
销毁播放器,接受一个参数表示是否销毁后同时移除播放器的 `html`,默认为 `true`
<div className="run-code">▶ Run Code</div>
```js{7}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('ready', () => {
art.destroy();
});
```
## `seek`
- Type: `Setter`
- Parameter: `Number`
视频时间跳转,单位秒
<div className="run-code">▶ Run Code</div>
```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`
视频时间快进,单位秒
<div className="run-code">▶ Run Code</div>
```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`
视频时间快退,单位秒
<div className="run-code">▶ Run Code</div>
```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`
设置和获取视频音量,范围在:`[0, 1]`
<div className="run-code">▶ Run Code</div>
```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`
设置和获取视频地址
<div className="run-code">▶ Run Code</div>
```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';
});
```
## `switchUrl`
- Type: `Function`
- Parameter: `String`
设置视频地址,设置时和 `url` 类似,但会执行一些优化操作
函数支持两个参数,第一个为新的视频地址,第二个为可选新的视频名字
<div className="run-code">▶ Run Code</div>
```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);
});
```
## `switchQuality`
- Type: `Function`
- Parameter: `String`
设置视频画质地址,和 `switchUrl` 类似,但会带上之前的播放进度
函数支持两个参数,第一个为新的视频地址,第二个为可选新的视频名字
<div className="run-code">▶ Run Code</div>
```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`
设置和获取视频是否静音
<div className="run-code">▶ Run Code</div>
```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`
设置和获取视频当前时间,设置时间时和 `seek` 类似,但它不会触发额外的事件
<div className="run-code">▶ Run Code</div>
```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`
获取视频时长
<div className="run-code">▶ Run Code</div>
```js{7}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('ready', () => {
console.info(art.duration);
});
```
:::warning 提示
有的视频是没有时长的,例如直播中的视频或者没被解码完成的视频,这个时候获取的时长会是 `0`
:::
## `screenshot`
- Type: `Function`
下载当前视频帧的截图
<div className="run-code">▶ Run Code</div>
```js{7}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('ready', () => {
art.screenshot();
});
```
## `getDataURL`
- Type: `Function`
获取当前视频帧的截图的`base64`地址,返回的是一个 `Promise`
<div className="run-code">▶ Run Code</div>
```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`
获取当前视频帧的截图的`blob`地址,返回的是一个 `Promise`
<div className="run-code">▶ Run Code</div>
```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`
设置和获取播放器窗口全屏
<div className="run-code">▶ Run Code</div>
```js{9}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
controls: [
{
position: 'right',
html: '全屏开关',
click: function () {
art.fullscreen = !art.fullscreen;
},
},
],
});
```
:::warning 提示
由于浏览器安全机制,触发窗口全屏前,页面必须先存在交互(例如用户点击过页面)
:::
## `fullscreenWeb`
- Type: `Setter/Getter`
- Parameter: `Boolean`
设置和获取播放器网页全屏
<div className="run-code">▶ Run Code</div>
```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`
设置和获取播放器画中画模式
<div className="run-code">▶ Run Code</div>
```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 提示
由于浏览器安全机制,触发画中画前,页面必须先存在交互(例如用户点击过页面)
:::
## `poster`
- Type: `Setter/Getter`
- Parameter: `String`
设置和获取视频海报,只有在视频播放前才能看到海报效果
<div className="run-code">▶ Run Code</div>
```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`
设置和获取播放器迷你模式
<div className="run-code">▶ Run Code</div>
```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`
获取视频是否正在播放中
<div className="run-code">▶ Run Code</div>
```js{8}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
muted: true,
});
art.on('ready', () => {
console.info(art.playing);
});
```
## `autoSize`
- Type: `Setter/Getter`
- Parameter: `Boolean`
设置视频是否自适应尺寸,设置为 `true` 之后它会只执行一次
<div className="run-code">▶ Run Code</div>
```js{8}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('ready', () => {
console.info(art.autoSize);
art.autoSize = true;
console.info(art.autoSize);
});
```
## `rect`
- Type: `Getter`
获取播放器的尺寸和坐标信息
<div className="run-code">▶ Run Code</div>
```js{7}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('ready', () => {
console.info(JSON.stringify(art.rect));
});
```
:::warning 提示
尺寸和坐标信息是通过 `getBoundingClientRect` 获取的
:::
## `flip`
- Type: `Setter/Getter`
- Parameter: `String`
设置和获取播放器翻转,支持`normal`, `horizontal`, `vertical`
<div className="run-code">▶ Run Code</div>
```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`
设置和获取播放器播放速度
<div className="run-code">▶ Run Code</div>
```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`
设置和获取播放器长宽比
<div className="run-code">▶ Run Code</div>
```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);
});
```
## `loop`
- Type: `Setter/Getter`
- Parameter: `Array`
设置和获取区间循序播放,单位秒
<div className="run-code">▶ Run Code</div>
```js{8}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('ready', () => {
console.info(art.loop);
art.loop = [5, 10];
console.info(art.loop);
});
```
:::warning 提示
删除区间循环播放,只需要设置 `loop` 为 `[]` 即可
`art.loop` 与 `art.option.loop` 是两个不同的东西,请勿弄乱
:::
## `autoHeight`
- Type: `Setter/Getter`
- Parameter: `Boolean`
当容器只有宽度,该属性可以自动计算出并设置视频的高度,设置为 `true` 之后它会只执行一次
<div className="run-code">▶ Run Code</div>
```js{7,11}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('ready', () => {
art.autoHeight = true;
});
art.on('resize', () => {
art.autoHeight = true;
});
```
:::warning 提示
当你的容器只有宽度,但不知道具体高度时,这个属性很有用,它能自动计算出视频的高度,但你需要确定设置这个属性的时机
:::
## `attr`
- Type: `Function`
- Parameter: `String`
动态获取和设置 video 元素的属性
<div className="run-code">▶ Run Code</div>
```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'));
});
```
## `title`
- Type: `Setter/Getter`
- Parameter: `String`
动态获取和设置播放器标题
<div className="run-code">▶ Run Code</div>
```js{8}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('ready', () => {
console.info(art.title);
art.title = '新标题';
console.info(art.title);
});
```
## `type`
- Type: `Setter/Getter`
- Parameter: `String`
动态获取和设置视频类型
<div className="run-code">▶ Run Code</div>
```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`
动态获取和设置播放器主题颜色
<div className="run-code">▶ Run Code</div>
```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`
开启隔空播放
<div className="run-code">▶ Run Code</div>
```js{10}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
controls: [
{
position: 'right',
html: 'AirPlay',
click: function () {
art.airplay();
},
},
],
});
```
## `loaded`
- Type: `Getter`
视频缓存的比例,范围是 `[0, 1]`,常配合 `video:timeupdate` 事件使用
<div className="run-code">▶ Run Code</div>
```js{7}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
art.on('video:timeupdate', () => {
console.info(art.loaded);
});
```
## `played`
- Type: `Getter`
视频播放的比例,范围是 `[0, 1]`,常配合 `video:timeupdate` 事件使用
<div className="run-code">▶ Run Code</div>
```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`
`DOM` 事件的代理函数,实质上代理了 `addEventListener` 和 `removeEventListener`, 当使用 `proxy` 来处理事件,播放器销毁时也会自动销毁该事件
<div className="run-code">▶ Run Code</div>
```js{7-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 提示
假如你需要一些 `DOM` 事件只存在于播放器的生命周期上时,强烈建议使用该函数,以避免造成内存泄漏
:::
## `query`
- Type: `Function`
`DOM` 的查询函数,类似 `document.querySelector`,但被查询的对象局限于当前播放器内,可以避免同类名的错误
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
console.info(art.query('.art-video'));
```
## `video`
- Type: `Element`
快捷返回播放器的 `video` 元素
<div className="run-code">▶ Run Code</div>
```js{6}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
});
console.info(art.video);
```
+270 -1
View File
@@ -1 +1,270 @@
# WIP...
# Install
## Install
::: code-group
```bash [npm]
npm install artplayer
```
```bash [yarn]
yarn add artplayer
```
```bash [pnpm]
pnpm add artplayer
```
```html [script]
<script src="path/to/artplayer.js"></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
```
:::
## Use
::: code-group
```js [index.js]
import Artplayer from 'artplayer';
const art = new Artplayer({
container: '.artplayer-app',
url: 'path/to/video.mp4',
});
```
```html [index.html]
<html>
<head>
<title>ArtPlayer Demo</title>
<meta charset="UTF-8" />
<style>
.artplayer-app {
width: 400px;
height: 300px;
}
</style>
</head>
<body>
<div class="artplayer-app"></div>
</body>
</html>
```
:::
::: warning Tip
The size of the player depends on the size of the `container`, so your `container` must have a size
:::
::: tip The following links can see more use examples
[/packages/artplayer-template](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer-template)
:::
## `Vue.js`
::: code-group
```vue [Artplayer.vue]
<template>
<div ref="artRef"></div>
</template>
<script>
import Artplayer from "artplayer";
export default {
data() {
return {
instance: null,
};
},
props: {
option: {
type: Object,
required: true,
},
},
mounted() {
this.instance = new Artplayer({
...this.option,
container: this.$refs.artRef,
});
this.$nextTick(() => {
this.$emit("get-instance", this.instance);
});
},
beforeUnmount() {
if (this.instance && this.instance.destroy) {
this.instance.destroy(false);
}
},
};
</script>
```
```vue [app.vue]
<template>
<Artplayer @get-instance="getInstance" :option="option" :style="style" />
</template>
<script>
import Artplayer from "./Artplayer.vue";
export default {
data() {
return {
option: {
url: "path/to/video.mp4",
},
style: {
width: "600px",
height: "400px",
margin: "60px auto 0",
},
};
},
components: {
Artplayer,
},
methods: {
getInstance(art) {
console.info(art);
},
},
};
</script>
```
:::
::: warning Tip
Modifying `option` directly in `Vue.js` will not change the player
:::
## `React.js`
::: code-group
```jsx [Artplayer.jsx]
import { useEffect, useRef } from 'react';
import Artplayer from 'artplayer';
export default function Player({ option, getInstance, ...rest }) {
const artRef = useRef();
useEffect(() => {
const art = new Artplayer({
...option,
container: artRef.current,
});
if (getInstance && typeof getInstance === 'function') {
getInstance(art);
}
return () => {
if (art && art.destroy) {
art.destroy(false);
}
};
}, []);
return <div ref={artRef} {...rest}></div>;
}
```
```jsx [app.jsx]
import React from 'react';
import Artplayer from './ArtPlayer.jsx';
function App() {
return (
<div>
<Artplayer
option={{
url: 'https://artplayer.org/assets/sample/video.mp4',
}}
style={{
width: '600px',
height: '400px',
margin: '60px auto 0',
}}
getInstance={(art) => console.info(art)}
/>
</div>
);
}
export default App;
```
:::
::: warning Tip
Modifying `option` directly in `React.js` will not change the player
:::
## Syntax hint
Sometimes your `js` file will lose the type prompt of `TypeScript`. At this time, you can manually import the type
Variable:
```js
/**
* @type {import("artplayer")}
*/
let art = null;
```
Parameters:
```js
/**
* @param {import("artplayer")} art
*/
function getInstance(art) {
//
}
```
Properties:
```js
export default {
data() {
return {
/**
* @type {import("artplayer")}
*/
art: null,
}
}
}
```
@@ -0,0 +1,36 @@
# dash.js
👉 [https://github.com/Dash-Industry-Forum/dash.js](https://github.com/Dash-Industry-Forum/dash.js)
<div className="run-code" data-libs="https://cdnjs.cloudflare.com/ajax/libs/dashjs/4.5.2/dash.all.min.js">
▶ Run Code
</div>
```js{18-21,25}
function playMpd(video, url, art) {
if (dashjs.supportsMediaSource()) {
const dash = dashjs.MediaPlayer().create();
dash.initialize(video, url, art.option.autoplay);
// optional
art.dash = dash;
art.once('url', () => dash.destroy());
art.once('destroy', () => dash.destroy());
} else {
art.notice.show = 'Unsupported playback format: mpd';
}
}
var art = new Artplayer({
container: '.artplayer-app',
url: 'https://dash.akamaized.net/envivio/EnvivioDash3/manifest.mpd',
type: 'mpd',
customType: {
mpd: playMpd
},
});
art.on('ready', () => {
console.info(art.dash);
});
```
@@ -0,0 +1,37 @@
# flv.js
👉 [https://github.com/Bilibili/flv.js](https://github.com/Bilibili/flv.js)
<div className="run-code" data-libs="https://cdnjs.cloudflare.com/ajax/libs/flv.js/1.6.2/flv.min.js">
▶ Run Code
</div>
```js{19-22,26}
function playFlv(video, url, art) {
if (flvjs.isSupported()) {
const flv = flvjs.createPlayer({ type: 'flv', url });
flv.attachMediaElement(video);
flv.load();
// optional
art.flv = flv;
art.once('url', () => flv.destroy());
art.once('destroy', () => flv.destroy());
} else {
art.notice.show = 'Unsupported playback format: flv';
}
}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.flv',
type: 'flv',
customType: {
flv: playFlv,
},
});
art.on('ready', () => {
console.info(art.flv);
});
```
@@ -0,0 +1,39 @@
# hls.js
👉 [https://github.com/video-dev/hls.js](https://github.com/video-dev/hls.js)
<div className="run-code" data-libs="https://cdnjs.cloudflare.com/ajax/libs/hls.js/8.0.0-beta.3/hls.min.js">
▶ Run Code
</div>
```js{21-24,28}
function playM3u8(video, url, art) {
if (Hls.isSupported()) {
const hls = new Hls();
hls.loadSource(url);
hls.attachMedia(video);
// optional
art.hls = hls;
art.once('url', () => hls.destroy());
art.once('destroy', () => hls.destroy());
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = url;
} else {
art.notice.show = 'Unsupported playback format: m3u8';
}
}
var art = new Artplayer({
container: '.artplayer-app',
url: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8',
type: 'm3u8',
customType: {
m3u8: playM3u8,
},
});
art.on('ready', () => {
console.info(art.hls);
});
```
@@ -0,0 +1,98 @@
# 视频广告
## 演示
👉 [查看完整演示](https://artplayer.org/?libs=./uncompiled/artplayer-plugin-ads/index.js&example=ads)
## 安装
::: code-group
```bash [npm]
npm install artplayer-plugin-ads
```
```bash [yarn]
yarn add artplayer-plugin-ads
```
```bash [pnpm]
pnpm add artplayer-plugin-ads
```
```html [script]
<script src="path/to/artplayer-plugin-ads.js"></script>
```
:::
## CDN
::: code-group
```bash [jsdelivr.net]
https://cdn.jsdelivr.net/npm/artplayer-plugin-ads/dist/artplayer-plugin-ads.js
```
```bash [unpkg.com]
https://unpkg.com/artplayer-plugin-ads/dist/artplayer-plugin-ads.js
```
:::
## 使用
<div className="run-code" data-libs="./uncompiled/artplayer-plugin-ads/index.js">
▶ Run Code
</div>
```js
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
autoSize: true,
fullscreen: true,
fullscreenWeb: true,
plugins: [
artplayerPluginAds({
// html广告,假如是视频广告则忽略该值
html: '<img src="/assets/sample/poster.jpg">',
// 视频广告的地址
video: '/assets/sample/test1.mp4',
// 广告跳转网址,为空则不跳转
url: 'http://artplayer.org',
// 必须观看的时长,期间不能被跳过,单位为秒
// 当该值大于或等于totalDuration时,不能提前关闭广告
// 当该值等于或小于0时,则随时都可以关闭广告
playDuration: 5,
// 广告总时长,单位为秒
totalDuration: 10,
// 视频广告是否默认静音
muted: false,
// 多语言支持
i18n: {
close: '关闭广告',
countdown: '%s秒',
detail: '查看详情',
canBeClosed: '%s秒后可关闭广告',
},
}),
],
});
// ad is clicked
art.on('artplayerPluginAds:click', (ads) => {
console.info(ads);
});
// Ad skipped
art.on('artplayerPluginAds:skip', (ads) => {
console.info(ads);
});
```
@@ -0,0 +1,92 @@
# 控制器皮肤
## 演示
👉 [查看完整演示](https://artplayer.org/?libs=./uncompiled/artplayer-plugin-control/index.js&example=control)
## 安装
::: code-group
```bash [npm]
npm install artplayer-plugin-control
```
```bash [yarn]
yarn add artplayer-plugin-control
```
```bash [pnpm]
pnpm add artplayer-plugin-control
```
```html [script]
<script src="path/to/artplayer-plugin-control.js"></script>
```
:::
## CDN
::: code-group
```bash [jsdelivr.net]
https://cdn.jsdelivr.net/npm/artplayer-plugin-control/dist/artplayer-plugin-control.js
```
```bash [unpkg.com]
https://unpkg.com/artplayer-plugin-control/dist/artplayer-plugin-control.js
```
:::
## 使用
<div className="run-code" data-libs="./uncompiled/artplayer-plugin-control/index.js">
▶ Run Code
</div>
```js{7}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
fullscreen: true,
fullscreenWeb: true,
plugins: [
artplayerPluginControl(),
],
});
```
## `enable`
- Type: `Getter/Setter`
- Parameter: `Boolean`
是否启用新的控制器皮肤
<div className="run-code" data-libs="./uncompiled/artplayer-plugin-control/index.js">
▶ Run Code
</div>
```js
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
fullscreen: true,
fullscreenWeb: true,
controls: [
{
position: 'right',
html: '<button type="button">Switch UI</button>',
click: function () {
const { enable } = art.plugins.artplayerPluginControl;
art.plugins.artplayerPluginControl.enable = !enable;
},
},
],
plugins: [
artplayerPluginControl(),
],
});
```
@@ -0,0 +1,41 @@
# HLS 画质
## 演示
👉 [查看完整演示](https://artplayer.org/?libs=https://cdnjs.cloudflare.com/ajax/libs/hls.js/8.0.0-beta.3/hls.min.js%0A./uncompiled/artplayer-plugin-hls-quality/index.js&example=hls.quality)
## 安装
::: code-group
```bash [npm]
npm install artplayer-plugin-hls-quality
```
```bash [yarn]
yarn add artplayer-plugin-hls-quality
```
```bash [pnpm]
pnpm add artplayer-plugin-hls-quality
```
```html [script]
<script src="path/to/artplayer-plugin-hls-quality.js"></script>
```
:::
## CDN
::: code-group
```bash [jsdelivr.net]
https://cdn.jsdelivr.net/npm/artplayer-plugin-hls-quality/dist/artplayer-plugin-hls-quality.js
```
```bash [unpkg.com]
https://unpkg.com/artplayer-plugin-hls-quality/dist/artplayer-plugin-hls-quality.js
```
:::
@@ -0,0 +1,293 @@
# Iframe 控制
## 说明
通过该插件,你可以轻松在 `index.html` 里控制跨域 `iframe.html` 页面里的播放器,如在 `index.html` 里通过代码控制 `iframe.html` 播放器的功能,或者获取 `iframe.html` 播放器的值
## 演示
👉 [查看完整演示](https://artplayer.org/?libs=./uncompiled/artplayer-plugin-iframe/index.js&example=iframe)
## 安装
::: code-group
```bash [npm]
npm install artplayer-plugin-iframe
```
```bash [yarn]
yarn add artplayer-plugin-iframe
```
```bash [pnpm]
pnpm add artplayer-plugin-iframe
```
```html [script]
<script src="path/to/artplayer-plugin-iframe.js"></script>
```
:::
## `CDN`
::: code-group
```bash [jsdelivr.net]
https://cdn.jsdelivr.net/npm/artplayer-plugin-iframe/dist/artplayer-plugin-iframe.js
```
```bash [unpkg.com]
https://unpkg.com/artplayer-plugin-iframe/dist/artplayer-plugin-iframe.js
```
:::
## 使用
::: code-group
```html [index.html]
<!DOCTYPE html>
<html>
<head>
<title>ArtPlayer</title>
<meta charset="UTF-8" />
</head>
<body>
<iframe id="iframe"></iframe>
<script src="path/to/artplayer-plugin-iframe.js"></script>
<script>
const iframe = new ArtplayerPluginIframe({
// Iframe element
iframe: document.querySelector('#iframe'),
// Iframe url
url: 'path/to/iframe.html',
});
// Send message to iframe
iframe.commit(() => {
var art = new Artplayer({
container: '.artplayer-app',
url: 'path/to/video.mp4',
});
});
</script>
</body>
</html>
```
```html [iframe.html]
<!DOCTYPE html>
<html>
<head>
<title>ArtPlayer</title>
<meta charset="UTF-8" />
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div class="artplayer-app" style="width: 100%; height: 100%;"></div>
<script src="path/to/artplayer.js"></script>
<script src="path/to/artplayer-plugin-iframe.js"></script>
<script>
// Inject scripts to receive messages from instances
ArtplayerPluginIframe.inject();
</script>
</body>
</html>
```
:::
## `index.html` 接口
### `commit`
从 `index.html` 将消息推送到 `iframe.html`,该函数将在 `iframe.html` 内部运行,同时它也能用于异步获取 `iframe.html` 里的值
```js
iframe.commit(() => {
var art = new Artplayer({
container: '.artplayer-app',
url: 'path/to/video.mp4',
});
});
iframe.commit(() => {
art.seek = 5;
});
// Get the value from the iframe.html
(async function () {
// Use the return keyword
var currentTime = await iframe.commit(() => {
return art.currentTime;
});
// or use the resolve method
var currentTime2 = await iframe.commit((resolve) => {
setTimeout(() => {
resolve(art.currentTime);
}, 1000);
});
})();
```
### `message`
在 `index.html` 接收来自 `iframe.html` 的消息
```js
iframe.message((event) => {
console.info(event);
});
```
### `destroy`
销毁后 `index.html` 无法与 `iframe.html` 通信
```js
iframe.destroy();
```
## `iframe.html` 接口
:::warning 提示
`iframe.html` 接口 只能运行在 `iframe.html` 里
:::
### `inject`
注入脚本,接收来自 `index.html` 的消息
```js
ArtplayerPluginIframe.inject();
```
### `postMessage`
将消息推送到 `index.html`
```js
iframe.message((event) => {
console.info(event);
});
iframe.commit(() => {
ArtplayerPluginIframe.postMessage({
type: 'currentTime',
data: art.currentTime,
});
});
```
## 例子
最常遇到的问题是,播放器在 `iframe.html` 里进行网页全屏,但在 `index.html` 是不生效的,这时候只要监听 `iframe.html` 里的 `fullscreenWeb` 事件并通知到 `index.html` 即可
::: code-group
```html [index.html]
<!DOCTYPE html>
<html>
<head>
<title>ArtPlayer</title>
<meta charset="UTF-8" />
</head>
<body>
<iframe id="iframe"></iframe>
<script src="path/to/artplayer-plugin-iframe.js"></script>
<style>
.fullscreenWeb {
position: fixed;
z-index: 9999;
width: 100%;
height: 100%;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
</style>
<script>
const iframe = new ArtplayerPluginIframe({
iframe: document.querySelector('#iframe'),
url: 'path/to/iframe.html',
});
iframe.message(({ type, data }) => {
switch (type) {
case 'fullscreenWeb':
if (data) {
$iframe.classList.add('fullscreenWeb');
} else {
$iframe.classList.remove('fullscreenWeb');
}
break;
default:
break;
}
});
iframe.commit(() => {
var art = new Artplayer({
container: '.artplayer-app',
url: 'path/to/video.mp4',
});
art.on('fullscreenWeb', (state) => {
ArtplayerPluginIframe.postMessage({
type: 'fullscreenWeb',
data: state,
});
});
});
</script>
</body>
</html>
```
```html [iframe.html]
<!DOCTYPE html>
<html>
<head>
<title>ArtPlayer</title>
<meta charset="UTF-8" />
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div class="artplayer-app" style="width: 100%; height: 100%;"></div>
<script src="path/to/artplayer.js"></script>
<script src="path/to/artplayer-plugin-iframe.js"></script>
<script>
ArtplayerPluginIframe.inject();
</script>
</body>
</html>
```
:::
@@ -0,0 +1,222 @@
# 组件配置
这里所说的组件配置主要是指:`layers` , `controls` , `contextmenu` 这三个共用的配置:
| 属性 | 类型 | 描述 |
| --------- | ------------------- | -------------------------- |
| `disable` | `Boolean` | 是否禁用组件 |
| `name` | `String` | 组件唯一名称,用于标记类名 |
| `index` | `Number` | 组件索引,用于显示的优先级 |
| `html` | `String`, `Element` | 组件的 DOM 元素 |
| `style` | `Object` | 组件样式对象 |
| `click` | `Function` | 组件点击事件 |
| `mounted` | `Function` | 组件挂载后触发 |
| `tooltip` | `String` | 组件的提示文本 |
:::warning 提示
- 当前组件只能添加,并没有销毁的功能
- 通过 `name` 选项可以快速获取组件的 `DOM` 元素
- 通过 `index` 选项可以控制组件出现的顺序
:::
## `layers`
实例化时添加一个层,例如可以添加 `logo` 或者 `广告` 等等
<div className="run-code">▶ Run Code</div>
```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: `<img style="width: 100px" src="${img}">`,
tooltip: 'Potser Tip',
style: {
position: 'absolute',
top: '50px',
right: '50px',
},
click: function (...args) {
console.info('click', args);
},
mounted: function (...args) {
console.info('mounted', args);
},
},
],
});
console.info(art.layers.potser);
```
也可以实例化之后添加一个层
<div className="run-code">▶ Run Code</div>
```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: `<img style="width: 100px" src="${img}">`,
tooltip: 'Potser Tip',
style: {
position: 'absolute',
top: '50px',
right: '50px',
},
click: function (...args) {
console.info('click', args);
},
mounted: function (...args) {
console.info('mounted', args);
},
});
console.info(art.layers.potser);
```
## `controls`
实例化时添加一个控制器
:::warning controls 还有三个额外的选项
- `position`: `left` 和 `right` 控制控制器出现的左右位置
- `selector`: 快速创建选择列表的对象数组
- `onSelect`: 选择列表的元素被点击时触发的函数
:::
<div className="run-code">▶ Run Code</div>
```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: '<span style="color:red">subtitle 01</span>',
},
{
html: '<span style="color:yellow">subtitle 02</span>',
},
],
onSelect: function (item, $dom) {
console.info(item, $dom);
return 'Your ' + item.html;
},
},
],
});
console.info(art.controls['your-button']);
console.info(art.controls.subtitle);
```
也可以实例化之后添加一个控制器
```js{6-22}
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);
},
});
console.info(art.controls.button1);
```
## `contextmenu`
实例化时添加一个右键菜单
<div className="run-code">▶ Run Code</div>
```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;
},
},
],
});
console.info(art.contextmenu['your-menu']);
```
也可以实例化之后添加一个右键菜单
<div className="run-code">▶ Run Code</div>
```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;
},
});
console.info(art.contextmenu['your-menu']);
```
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,214 @@
# 设置面板
需先打开设置面板,播放器默认自带四个设置项:`flip`, `playbackRate`, `aspectRatio`, `subtitleOffset`
<div className="run-code">▶ Run Code</div>
```js{4}
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
setting: true,
flip: true,
playbackRate: true,
aspectRatio: true,
subtitleOffset: true,
});
```
## 选择列表
| 属性 | 类型 | 描述 |
| ---------- | ------------------- | --------------- |
| `html` | `String`, `Element` | 元素的 DOM 元素 |
| `icon` | `String`, `Element` | 元素的图标 |
| `selector` | `Array` | 元素列表 |
| `onSelect` | `Function` | 元素点击事件 |
| `width` | `Number` | 列表宽度 |
| `default` | `Boolean` | 是否默认选中 |
| `tooltip` | `String` | 提示文本 |
<div className="run-code">▶ Run Code</div>
```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: '<span style="color:red">Subtitle 01</span>',
url: '/assets/sample/subtitle.srt?id=1',
},
{
html: '<span style="color:yellow">Subtitle 02</span>',
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;
},
},
],
});
```
## 列表嵌套
<div className="run-code">▶ Run Code</div>
```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;
},
},
],
},
],
});
```
## 切换按钮
| 属性 | 类型 | 描述 |
| ---------- | ------------------- | --------------- |
| `html` | `String`, `Element` | 元素的 DOM 元素 |
| `icon` | `String`, `Element` | 元素的图标 |
| `switch` | `Boolean` | 按钮默认状态 |
| `onSwitch` | `Function` | 按钮切换事件 |
| `tooltip` | `String` | 提示文本 |
<div className="run-code">▶ Run Code</div>
```js
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
setting: true,
settings: [
{
html: 'PIP Mode',
tooltip: 'Close',
icon: '<img width="22" heigth="22" src="/assets/img/state.svg">',
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;
},
},
],
});
```
## 范围滑块
| 属性 | 类型 | 描述 |
| ---------- | ------------------- | ---------------- |
| `html` | `String`, `Element` | 元素的 DOM 元素 |
| `icon` | `String`, `Element` | 元素的图标 |
| `range` | `Array` | 默认状态数组 |
| `onRange` | `Function` | 完成时触发的事件 |
| `onChange` | `Function` | 变化时触发的事件 |
| `tooltip` | `String` | 提示文本 |
```js
const range = [5, 1, 10, 1];
const value = range[0];
const min = range[1];
const max = range[2];
const step = range[3];
```
<div className="run-code">▶ Run Code</div>
```js
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
setting: true,
settings: [
{
html: 'Slider',
tooltip: '5x',
icon: '<img width="22" heigth="22" src="/assets/img/state.svg">',
range: [5, 1, 10, 1],
onChange: function (item, $dom, event) {
console.info(item, $dom, event);
return item.range + 'x';
},
},
],
});
```
@@ -170,7 +170,7 @@ var art = new Artplayer({
- Type: `String`
- Default: `#f00`
播放器主题颜色,目前作用于 `进度条` 和 `高亮元素` 上
播放器主题颜色,目前用于 `进度条` 和 `高亮元素` 上
<div className="run-code">▶ Run Code</div>
@@ -429,8 +429,8 @@ var art = new Artplayer({
| ------- | ------------- |
| `↑` | 增加音量 |
| `↓` | 降低音量 |
| `←` | 快进 5 秒 |
| `→` | 快退 5 秒 |
| `←` | 视频快进 |
| `→` | 视频快退 |
| `space` | 切换播放/暂停 |
:::warning 提示