diff --git a/packages/artplayer-vitepress/docs/en/advanced/built-in.md b/packages/artplayer-vitepress/docs/en/advanced/built-in.md
new file mode 100644
index 000000000..69eaf6f09
--- /dev/null
+++ b/packages/artplayer-vitepress/docs/en/advanced/built-in.md
@@ -0,0 +1,498 @@
+# 高级属性
+
+这里的 `高级属性` 是指挂载在 `实例` 的 `二级属性`,比较少用
+
+## `option`
+
+播放器的选项
+
+
▶ Run Code
+
+```js
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+console.info(art.option);
+```
+
+:::warning 提示
+
+假如直接修改这个 `option` 对象,播放器不会马上做出响应
+
+:::
+
+## `whitelist`
+
+管理移动设备的白名单功能,只有一个属性 `state` 返回是否启用播放器功能
+
+▶ Run Code
+
+```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` 元素
+
+▶ 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 提示
+
+为了方便区别 `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` 加载事件
+
+▶ 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);
+});
+
+art.events.loadImg('/assets/sample/poster.jpg').then(img => {
+ console.info('loadImg', img);
+});
+```
+
+:::warning 提示
+
+假如你需要一些 `DOM` 事件只存在于播放器的生命周期上时,强烈建议使用这些函数,以避免造成内存泄漏
+
+:::
+
+## `storage`
+
+管理播放器的本地存储
+
+- `name` 属性用于设置缓存的 `key`
+- `set` 方法用于设置缓存
+- `get` 方法用于获取缓存
+- `del` 方法用于删除缓存
+- `clear` 方法用于清空缓存
+
+▶ 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 提示
+
+默认所有播放器实例都是共享同一个 `localStorage` 的,而且默认的 `key` 是 `artplayer_settings`
+
+如果你想不同的播放器使用不同的 `localStorage`,你可以修改 `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`
+
+管理播放器所有的 `svg` 图标
+
+▶ Run Code
+
+```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` 对象
+
+▶ 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
+
+使用 `art.i18n.update` 只能更新实例化之后的 `i18n`,假如想在实例化之前更新 `i18n`,请使用基础选项的 `i18n` 来更新
+
+:::
+
+
+## `notice`
+
+管理播放器的提示语,只有一个 `show` 属性用于显示提示语
+
+▶ 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
+
+如果想马上隐藏 `notice` 的显示:`art.notice.show = '';`
+
+:::
+
+## `layers`
+
+管理播放器的层
+
+- `add` 方法用于动态添加层
+- `show` 属性用于设置是否显示全部层
+- `toggle` 属性用于切换是否显示全部层
+
+▶ 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 `组件配置` 请参考以下地址:
+
+[/start/component.html](/start/component.html)
+
+:::
+
+## `controls`
+
+管理播放器的控制器
+
+- `add` 方法用于动态添加控制器
+- `show` 属性用于设置是否显示全部控制器
+- `toggle` 属性用于切换是否显示全部控制器
+
+▶ 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 `组件配置` 请参考以下地址:
+
+[/start/component.html](/start/component.html)
+
+:::
+
+## `contextmenu`
+
+管理播放器的右键菜单
+
+- `add` 方法用于动态添加菜单
+- `show` 属性用于设置是否显示全部菜单
+- `toggle` 属性用于切换是否显示全部菜单
+
+▶ 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 `组件配置` 请参考以下地址:
+
+[/start/component.html](/start/component.html)
+
+:::
+
+## `subtitle`
+
+管理播放器的字幕功能
+
+- `url` 属性设置和返回当前字幕地址
+- `style` 方法设置当前字幕的样式
+- `switch` 方法设置当前字幕地址和选项
+
+▶ 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',
+ });
+});
+```
+
+## `loading`
+
+管理播放器的加载层
+
+- `show` 属性用于设置是否显示加载层
+- `toggle` 属性用于切换是否显示加载层
+
+▶ 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`
+
+管理播放器的快捷键功能
+
+- `add` 方法用于添加快捷键
+- `remove` 方法用于删除快捷键
+
+▶ 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 提示
+
+只在播放器获得焦点后(如点击了播放器后),这些快捷键才会生效
+
+:::
+
+## `mask`
+
+管理播放器的遮罩层
+
+- `show` 属性用于设置是否显示遮罩层
+- `toggle` 属性用于切换是否显示遮罩层
+
+▶ 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`
+
+管理播放器的设置面板
+
+- `add` 方法用于动态添加设置项
+- `show` 属性用于设置是否显示全部设置项
+- `toggle` 属性用于切换是否显示全部设置项
+- `update` 方法动态更新设置项
+
+▶ 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 `设置面板` 请参考以下地址
+
+[/start/setting.html](/start/setting.html)
+
+:::
+
+## `plugins`
+
+管理播放器的插件功能,只有一个方法 `add` 用于动态添加插件
+
+▶ 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);
+});
+```
\ No newline at end of file
diff --git a/packages/artplayer-vitepress/docs/en/advanced/class.md b/packages/artplayer-vitepress/docs/en/advanced/class.md
new file mode 100644
index 000000000..0d38a41c9
--- /dev/null
+++ b/packages/artplayer-vitepress/docs/en/advanced/class.md
@@ -0,0 +1,212 @@
+# 静态属性
+
+这里的 `静态属性` 是指挂载在 `构造函数` 的 `一级属性`,非常少使用
+
+:::warning 提示
+
+有些属性是全大写的,说明这些属性是不稳定的,可能会在将来被更改
+
+:::
+
+## `instances`
+
+返回全部播放器实例的数组,假如你想同时管理多个播放器的时候,可以用到该属性
+
+▶ Run Code
+
+```js
+console.info([...Artplayer.instances]);
+
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+console.info([...Artplayer.instances]);
+```
+
+## `version`
+
+返回播放器的版本信息
+
+▶ Run Code
+
+```js
+console.info(Artplayer.version);
+```
+
+## `env`
+
+返回播放器的环境变量
+
+▶ Run Code
+
+```js
+console.info(Artplayer.env);
+```
+
+## `build`
+
+返回播放器的打包时间
+
+▶ Run Code
+
+```js
+console.info(Artplayer.build);
+```
+
+## `config`
+
+返回视频的默认配置
+
+▶ Run Code
+
+```js
+console.info(Artplayer.config);
+```
+
+## `utils`
+
+返回播放器的工具函数集合
+
+▶ Run Code
+
+```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`
+
+返回播放器选项的校验方案
+
+▶ Run Code
+
+```js
+console.info(Artplayer.scheme);
+```
+
+## `Emitter`
+
+返回事件分发器的构造函数
+
+▶ Run Code
+
+```js
+console.info(Artplayer.Emitter);
+```
+
+## `validator`
+
+返回选项的校验函数
+
+▶ Run Code
+
+```js
+console.info(Artplayer.validator);
+```
+
+## `kindOf`
+
+返回类型检测的函数工具
+
+▶ Run Code
+
+```js
+console.info(Artplayer.kindOf);
+```
+
+## `html`
+
+返回播放器所需的 `html` 字符串
+
+▶ Run Code
+
+```js
+console.info(Artplayer.html);
+```
+
+## `option`
+
+返回播放器的默认选项
+
+▶ Run Code
+
+```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`
\ No newline at end of file
diff --git a/packages/artplayer-vitepress/docs/en/advanced/event.md b/packages/artplayer-vitepress/docs/en/advanced/event.md
new file mode 100644
index 000000000..3b87d8a0d
--- /dev/null
+++ b/packages/artplayer-vitepress/docs/en/advanced/event.md
@@ -0,0 +1,712 @@
+# 实例事件
+
+播放器的事件分为两种,一种视频的 `原生事件` (前缀 `video:`),另外一种是 `自定义事件`
+
+监听事件:
+
+▶ Run Code
+
+```js{6}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+art.on('video:canplay', () => {
+ console.info('video:canplay');
+});
+```
+
+只监听一次事件:
+
+▶ Run Code
+
+```js{6}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+art.once('video:canplay', () => {
+ console.info('video:canplay');
+});
+```
+
+手动触发事件:
+
+▶ Run Code
+
+```js{6}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+art.emit('focus');
+```
+
+移除事件:
+
+▶ 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 全部事件请参考以下地址:
+
+[artplayer/types/events.d.ts](https://github.com/zhw2590582/ArtPlayer/blob/master/packages/artplayer/types/events.d.ts)
+
+:::
+
+## `ready`
+
+当播放器首次可以播放器时触发
+
+▶ Run Code
+
+```js{6}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+art.on('ready', () => {
+ console.info('ready');
+});
+```
+
+## `restart`
+
+当播放器切换地址后并可以播放时触发
+
+▶ 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', () => {
+ console.info('restart');
+});
+```
+
+## `pause`
+
+当播放器暂停时触发
+
+▶ Run Code
+
+```js{6}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+art.on('pause', () => {
+ console.info('pause');
+});
+```
+
+## `play`
+
+当播放器播放时触发
+
+▶ Run Code
+
+```js{6}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+art.on('play', () => {
+ console.info('play');
+});
+```
+
+## `hotkey`
+
+当播放器热键被按下时触发
+
+▶ 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`
+
+当播放器销毁时触发
+
+▶ 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');
+});
+```
+
+## `url`
+
+当视频地址变化时触发
+
+▶ 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?t=0'
+});
+
+art.on('url', (url) => {
+ console.info('url', url);
+});
+```
+
+## `focus`
+
+当播放器获得焦点时触发
+
+▶ Run Code
+
+```js{6}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+art.on('focus', () => {
+ console.info('focus');
+});
+```
+
+## `blur`
+
+当播放器失去焦点时触发
+
+▶ Run Code
+
+```js{6}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+art.on('blur', () => {
+ console.info('blur');
+});
+```
+
+## `dblclick`
+
+当播放器被双击时触发
+
+▶ Run Code
+
+```js{6}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+art.on('dblclick', () => {
+ console.info('dblclick');
+});
+```
+
+## `click`
+
+当播放器被单击时触发
+
+▶ Run Code
+
+```js{6}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+art.on('click', () => {
+ console.info('click');
+});
+```
+
+## `error`
+
+当播放器加载视频发生错误时触发
+
+▶ 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`
+
+当播放器被鼠标移出或者移入时触发
+
+▶ Run Code
+
+```js{6}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+art.on('hover', (state) => {
+ console.info('hover', state);
+});
+```
+
+## `mousemove`
+
+当播放器被鼠标经过时触发
+
+▶ 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`
+
+当播放器尺寸变化时触发
+
+▶ Run Code
+
+```js{6}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+art.on('resize', () => {
+ console.info('resize');
+});
+```
+
+## `view`
+
+当播放器出现在视口时触发
+
+▶ Run Code
+
+```js{6}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+art.on('view', (state) => {
+ console.info('view', state);
+});
+```
+
+## `aspectRatio`
+
+当播放器长宽比变化时触发
+
+▶ 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`
+
+当播放器自动设置高度时触发
+
+▶ Run Code
+
+```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`
+
+当播放器自动设置尺寸时触发
+
+▶ 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`
+
+当播放器发生翻转时触发
+
+▶ 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`
+
+当播放器发生窗口全屏时触发
+
+▶ 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);
+});
+```
+
+## `fullscreenWeb`
+
+当播放器发生网页全屏时触发
+
+▶ 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`
+
+当播放器进入迷你模式时触发
+
+▶ 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`
+
+当播放器进入画中画时触发
+
+▶ 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`
+
+当播放器被截图时触发
+
+▶ 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`
+
+当播放器发生时间跳转时触发
+
+▶ 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`
+
+当播放器发生字幕偏移时触发
+
+▶ 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);
+});
+```
+
+## `subtitleUpdate`
+
+当字幕更新时触发
+
+▶ Run Code
+
+```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`
+
+当字幕加载时触发
+
+▶ 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', (url) => {
+ console.info('subtitleLoad', url);
+});
+```
+
+## `subtitleSwitch`
+
+当字幕切换时触发
+
+▶ Run Code
+
+```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`
+
+由于暂时缺少数据,播放已停止
+
diff --git a/packages/artplayer-vitepress/docs/en/advanced/plugin.md b/packages/artplayer-vitepress/docs/en/advanced/plugin.md
new file mode 100644
index 000000000..4578acb33
--- /dev/null
+++ b/packages/artplayer-vitepress/docs/en/advanced/plugin.md
@@ -0,0 +1,125 @@
+# 编写插件
+
+但你已经知道播放器的`属性`, `方法`和`事件`后,再编写插件是非常简单的事
+
+可以在实例化的时候加载插件的函数
+
+▶ 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);
+});
+```
+
+可以在实例化之后再加载插件的函数
+
+▶ 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);
+});
+```
+
+例如我想写一个在视频暂停后,显示一个图片广告的插件
+
+▶ 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'
+ })
+ ],
+});
+```
\ No newline at end of file
diff --git a/packages/artplayer-vitepress/docs/en/advanced/property.md b/packages/artplayer-vitepress/docs/en/advanced/property.md
new file mode 100644
index 000000000..3ba3543bc
--- /dev/null
+++ b/packages/artplayer-vitepress/docs/en/advanced/property.md
@@ -0,0 +1,910 @@
+# 实例属性
+
+这里的 `实例属性` 是指挂载在 `实例` 的 `一级属性`,比较常用
+
+## `play`
+
+- Type: `Function`
+
+播放视频
+
+▶ 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`
+
+暂停视频
+
+▶ 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`
+
+切换视频的播放和暂停
+
+▶ 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`
+
+销毁播放器,接受一个参数表示是否销毁后同时移除播放器的 `html`,默认为 `true`
+
+▶ Run Code
+
+```js{7}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+art.on('ready', () => {
+ art.destroy();
+});
+```
+
+## `seek`
+
+- Type: `Setter`
+- Parameter: `Number`
+
+视频时间跳转,单位秒
+
+▶ 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`
+
+视频时间快进,单位秒
+
+▶ 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`
+
+视频时间快退,单位秒
+
+▶ 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`
+
+设置和获取视频音量,范围在:`[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`
+
+设置和获取视频地址
+
+▶ 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';
+});
+```
+
+## `switchUrl`
+
+- Type: `Function`
+- Parameter: `String`
+
+设置视频地址,设置时和 `url` 类似,但会执行一些优化操作
+
+函数支持两个参数,第一个为新的视频地址,第二个为可选新的视频名字
+
+▶ 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);
+});
+```
+
+## `switchQuality`
+
+- Type: `Function`
+- Parameter: `String`
+
+设置视频画质地址,和 `switchUrl` 类似,但会带上之前的播放进度
+
+函数支持两个参数,第一个为新的视频地址,第二个为可选新的视频名字
+
+▶ 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`
+
+设置和获取视频是否静音
+
+▶ 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`
+
+设置和获取视频当前时间,设置时间时和 `seek` 类似,但它不会触发额外的事件
+
+▶ 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`
+
+获取视频时长
+
+▶ Run Code
+
+```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`
+
+下载当前视频帧的截图
+
+▶ Run Code
+
+```js{7}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+art.on('ready', () => {
+ art.screenshot();
+});
+```
+
+## `getDataURL`
+
+- Type: `Function`
+
+获取当前视频帧的截图的`base64`地址,返回的是一个 `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`
+
+获取当前视频帧的截图的`blob`地址,返回的是一个 `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`
+
+设置和获取播放器窗口全屏
+
+▶ Run Code
+
+```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`
+
+设置和获取播放器网页全屏
+
+▶ 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`
+
+设置和获取播放器画中画模式
+
+▶ 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 提示
+
+由于浏览器安全机制,触发画中画前,页面必须先存在交互(例如用户点击过页面)
+
+:::
+
+## `poster`
+
+- Type: `Setter/Getter`
+- Parameter: `String`
+
+设置和获取视频海报,只有在视频播放前才能看到海报效果
+
+▶ 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`
+
+设置和获取播放器迷你模式
+
+▶ 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`
+
+获取视频是否正在播放中
+
+▶ 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);
+});
+```
+
+## `autoSize`
+
+- Type: `Setter/Getter`
+- Parameter: `Boolean`
+
+设置视频是否自适应尺寸,设置为 `true` 之后它会只执行一次
+
+▶ Run Code
+
+```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`
+
+获取播放器的尺寸和坐标信息
+
+▶ 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 提示
+
+尺寸和坐标信息是通过 `getBoundingClientRect` 获取的
+
+:::
+
+## `flip`
+
+- Type: `Setter/Getter`
+- Parameter: `String`
+
+设置和获取播放器翻转,支持`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`
+
+设置和获取播放器播放速度
+
+▶ 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`
+
+设置和获取播放器长宽比
+
+▶ 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);
+});
+```
+
+## `loop`
+
+- Type: `Setter/Getter`
+- Parameter: `Array`
+
+设置和获取区间循序播放,单位秒
+
+▶ Run Code
+
+```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` 之后它会只执行一次
+
+▶ Run Code
+
+```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 元素的属性
+
+▶ 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'));
+});
+```
+
+## `title`
+
+- Type: `Setter/Getter`
+- Parameter: `String`
+
+动态获取和设置播放器标题
+
+▶ Run Code
+
+```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`
+
+动态获取和设置视频类型
+
+▶ 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`
+
+动态获取和设置播放器主题颜色
+
+▶ 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`
+
+开启隔空播放
+
+▶ Run Code
+
+```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` 事件使用
+
+▶ Run Code
+
+```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` 事件使用
+
+▶ 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`
+
+`DOM` 事件的代理函数,实质上代理了 `addEventListener` 和 `removeEventListener`, 当使用 `proxy` 来处理事件,播放器销毁时也会自动销毁该事件
+
+▶ Run Code
+
+```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`,但被查询的对象局限于当前播放器内,可以避免同类名的错误
+
+▶ 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`
+
+快捷返回播放器的 `video` 元素
+
+▶ Run Code
+
+```js{6}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+
+console.info(art.video);
+```
\ No newline at end of file
diff --git a/packages/artplayer-vitepress/docs/en/index.md b/packages/artplayer-vitepress/docs/en/index.md
index 3285b6cc7..f03629a54 100644
--- a/packages/artplayer-vitepress/docs/en/index.md
+++ b/packages/artplayer-vitepress/docs/en/index.md
@@ -1 +1,270 @@
-# WIP...
\ No newline at end of file
+# Install
+
+## Install
+
+::: code-group
+
+```bash [npm]
+npm install artplayer
+```
+
+```bash [yarn]
+yarn add artplayer
+```
+
+```bash [pnpm]
+pnpm 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
+```
+
+:::
+
+## 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]
+
+
+ ArtPlayer Demo
+
+
+
+
+
+
+
+```
+
+:::
+
+::: 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]
+
+
+
+
+
+```
+
+```vue [app.vue]
+
+
+
+
+
+```
+
+:::
+
+::: 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
;
+}
+```
+
+```jsx [app.jsx]
+import React from 'react';
+import Artplayer from './ArtPlayer.jsx';
+
+function App() {
+ return (
+
+
console.info(art)}
+ />
+
+ );
+}
+
+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,
+ }
+ }
+}
+```
\ No newline at end of file
diff --git a/packages/artplayer-vitepress/docs/en/library/dash.md b/packages/artplayer-vitepress/docs/en/library/dash.md
new file mode 100644
index 000000000..fca6eb270
--- /dev/null
+++ b/packages/artplayer-vitepress/docs/en/library/dash.md
@@ -0,0 +1,36 @@
+# dash.js
+
+👉 [https://github.com/Dash-Industry-Forum/dash.js](https://github.com/Dash-Industry-Forum/dash.js)
+
+
+ ▶ Run Code
+
+
+```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);
+});
+```
\ No newline at end of file
diff --git a/packages/artplayer-vitepress/docs/en/library/flv.md b/packages/artplayer-vitepress/docs/en/library/flv.md
new file mode 100644
index 000000000..1cbf17a8f
--- /dev/null
+++ b/packages/artplayer-vitepress/docs/en/library/flv.md
@@ -0,0 +1,37 @@
+# flv.js
+
+👉 [https://github.com/Bilibili/flv.js](https://github.com/Bilibili/flv.js)
+
+
+ ▶ Run Code
+
+
+```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);
+});
+```
\ No newline at end of file
diff --git a/packages/artplayer-vitepress/docs/en/library/hls.md b/packages/artplayer-vitepress/docs/en/library/hls.md
new file mode 100644
index 000000000..8c2dda210
--- /dev/null
+++ b/packages/artplayer-vitepress/docs/en/library/hls.md
@@ -0,0 +1,39 @@
+# hls.js
+
+👉 [https://github.com/video-dev/hls.js](https://github.com/video-dev/hls.js)
+
+
+ ▶ Run Code
+
+
+```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);
+});
+```
\ No newline at end of file
diff --git a/packages/artplayer-vitepress/docs/en/plugin/ads.md b/packages/artplayer-vitepress/docs/en/plugin/ads.md
new file mode 100644
index 000000000..56af13fa9
--- /dev/null
+++ b/packages/artplayer-vitepress/docs/en/plugin/ads.md
@@ -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]
+
+```
+
+:::
+
+## 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
+```
+
+:::
+
+## 使用
+
+
+ ▶ Run Code
+
+
+```js
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ autoSize: true,
+ fullscreen: true,
+ fullscreenWeb: true,
+ plugins: [
+ artplayerPluginAds({
+ // html广告,假如是视频广告则忽略该值
+ html: ' ',
+
+ // 视频广告的地址
+ 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);
+});
+```
diff --git a/packages/artplayer-vitepress/docs/en/plugin/control-ui.md b/packages/artplayer-vitepress/docs/en/plugin/control-ui.md
new file mode 100644
index 000000000..d205f6d9b
--- /dev/null
+++ b/packages/artplayer-vitepress/docs/en/plugin/control-ui.md
@@ -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]
+
+```
+
+:::
+
+## 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
+```
+
+:::
+
+## 使用
+
+
+ ▶ Run Code
+
+
+```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`
+
+是否启用新的控制器皮肤
+
+
+ ▶ Run Code
+
+
+```js
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ fullscreen: true,
+ fullscreenWeb: true,
+ controls: [
+ {
+ position: 'right',
+ html: 'Switch UI ',
+ click: function () {
+ const { enable } = art.plugins.artplayerPluginControl;
+ art.plugins.artplayerPluginControl.enable = !enable;
+ },
+ },
+ ],
+ plugins: [
+ artplayerPluginControl(),
+ ],
+});
+```
\ No newline at end of file
diff --git a/packages/artplayer-vitepress/docs/en/plugin/hls-quality.md b/packages/artplayer-vitepress/docs/en/plugin/hls-quality.md
new file mode 100644
index 000000000..e7adae9b2
--- /dev/null
+++ b/packages/artplayer-vitepress/docs/en/plugin/hls-quality.md
@@ -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]
+
+```
+
+:::
+
+## 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
+```
+
+:::
\ No newline at end of file
diff --git a/packages/artplayer-vitepress/docs/en/plugin/iframe.md b/packages/artplayer-vitepress/docs/en/plugin/iframe.md
new file mode 100644
index 000000000..393ff7135
--- /dev/null
+++ b/packages/artplayer-vitepress/docs/en/plugin/iframe.md
@@ -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]
+
+```
+
+:::
+
+## `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]
+
+
+
+ ArtPlayer
+
+
+
+
+
+
+
+
+```
+
+```html [iframe.html]
+
+
+
+ ArtPlayer
+
+
+
+
+
+
+
+
+
+
+```
+
+:::
+
+## `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]
+
+
+
+
+ ArtPlayer
+
+
+
+
+
+
+
+
+
+
+```
+
+```html [iframe.html]
+
+
+
+
+ ArtPlayer
+
+
+
+
+
+
+
+
+
+
+
+```
+
+:::
\ No newline at end of file
diff --git a/packages/artplayer-vitepress/docs/en/start/component.md b/packages/artplayer-vitepress/docs/en/start/component.md
new file mode 100644
index 000000000..9f83f1d62
--- /dev/null
+++ b/packages/artplayer-vitepress/docs/en/start/component.md
@@ -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` 或者 `广告` 等等
+
+▶ 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);
+ },
+ },
+ ],
+});
+
+console.info(art.layers.potser);
+```
+
+也可以实例化之后添加一个层
+
+▶ 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);
+ },
+});
+
+console.info(art.layers.potser);
+```
+
+## `controls`
+
+实例化时添加一个控制器
+
+:::warning controls 还有三个额外的选项
+
+- `position`: `left` 和 `right` 控制控制器出现的左右位置
+- `selector`: 快速创建选择列表的对象数组
+- `onSelect`: 选择列表的元素被点击时触发的函数
+
+:::
+
+▶ 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;
+ },
+ },
+ ],
+});
+
+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`
+
+实例化时添加一个右键菜单
+
+▶ 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;
+ },
+ },
+ ],
+});
+
+console.info(art.contextmenu['your-menu']);
+```
+
+也可以实例化之后添加一个右键菜单
+
+▶ 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;
+ },
+});
+
+console.info(art.contextmenu['your-menu']);
+```
\ No newline at end of file
diff --git a/packages/artplayer-vitepress/docs/en/start/option.md b/packages/artplayer-vitepress/docs/en/start/option.md
new file mode 100644
index 000000000..2a8e9f14a
--- /dev/null
+++ b/packages/artplayer-vitepress/docs/en/start/option.md
@@ -0,0 +1,1204 @@
+# Option
+
+## `container`
+
+- Type: `String, Element`
+- Default: `#artplayer`
+
+The `DOM` container attached to the player
+
+▶ 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 initialize the size of container elements, such as:
+
+```css{2-3}
+.artplayer-app {
+ width: 400px;
+ height: 300px;
+}
+```
+
+:::warning Tip
+
+Of all options, only `container` is required
+
+:::
+
+## `url`
+
+- Type: `String`
+- Default: `''`
+
+Video source address
+
+▶ Run Code
+
+```js{3}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+});
+```
+
+Sometimes the `url` address is not known so quickly. At this time, 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 Tip
+
+Three video file formats are supported by default: `.mp4`, `.ogg`, and `.webm`
+
+If you need to play `.m3u8` or `.flv` or other formats, please refer to the `Libraries` on the left
+
+:::
+
+
+## `id`
+
+- Type: `String`
+- Default: `''`
+
+The unique identifier of the player, currently only used for `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, which is triggered when the player is initialized successfully and the video can be played, just like 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 Tip
+
+The `this` in the callback function is the player instance, but if the callback function uses the arrow function, the `this` will not point to the player instance
+
+:::
+
+## `poster`
+
+- Type: `String`
+- Default: `''`
+
+Video posters will only appear when the player is initialized and not played
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ poster: '/assets/sample/poster.jpg',
+});
+```
+
+## `title`
+
+- Type: `String`
+- Default: `''`
+
+Video title, which currently appears in `video screenshot` and `mini mode`
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ title: 'your-video-title',
+ screenshot: true,
+});
+```
+
+## `theme`
+
+- Type: `String`
+- Default: `#f00`
+
+The player theme color is currently used on the `progress bar` and `highlighted element`
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ theme: '#ffad00',
+});
+```
+
+## `volume`
+
+- Type: `Number`
+- Default: `0.7`
+
+Default volume of player
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ volume: 0.5,
+});
+```
+
+:::warning Tip
+
+The player will cache the size of the last volume, and the player will read the cache value at the next initialization (such as refreshing the page)
+
+:::
+
+## `isLive`
+
+- Type: `Boolean`
+- Default: `false`
+
+When using live mode, the progress bar and playback time will be hidden
+
+▶ 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 mute 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 play automatically
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ autoplay: true,
+ muted: true,
+});
+```
+
+:::warning Tip
+
+If you want to enter the page by default to automatically play the video, `muted` must be `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`
+
+The size of the player will fill the entire `container` size by default, so black edges often appear. This value can automatically adjust the size of the player to hide the black edges, similar to the `object-fit: contain` of `css`
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ autoSize: true,
+});
+```
+
+## `autoMini`
+
+- Type: `Boolean`
+- Default: `false`
+
+When the player scrolls outside the viewport, it automatically enters the `mini mode`
+
+▶ 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 play in a loop
+
+▶ 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 `Setting` and `Contextmenu`
+
+▶ 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 will appear in the `Setting` and `Contextmenu`
+
+▶ 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 will appear in the `Setting` and `Contextmenu`
+
+▶ 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 `video 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 Tip
+
+Due to the browser security policy, if the video source address and website are cross-domain, the screenshot may fail
+
+:::
+
+## `setting`
+
+- Type: `Boolean`
+- Default: `false`
+
+Whether to display the switch button of `Setting` 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 shortcut keys
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ hotkey: true,
+});
+```
+
+| Hotkeys | Sescribe |
+| ------- | ----------------- |
+| `↑` | Volume Up |
+| `↓` | Volume Down |
+| `←` | Fast forward |
+| `→` | Fast rewind |
+| `space` | Toggle play/pause |
+
+:::warning Tip
+
+These shortcut keys will only take effect after the player gets the focus (such as clicking the player)
+
+:::
+
+## `pip`
+
+- Type: `Boolean`
+- Default: `false`
+
+Whether to display the `picture in picture` switch 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 there are multiple players in the page at the same time, can only one player play
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ mutex: true,
+});
+```
+
+## `fullscreen`
+
+- Type: `Boolean`
+- Default: `false`
+
+Whether to display the player `window full screen` 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 `full screen web page` 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, with the range of `[-5s, 5s]`, appears in the `Settings`
+
+▶ 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`
+
+Mini progress bar, 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 the `SSR` mount mode is useful if you want to render the `HTML` required by the player in advance before the player is mounted
+
+You can access the `HTML` required by the player through `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 the `playsInline` mode on the mobile end
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ playsInline: true,
+});
+```
+
+## `layers`
+
+- Type: `Array`
+- Default: `[]`
+
+Initialize the customized `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 Please refer to the following address for `Component`:
+
+[/start/component.html](/start/component.html)
+
+:::
+
+## `settings`
+
+- Type: `Array`
+- Default: `[]`
+
+Initialize the customized `Setting`
+
+▶ 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 Please refer to the following address for `Setting`
+
+[/start/setting.html](/start/setting.html)
+
+:::
+
+## `contextmenu`
+
+- Type: `Array`
+- Default: `[]`
+
+初始化自定义的 `右键菜单`
+
+▶ 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 `组件配置` 请参考以下地址:
+
+[/start/component.html](/start/component.html)- Type:
+
+:::
+
+## `controls`
+
+- Type: `Array`
+- Default: `[]`
+
+初始化自定义的底部 `控制栏`
+
+▶ 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 `组件配置` 请参考以下地址:
+
+[/start/component.html](/start/component.html)
+
+:::
+
+## `quality`
+
+- Type: `Array`
+- Default: `[]`
+
+是否在底部控制栏里显示 `画质选择` 列表
+
+| 属性 | 类型 | 描述 |
+| --------- | --------- | -------- |
+| `default` | `Boolean` | 默认画质 |
+| `html` | `String` | 画质名字 |
+| `url` | `String` | 画质地址 |
+
+▶ 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: `[]`
+
+在进度条上显示 `高亮信息`
+
+| 属性 | 类型 | 描述 |
+| ------ | -------- | ------------------ |
+| `time` | `Number` | 高亮时间(单位秒) |
+| `text` | `String` | 高亮文本 |
+
+▶ 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: `[]`
+
+初始化自定义的 `插件`
+
+▶ 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],
+});
+```
+
+## `whitelist`
+
+- Type: `Array`
+- Default: `[]`
+
+因为不同的移动设备存在多种差异和限制,有时候你希望在某些移动设备上不使用本播放器,而是直接使用原生的功能时,可以通过该选项控制
+
+白名单是一个数组类型,分别与 `window.navigator.userAgent` 进行匹配,只要其中一项匹配成功则启用播放器
+
+支持 `字符串` 匹配, `函数` 匹配, `正则` 匹配
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ whitelist: [(ua) => /iPhone OS 11/gi.test(ua)],
+ // whitelist: [/iPhone OS 11/gi],
+ // whitelist: ['iPhone OS 11'],
+});
+```
+
+:::warning 提示
+
+假如该选项不填,则默认使用本播放器
+
+:::
+
+## `thumbnails`
+
+- Type: `Object`
+- Default: `{}`
+
+在进度条上设置 `预览图`
+
+| 属性 | 类型 | 描述 |
+| -------- | -------- | ---------- |
+| `url` | `String` | 预览图地址 |
+| `number` | `Number` | 预览图数量 |
+| `column` | `Number` | 预览图列数 |
+| `width` | `Number` | 预览图宽度 |
+| `height` | `Number` | 预览图高度 |
+
+▶ Run Code
+
+```js{4-8}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ thumbnails: {
+ url: '/assets/sample/thumbnails.png',
+ number: 100,
+ column: 10,
+ },
+});
+```
+
+:::warning 在线生成预览图
+
+[artplayer-tool-thumbnail](https://artplayer.org/?libs=./uncompiled/artplayer-tool-thumbnail/index.js&example=thumbnail)
+
+:::
+
+## `subtitle`
+
+- Type: `Object`
+- Default: `{}`
+
+设置视频的字幕,支持字幕格式:`vtt`, `srt`, `ass`
+
+| 属性 | 类型 | 描述 |
+| ---------- | -------- | ---------------------------------- |
+| `url` | `String` | 字幕地址 |
+| `type` | `String` | 字幕类型,可选 `vtt`, `srt`, `ass` |
+| `style` | `Object` | 字幕样式 |
+| `encoding` | `String` | 字幕编码,默认 `utf-8` |
+
+▶ 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',
+ style: {
+ color: '#03A9F4',
+ 'font-size': '30px',
+ },
+ },
+});
+```
+
+## `moreVideoAttr`
+
+- Type: `Object`
+- Default: `{'controls': false,'preload': 'metadata'}`
+
+更多视频属性,这些属性将直接写入视频元素里
+
+▶ 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: `{}`
+
+用于替换默认图标,支持 `Html` 字符串和 `HTMLElement`
+
+▶ Run Code
+
+```js{4-7}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ icons: {
+ loading: ' ',
+ state: ' ',
+ },
+});
+```
+
+:::warning 全部图标的定义
+
+[artplayer/types/icons.d.ts](https://github.com/zhw2590582/ArtPlayer/blob/master/packages/artplayer/types/icons.d.ts)
+
+:::
+
+## `type`
+
+- Type: `String`
+- Default: `''`
+
+用于指明视频的格式,需要配合 `customType` 一起使用,默认视频的格式就是视频地址的后缀(如 `.m3u8`, `.mkv`, `.ts`),但有时候视频地地址没有正确的后缀,所以需要特别指明
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.m3u8',
+ type: 'm3u8',
+});
+```
+
+:::warning 后缀的识别
+
+播放器只能解析这种后缀:`/assets/sample/video.m3u8`
+
+但无法解析这种后缀:`/assets/sample/video?type=m3u8`
+
+所以假如你使用了 `customType`,最好同时要指明 `type`
+
+:::
+
+## `customType`
+
+- Type: `Object`
+- Default: `{}`
+
+通过视频的 `type` 进行匹配,把视频解码权交给第三方程序进行处理,处理的函数能接收三个参数
+
+- `video` : 视频 `DOM` 元素
+- `url` : 视频地址
+- `art` : 当前实例
+
+▶ 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()`
+
+默认显示语言,目前支持:`en`, `zh-cn`, `zh-tw`, `cs`, `pl`, `es`, `fa`
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ lang: 'en',
+});
+```
+
+## `i18n`
+
+- Type: `Object`
+- Default: `{}`
+
+自定义 `i18n` 配置,该配置会和自带的 `i18n` 进行深度合并
+
+新增你的语言:
+
+▶ 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'
+ },
+ },
+});
+```
+
+修改现有的语言
+
+▶ 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 i18n 写法参考
+
+[artplayer/types/i18n.d.ts](https://github.com/zhw2590582/ArtPlayer/blob/master/packages/artplayer/types/i18n.d.ts)
+
+:::
+
+## `lock`
+
+- Type: `Boolean`
+- Default: `false`
+
+是否在移动端显示一个 `锁定按钮` ,用于隐藏底部 `控制栏`
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ lock: true,
+});
+```
+
+## `fastForward`
+
+- Type: `Boolean`
+- Default: `false`
+
+是否在移动端添加长按视频快进功能
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ fastForward: true,
+});
+```
+
+## `autoPlayback`
+
+- Type: `Boolean`
+- Default: `false`
+
+是否使用自动 `回放功能`
+
+▶ Run Code
+
+```js{4-5}
+var art = new Artplayer({
+ container: '.artplayer-app',gb
+ url: '/assets/sample/video.mp4',
+ id: 'your-url-id',
+ autoPlayback: true,
+});
+```
+
+:::warning 提示
+
+因为播放器默认使用 `url` 作为 `key` 来缓存播放进度的
+
+但假如你的同一个视频的 `url` 是不同的话,那么你需要使用 `id` 来标识视频的唯一 `key`
+
+:::
+
+## `autoOrientation`
+
+- Type: `Boolean`
+- Default: `false`
+
+是否在移动端的网页全屏时,根据视频尺寸和视口尺寸,旋转播放器
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ autoOrientation: true,
+});
+```
+
+## `airplay`
+
+- Type: `Boolean`
+- Default: `false`
+
+是否显示 `airplay` 按钮,当前只有部分浏览器支持该功能
+
+▶ Run Code
+
+```js{4}
+var art = new Artplayer({
+ container: '.artplayer-app',
+ url: '/assets/sample/video.mp4',
+ airplay: true,
+});
+```
\ No newline at end of file
diff --git a/packages/artplayer-vitepress/docs/en/start/setting.md b/packages/artplayer-vitepress/docs/en/start/setting.md
new file mode 100644
index 000000000..d90826c6b
--- /dev/null
+++ b/packages/artplayer-vitepress/docs/en/start/setting.md
@@ -0,0 +1,214 @@
+# 设置面板
+
+需先打开设置面板,播放器默认自带四个设置项:`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,
+});
+```
+
+## 选择列表
+
+| 属性 | 类型 | 描述 |
+| ---------- | ------------------- | --------------- |
+| `html` | `String`, `Element` | 元素的 DOM 元素 |
+| `icon` | `String`, `Element` | 元素的图标 |
+| `selector` | `Array` | 元素列表 |
+| `onSelect` | `Function` | 元素点击事件 |
+| `width` | `Number` | 列表宽度 |
+| `default` | `Boolean` | 是否默认选中 |
+| `tooltip` | `String` | 提示文本 |
+
+▶ 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;
+ },
+ },
+ ],
+});
+```
+
+## 列表嵌套
+
+▶ 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;
+ },
+ },
+ ],
+ },
+ ],
+});
+```
+
+## 切换按钮
+
+| 属性 | 类型 | 描述 |
+| ---------- | ------------------- | --------------- |
+| `html` | `String`, `Element` | 元素的 DOM 元素 |
+| `icon` | `String`, `Element` | 元素的图标 |
+| `switch` | `Boolean` | 按钮默认状态 |
+| `onSwitch` | `Function` | 按钮切换事件 |
+| `tooltip` | `String` | 提示文本 |
+
+▶ 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;
+ },
+ },
+ ],
+});
+```
+
+## 范围滑块
+
+| 属性 | 类型 | 描述 |
+| ---------- | ------------------- | ---------------- |
+| `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];
+```
+
+▶ 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 + 'x';
+ },
+ },
+ ],
+});
+```
diff --git a/packages/artplayer-vitepress/docs/start/option.md b/packages/artplayer-vitepress/docs/start/option.md
index f9d69cea3..f592bfdd3 100644
--- a/packages/artplayer-vitepress/docs/start/option.md
+++ b/packages/artplayer-vitepress/docs/start/option.md
@@ -170,7 +170,7 @@ var art = new Artplayer({
- Type: `String`
- Default: `#f00`
-播放器主题颜色,目前作用于 `进度条` 和 `高亮元素` 上
+播放器主题颜色,目前用于 `进度条` 和 `高亮元素` 上
▶ Run Code
@@ -429,8 +429,8 @@ var art = new Artplayer({
| ------- | ------------- |
| `↑` | 增加音量 |
| `↓` | 降低音量 |
-| `←` | 快进 5 秒 |
-| `→` | 快退 5 秒 |
+| `←` | 视频快进 |
+| `→` | 视频快退 |
| `space` | 切换播放/暂停 |
:::warning 提示