feat: add link to LLMs resource in README

Implement code changes to enhance functionality and improve performance

chore: add initial empty files for artplayer.d.ts, llm.txt, and build-llm.js

Refactor Artplayer examples for improved readability and consistency

- Updated mobile.js to enhance code formatting and structure.
- Refined mpegts.js for better readability and consistency in function usage.
- Improved multiple.subtitles.js with clearer structure and modern syntax.
- Enhanced setting.test.js for better organization and clarity in settings management.
- Streamlined thumbnail.js for consistent formatting.
- Updated vast.js for improved readability and consistency in plugin usage.
- Refined vtt.thumbnail.js for better code organization.
- Enhanced webtorrent.js for improved readability and consistency in async handling.
- Updated TypeScript definitions for various plugins to maintain consistency in export statements.
- Adjusted package.json linting script to include TypeScript files in the docs/assets/ts directory.
- Removed outdated types.test.js file to clean up the test suite.

refactor: remove outdated documentation files and update translation script

- Deleted i18n.md and option.md documentation files as they are no longer needed.
- Updated trans-docs.js to streamline the translation process and improve error handling.
- Adjusted plugin template package.json for consistency.
- Changed console.log to console.warn in various test files for better logging practices.

feat: add danmaku plugin documentation and i18n support

- Introduced comprehensive documentation for the Danmaku library, including installation, usage examples, and configuration options.
- Added language settings documentation, highlighting the need for manual language imports starting from version 5.1.0.
- Updated basic options documentation with detailed descriptions and examples for player configuration options.

Refactor documentation for clarity and consistency; update translation script to handle large Markdown chunks

refactor: improve documentation clarity and consistency across various components

- Updated property descriptions in layers.md and setting.md for better readability.
- Enhanced language and structure in index.md, danmuku.md, i18n.md, and option.md to ensure uniformity.
- Corrected minor grammatical errors and improved phrasing throughout the documentation.
- Ensured consistent formatting in tables and code snippets for better user experience.

feat: add build script for generating llm.txt and update translation source directories

Refactor build-llm.js to improve concurrency and enhance prompt clarity

- Introduced a MAX_CONCURRENT_REQUESTS constant to manage concurrent API requests.
- Added a runConcurrent function to handle task execution with a limit on concurrent requests.
- Updated the askDeepSeek function to include more informative logging.
- Enhanced prompts for summarizing documentation, TypeScript definitions, and JavaScript examples to improve clarity and maintain formatting.
- Modified the main function to fetch files concurrently and streamline the summarization process.

Increase text chunk size from 5000 to 8000 in summarizeSection function for improved processing of larger files.

fix: update lint script to include .js files in the scripts directory
This commit is contained in:
Harvey Zhao committed 2025-10-08 12:20:12 +08:00
1 parent 987795503b
commit 0a9aadf543
71 files changed
+10851 -1945

No files matched your search

+34 -34
View File
@@ -1,48 +1,48 @@
// npm i artplayer-plugin-ads
// import artplayerPluginAds from 'artplayer-plugin-ads';
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">',
const 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',
// 视频广告的地址
video: '/assets/sample/test1.mp4',
// 广告跳转网址,为空则不跳转
url: 'http://artplayer.org',
// 广告跳转网址,为空则不跳转
url: 'http://artplayer.org',
// 必须观看的时长,期间不能被跳过,单位为秒
// 当该值大于或等于totalDuration时,不能提前关闭广告
// 当该值等于或小于0时,则随时都可以关闭广告
playDuration: 5,
// 必须观看的时长,期间不能被跳过,单位为秒
// 当该值大于或等于totalDuration时,不能提前关闭广告
// 当该值等于或小于0时,则随时都可以关闭广告
playDuration: 5,
// 广告总时长,单位为秒
totalDuration: 10,
// 广告总时长,单位为秒
totalDuration: 10,
// 多语言支持
i18n: {
close: '关闭广告',
countdown: '%s秒',
detail: '查看详情',
canBeClosed: '%s秒后可关闭广告',
},
}),
],
});
// 多语言支持
i18n: {
close: '关闭广告',
countdown: '%s秒',
detail: '查看详情',
canBeClosed: '%s秒后可关闭广告',
},
}),
],
})
// 广告被点击
art.on('artplayerPluginAds:click', (ads) => {
console.info('广告被点击', ads);
});
console.info('广告被点击', ads)
})
// 广告被跳过
art.on('artplayerPluginAds:skip', (ads) => {
console.info('广告被跳过', ads);
});
console.info('广告被跳过', ads)
})
+13 -13
View File
@@ -1,16 +1,16 @@
// npm i artplayer-plugin-ambilight
// import artplayerPluginAmbilight from 'artplayer-plugin-ambilight';
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
autoSize: true,
plugins: [
artplayerPluginAmbilight({
blur: '50px',
opacity: 1,
frequency: 10,
duration: 0.3,
}),
],
});
const art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
autoSize: true,
plugins: [
artplayerPluginAmbilight({
blur: '50px',
opacity: 1,
frequency: 10,
duration: 0.3,
}),
],
})
+52 -49
View File
@@ -1,58 +1,61 @@
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/steve-jobs.mp4',
autoSize: true,
fullscreen: true,
fullscreenWeb: true,
moreVideoAttr: {
// crossOrigin: 'anonymous',
},
plugins: [
artplayerPluginAsr({
length: 2,
interval: 40,
sampleRate: 16000,
autoHideTimeout: 10000,
// Use your AI tool to convert pcm into subtitles
onAudioChunk: ({ pcm }) => startAsr(pcm),
}),
]
});
const art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/steve-jobs.mp4',
autoSize: true,
fullscreen: true,
fullscreenWeb: true,
moreVideoAttr: {
// crossOrigin: 'anonymous',
},
plugins: [
artplayerPluginAsr({
length: 2,
interval: 40,
sampleRate: 16000,
autoHideTimeout: 10000,
// Use your AI tool to convert pcm into subtitles
onAudioChunk: ({ pcm }) => startAsr(pcm),
}),
],
})
var ws = null;
var loading = false;
let ws = null
let loading = false
function stopAsr() {
try {
ws.send(JSON.stringify({ type: 'end' }));
ws.close();
} catch {}
ws = null;
loading = false;
try {
ws.send(JSON.stringify({ type: 'end' }))
ws.close()
}
catch {}
ws = null
loading = false
}
async function startAsr(buffer) {
if (loading) return;
if (!ws) {
loading = true;
const api = 'https://api.aimu.app/asr/tencent?engine_model_type=16k_en';
const { url } = await (await fetch(api)).json();
ws = new WebSocket(url);
ws.binaryType = 'arraybuffer';
ws.onmessage = (event) => {
const { code, result, message } = JSON.parse(event.data);
if (code === 0) {
art.plugins.artplayerPluginAsr.append(result?.voice_text_str);
} else {
console.error(code, message);
stopAsr();
}
};
loading = false;
}
if (ws?.readyState === WebSocket.OPEN) {
ws.send(buffer);
if (loading)
return
if (!ws) {
loading = true
const api = 'https://api.aimu.app/asr/tencent?engine_model_type=16k_en'
const { url } = await (await fetch(api)).json()
ws = new WebSocket(url)
ws.binaryType = 'arraybuffer'
ws.onmessage = (event) => {
const { code, result, message } = JSON.parse(event.data)
if (code === 0) {
art.plugins.artplayerPluginAsr.append(result?.voice_text_str)
}
else {
console.error(code, message)
stopAsr()
}
}
loading = false
}
if (ws?.readyState === WebSocket.OPEN) {
ws.send(buffer)
}
}
art.on('destroy', stopAsr);
art.on('destroy', stopAsr)
+9 -9
View File
@@ -1,12 +1,12 @@
// npm i artplayer-plugin-auto-thumbnail
// import artplayerPluginAutoThumbnail from 'artplayer-plugin-auto-thumbnail';
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
plugins: [
artplayerPluginAutoThumbnail({
//
}),
],
});
const art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
plugins: [
artplayerPluginAutoThumbnail({
//
}),
],
})
+27 -27
View File
@@ -1,30 +1,30 @@
// npm i artplayer-proxy-canvas
// import artplayerProxyCanvas from 'artplayer-proxy-canvas';
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
poster: '/assets/sample/poster.jpg',
volume: 0.5,
autoplay: false,
autoSize: false,
screenshot: true,
setting: true,
loop: true,
flip: true,
pip: true,
playbackRate: true,
aspectRatio: true,
fullscreen: true,
fullscreenWeb: true,
miniProgressBar: true,
autoPlayback: true,
autoOrientation: true,
thumbnails: {
url: '/assets/sample/thumbnails.png',
number: 60,
column: 10,
scale: 0.85,
},
proxy: artplayerProxyCanvas(),
});
const art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
poster: '/assets/sample/poster.jpg',
volume: 0.5,
autoplay: false,
autoSize: false,
screenshot: true,
setting: true,
loop: true,
flip: true,
pip: true,
playbackRate: true,
aspectRatio: true,
fullscreen: true,
fullscreenWeb: true,
miniProgressBar: true,
autoPlayback: true,
autoOrientation: true,
thumbnails: {
url: '/assets/sample/thumbnails.png',
number: 60,
column: 10,
scale: 0.85,
},
proxy: artplayerProxyCanvas(),
})
+25 -25
View File
@@ -1,28 +1,28 @@
// npm i artplayer-plugin-chapter
// import artplayerPluginChapter from 'artplayer-plugin-chapter';
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
autoSize: true,
fullscreen: true,
fullscreenWeb: true,
miniProgressBar: true,
autoOrientation: true,
thumbnails: {
url: '/assets/sample/thumbnails.png',
number: 60,
column: 10,
},
plugins: [
artplayerPluginChapter({
chapters: [
{ start: 0, end: 18, title: 'One more chance' },
{ start: 18, end: 36, title: '谁でもいいはずなのに' },
{ start: 36, end: 54, title: '夏の想い出がまわる' },
{ start: 54, end: 72, title: 'こんなとこにあるはずもないのに' },
{ start: 72, end: Infinity, title: '终わり' },
]
}),
],
});
const art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
autoSize: true,
fullscreen: true,
fullscreenWeb: true,
miniProgressBar: true,
autoOrientation: true,
thumbnails: {
url: '/assets/sample/thumbnails.png',
number: 60,
column: 10,
},
plugins: [
artplayerPluginChapter({
chapters: [
{ start: 0, end: 18, title: 'One more chance' },
{ start: 18, end: 36, title: '谁でもいいはずなのに' },
{ start: 36, end: 54, title: '夏の想い出がまわる' },
{ start: 54, end: 72, title: 'こんなとこにあるはずもないのに' },
{ start: 72, end: Infinity, title: '终わり' },
],
}),
],
})
+12 -12
View File
@@ -1,15 +1,15 @@
// npm i artplayer-plugin-chromecast
// import artplayerPluginChromecast from 'artplayer-plugin-chromecast';
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
fullscreen: true,
fullscreenWeb: true,
plugins: [
artplayerPluginChromecast({
// sdk: '', // The URL of the Cast SDK
// mimeType: '', // The MIME type of the media
}),
],
});
const art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
fullscreen: true,
fullscreenWeb: true,
plugins: [
artplayerPluginChromecast({
// sdk: '', // The URL of the Cast SDK
// mimeType: '', // The MIME type of the media
}),
],
})
+48 -48
View File
@@ -2,53 +2,53 @@
// import artplayerPluginDanmuku from 'artplayer-plugin-danmuku';
// 使用文档 https://artplayer.org/document/plugin/danmuku.html
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
autoSize: true,
fullscreen: true,
fullscreenWeb: true,
autoOrientation: true,
plugins: [
artplayerPluginDanmuku({
danmuku: '/assets/sample/danmuku.xml',
const art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
autoSize: true,
fullscreen: true,
fullscreenWeb: true,
autoOrientation: true,
plugins: [
artplayerPluginDanmuku({
danmuku: '/assets/sample/danmuku.xml',
// 以下为非必填
speed: 5, // 弹幕持续时间,范围在[1 ~ 10]
margin: [10, '25%'], // 弹幕上下边距,支持像素数字和百分比
opacity: 1, // 弹幕透明度,范围在[0 ~ 1]
color: '#FFFFFF', // 默认弹幕颜色,可以被单独弹幕项覆盖
mode: 0, // 默认弹幕模式: 0: 滚动,1: 顶部,2: 底部
modes: [0, 1, 2], // 弹幕可见的模式
fontSize: 25, // 弹幕字体大小,支持像素数字和百分比
antiOverlap: true, // 弹幕是否防重叠
synchronousPlayback: false, // 是否同步播放速度
mount: undefined, // 弹幕发射器挂载点, 默认为播放器控制栏中部
heatmap: true, // 是否开启热力图
width: 512, // 当播放器宽度小于此值时,弹幕发射器置于播放器底部
points: [], // 热力图数据
filter: (danmu) => danmu.text.length <= 100, // 弹幕载入前的过滤器
beforeVisible: () => true, // 弹幕显示前的过滤器,返回 true 则可以发送
visible: true, // 弹幕层是否可见
emitter: true, // 是否开启弹幕发射器
maxLength: 200, // 弹幕输入框最大长度, 范围在[1 ~ 1000]
lockTime: 5, // 输入框锁定时间,范围在[1 ~ 60]
theme: 'dark', // 弹幕主题,支持 dark 和 light,只在自定义挂载时生效
OPACITY: {}, // 不透明度配置项
FONT_SIZE: {}, // 弹幕字号配置项
MARGIN: {}, // 显示区域配置项
SPEED: {}, // 弹幕速度配置项
COLOR: [], // 颜色列表配置项
// 以下为非必填
speed: 5, // 弹幕持续时间,范围在[1 ~ 10]
margin: [10, '25%'], // 弹幕上下边距,支持像素数字和百分比
opacity: 1, // 弹幕透明度,范围在[0 ~ 1]
color: '#FFFFFF', // 默认弹幕颜色,可以被单独弹幕项覆盖
mode: 0, // 默认弹幕模式: 0: 滚动,1: 顶部,2: 底部
modes: [0, 1, 2], // 弹幕可见的模式
fontSize: 25, // 弹幕字体大小,支持像素数字和百分比
antiOverlap: true, // 弹幕是否防重叠
synchronousPlayback: false, // 是否同步播放速度
mount: undefined, // 弹幕发射器挂载点, 默认为播放器控制栏中部
heatmap: true, // 是否开启热力图
width: 512, // 当播放器宽度小于此值时,弹幕发射器置于播放器底部
points: [], // 热力图数据
filter: danmu => danmu.text.length <= 100, // 弹幕载入前的过滤器
beforeVisible: () => true, // 弹幕显示前的过滤器,返回 true 则可以发送
visible: true, // 弹幕层是否可见
emitter: true, // 是否开启弹幕发射器
maxLength: 200, // 弹幕输入框最大长度, 范围在[1 ~ 1000]
lockTime: 5, // 输入框锁定时间,范围在[1 ~ 60]
theme: 'dark', // 弹幕主题,支持 dark 和 light,只在自定义挂载时生效
OPACITY: {}, // 不透明度配置项
FONT_SIZE: {}, // 弹幕字号配置项
MARGIN: {}, // 显示区域配置项
SPEED: {}, // 弹幕速度配置项
COLOR: [], // 颜色列表配置项
// 手动发送弹幕前的过滤器,返回 true 则可以发送,可以做存库处理
beforeEmit(danmu) {
return new Promise((resolve) => {
console.log(danmu);
setTimeout(() => {
resolve(true);
}, 1000);
});
},
}),
],
});
// 手动发送弹幕前的过滤器,返回 true 则可以发送,可以做存库处理
beforeEmit(danmu) {
return new Promise((resolve) => {
console.log(danmu)
setTimeout(() => {
resolve(true)
}, 1000)
})
},
}),
],
})
+16 -16
View File
@@ -4,19 +4,19 @@
// npm i @mediapipe/selfie_segmentation
// 把 node_modules/@mediapipe/selfie_segmentation 目录复制到你的项目下
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
autoSize: true,
fullscreen: true,
fullscreenWeb: true,
autoOrientation: true,
plugins: [
artplayerPluginDanmuku({
danmuku: '/assets/sample/danmuku.xml'
}),
artplayerPluginDanmukuMask({
solutionPath: '/assets/@mediapipe/selfie_segmentation',
}),
],
});
const art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
autoSize: true,
fullscreen: true,
fullscreenWeb: true,
autoOrientation: true,
plugins: [
artplayerPluginDanmuku({
danmuku: '/assets/sample/danmuku.xml',
}),
artplayerPluginDanmukuMask({
solutionPath: '/assets/@mediapipe/selfie_segmentation',
}),
],
})
+45 -43
View File
@@ -4,47 +4,49 @@
// import dashjs from 'dashjs';
// import artplayerPluginDashControl from 'artplayer-plugin-dash-control';
var art = new Artplayer({
container: '.artplayer-app',
url: 'https://media.axprod.net/TestVectors/v7-Clear/Manifest_1080p.mpd',
setting: true,
plugins: [
artplayerPluginDashControl({
quality: {
// Show qualitys in control
control: true,
// Show qualitys in setting
setting: true,
// Get the quality name from level
getName: (level) => level.height + 'P',
// I18n
title: 'Quality',
auto: 'Auto',
},
audio: {
// Show audios in control
control: true,
// Show audios in setting
setting: true,
// Get the audio name from track
getName: (track) => track.lang.toUpperCase(),
// I18n
title: 'Audio',
auto: 'Auto',
}
}),
],
customType: {
mpd: function playMpd(video, url, art) {
if (dashjs.supportsMediaSource()) {
if (art.dash) art.dash.destroy();
const dash = dashjs.MediaPlayer().create();
dash.initialize(video, url, art.option.autoplay);
art.dash = dash;
art.on('destroy', () => dash.destroy());
} else {
art.notice.show = 'Unsupported playback format: mpd';
}
}
const art = new Artplayer({
container: '.artplayer-app',
url: 'https://media.axprod.net/TestVectors/v7-Clear/Manifest_1080p.mpd',
setting: true,
plugins: [
artplayerPluginDashControl({
quality: {
// Show qualitys in control
control: true,
// Show qualitys in setting
setting: true,
// Get the quality name from level
getName: level => `${level.height}P`,
// I18n
title: 'Quality',
auto: 'Auto',
},
audio: {
// Show audios in control
control: true,
// Show audios in setting
setting: true,
// Get the audio name from track
getName: track => track.lang.toUpperCase(),
// I18n
title: 'Audio',
auto: 'Auto',
},
}),
],
customType: {
mpd: function playMpd(video, url, art) {
if (dashjs.supportsMediaSource()) {
if (art.dash)
art.dash.destroy()
const dash = dashjs.MediaPlayer().create()
dash.initialize(video, url, art.option.autoplay)
art.dash = dash
art.on('destroy', () => dash.destroy())
}
else {
art.notice.show = 'Unsupported playback format: mpd'
}
},
});
},
})
+21 -19
View File
@@ -2,26 +2,28 @@
// import dashjs from 'dashjs';
function playMpd(video, url, art) {
if (dashjs.supportsMediaSource()) {
if (art.dash) art.dash.destroy();
const dash = dashjs.MediaPlayer().create();
dash.initialize(video, url, art.option.autoplay);
art.dash = dash;
art.on('destroy', () => dash.destroy());
} else {
art.notice.show = 'Unsupported playback format: mpd';
}
if (dashjs.supportsMediaSource()) {
if (art.dash)
art.dash.destroy()
const dash = dashjs.MediaPlayer().create()
dash.initialize(video, url, art.option.autoplay)
art.dash = dash
art.on('destroy', () => dash.destroy())
}
else {
art.notice.show = 'Unsupported playback format: mpd'
}
}
var art = new Artplayer({
container: '.artplayer-app',
url: 'https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd',
type: 'mpd',
customType: {
mpd: playMpd
},
});
const art = new Artplayer({
container: '.artplayer-app',
url: 'https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd',
type: 'mpd',
customType: {
mpd: playMpd,
},
})
art.on('ready', () => {
console.info(art.dash);
});
console.info(art.dash)
})
+1 -1
View File
@@ -1,7 +1,7 @@
// npm i artplayer-plugin-document-pip
// import artplayerPluginDocumentPip from 'artplayer-plugin-document-pip';
let art = new Artplayer({
const art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
plugins: [
+22 -20
View File
@@ -2,27 +2,29 @@
// import flvjs from 'flv.js';
function playFlv(video, url, art) {
if (flvjs.isSupported()) {
if (art.flv) art.flv.destroy();
const flv = flvjs.createPlayer({ type: 'flv', url });
flv.attachMediaElement(video);
flv.load();
art.flv = flv;
art.on('destroy', () => flv.destroy());
} else {
art.notice.show = 'Unsupported playback format: flv';
}
if (flvjs.isSupported()) {
if (art.flv)
art.flv.destroy()
const flv = flvjs.createPlayer({ type: 'flv', url })
flv.attachMediaElement(video)
flv.load()
art.flv = flv
art.on('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,
},
});
const art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.flv',
type: 'flv',
customType: {
flv: playFlv,
},
})
art.on('ready', () => {
console.info(art.flv);
});
console.info(art.flv)
})
+49 -46
View File
@@ -4,50 +4,53 @@
// import Hls from 'hls.js';
// import artplayerPluginHlsControl from 'artplayer-plugin-hls-control';
var art = new Artplayer({
container: '.artplayer-app',
url: 'https://playertest.longtailvideo.com/adaptive/elephants_dream_v4/index.m3u8',
setting: true,
plugins: [
artplayerPluginHlsControl({
quality: {
// Show qualitys in control
control: true,
// Show qualitys in setting
setting: true,
// Get the quality name from level
getName: (level) => level.height + 'P',
// I18n
title: 'Quality',
auto: 'Auto',
},
audio: {
// Show audios in control
control: true,
// Show audios in setting
setting: true,
// Get the audio name from track
getName: (track) => track.name,
// I18n
title: 'Audio',
auto: 'Auto',
}
}),
],
customType: {
m3u8: function playM3u8(video, url, art) {
if (Hls.isSupported()) {
if (art.hls) art.hls.destroy();
const hls = new Hls();
hls.loadSource(url);
hls.attachMedia(video);
art.hls = hls;
art.on('destroy', () => hls.destroy());
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = url;
} else {
art.notice.show = 'Unsupported playback format: m3u8';
}
}
const art = new Artplayer({
container: '.artplayer-app',
url: 'https://playertest.longtailvideo.com/adaptive/elephants_dream_v4/index.m3u8',
setting: true,
plugins: [
artplayerPluginHlsControl({
quality: {
// Show qualitys in control
control: true,
// Show qualitys in setting
setting: true,
// Get the quality name from level
getName: level => `${level.height}P`,
// I18n
title: 'Quality',
auto: 'Auto',
},
audio: {
// Show audios in control
control: true,
// Show audios in setting
setting: true,
// Get the audio name from track
getName: track => track.name,
// I18n
title: 'Audio',
auto: 'Auto',
},
}),
],
customType: {
m3u8: function playM3u8(video, url, art) {
if (Hls.isSupported()) {
if (art.hls)
art.hls.destroy()
const hls = new Hls()
hls.loadSource(url)
hls.attachMedia(video)
art.hls = hls
art.on('destroy', () => hls.destroy())
}
else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = url
}
else {
art.notice.show = 'Unsupported playback format: m3u8'
}
},
});
},
})
+25 -22
View File
@@ -2,29 +2,32 @@
// import Hls from 'hls.js';
function playM3u8(video, url, art) {
if (Hls.isSupported()) {
if (art.hls) art.hls.destroy();
const hls = new Hls();
hls.loadSource(url);
hls.attachMedia(video);
art.hls = hls;
art.on('destroy', () => hls.destroy());
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = url;
} else {
art.notice.show = 'Unsupported playback format: m3u8';
}
if (Hls.isSupported()) {
if (art.hls)
art.hls.destroy()
const hls = new Hls()
hls.loadSource(url)
hls.attachMedia(video)
art.hls = hls
art.on('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,
},
});
const 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);
});
console.info(art.hls)
})
+36 -35
View File
@@ -1,46 +1,47 @@
// npm i artplayer-plugin-iframe
// import ArtplayerPluginIframe from 'artplayer-plugin-iframe';
const $iframe = document.createElement('iframe');
$iframe.allowFullscreen = true;
$iframe.width = '100%';
$iframe.height = '100%';
const $iframe = document.createElement('iframe')
$iframe.allowFullscreen = true
$iframe.width = '100%'
$iframe.height = '100%'
const $container = document.querySelector('.artplayer-app');
$container.innerHTML = '';
$container.appendChild($iframe);
const $container = document.querySelector('.artplayer-app')
$container.innerHTML = ''
$container.appendChild($iframe)
const iframe = new ArtplayerPluginIframe({
iframe: $iframe,
url: '/iframe.html',
});
iframe: $iframe,
url: '/iframe.html',
})
iframe.message(({ type, data }) => {
switch (type) {
case 'fullscreenWeb':
if (data) {
$iframe.classList.add('fullscreenWeb');
} else {
$iframe.classList.remove('fullscreenWeb');
}
break;
default:
break;
}
});
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: '/assets/sample/video.mp4',
fullscreen: true,
fullscreenWeb: true,
});
const art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
fullscreen: true,
fullscreenWeb: true,
})
art.on('fullscreenWeb', (state) => {
ArtplayerPluginIframe.postMessage({
type: 'fullscreenWeb',
data: state,
});
});
});
art.on('fullscreenWeb', (state) => {
ArtplayerPluginIframe.postMessage({
type: 'fullscreenWeb',
data: state,
})
})
})
+185 -185
View File
@@ -1,190 +1,190 @@
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
poster: '/assets/sample/poster.jpg',
volume: 0.5,
isLive: false,
muted: false,
autoplay: false,
pip: true,
autoSize: true,
autoMini: true,
screenshot: true,
setting: true,
loop: true,
flip: true,
playbackRate: true,
aspectRatio: true,
fullscreen: true,
fullscreenWeb: true,
subtitleOffset: true,
miniProgressBar: true,
mutex: true,
backdrop: true,
playsInline: true,
autoPlayback: true,
airplay: true,
theme: '#23ade5',
lang: navigator.language.toLowerCase(),
moreVideoAttr: {
crossOrigin: 'anonymous',
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
poster: '/assets/sample/poster.jpg',
volume: 0.5,
isLive: false,
muted: false,
autoplay: false,
pip: true,
autoSize: true,
autoMini: true,
screenshot: true,
setting: true,
loop: true,
flip: true,
playbackRate: true,
aspectRatio: true,
fullscreen: true,
fullscreenWeb: true,
subtitleOffset: true,
miniProgressBar: true,
mutex: true,
backdrop: true,
playsInline: true,
autoPlayback: true,
airplay: true,
theme: '#23ade5',
lang: navigator.language.toLowerCase(),
moreVideoAttr: {
crossOrigin: 'anonymous',
},
settings: [
{
width: 200,
html: 'Subtitle',
tooltip: 'Bilingual',
icon: '<img width="22" height="22" src="/assets/img/subtitle.svg">',
selector: [
{
html: 'Display',
tooltip: 'Show',
switch: true,
onSwitch(item) {
item.tooltip = item.switch ? 'Hide' : 'Show'
art.subtitle.show = !item.switch
return !item.switch
},
},
{
default: true,
html: 'Bilingual',
url: '/assets/sample/subtitle.srt',
},
{
html: 'Chinese',
url: '/assets/sample/subtitle.cn.srt',
},
{
html: 'Japanese',
url: '/assets/sample/subtitle.jp.srt',
},
],
onSelect(item) {
art.subtitle.switch(item.url, {
name: item.html,
})
return item.html
},
},
settings: [
{
width: 200,
html: 'Subtitle',
tooltip: 'Bilingual',
icon: '<img width="22" height="22" src="/assets/img/subtitle.svg">',
selector: [
{
html: 'Display',
tooltip: 'Show',
switch: true,
onSwitch: function (item) {
item.tooltip = item.switch ? 'Hide' : 'Show';
art.subtitle.show = !item.switch;
return !item.switch;
},
},
{
default: true,
html: 'Bilingual',
url: '/assets/sample/subtitle.srt',
},
{
html: 'Chinese',
url: '/assets/sample/subtitle.cn.srt',
},
{
html: 'Japanese',
url: '/assets/sample/subtitle.jp.srt',
},
],
onSelect: function (item) {
art.subtitle.switch(item.url, {
name: item.html,
});
return item.html;
},
},
{
html: 'Switcher',
icon: '<img width="22" height="22" src="/assets/img/state.svg">',
tooltip: 'OFF',
switch: false,
onSwitch: function (item) {
item.tooltip = item.switch ? 'OFF' : 'ON';
console.info('You clicked on the custom switch', item.switch);
return !item.switch;
},
},
{
html: 'Slider',
icon: '<img width="22" height="22" src="/assets/img/state.svg">',
tooltip: '5x',
range: [5, 1, 10, 0.1],
onRange: function (item) {
return item.range[0] + 'x';
},
},
{
html: 'Button',
icon: '<img width="22" height="22" src="/assets/img/state.svg">',
tooltip: 'tooltip',
onClick() {
return 'Button clicked';
}
},
],
contextmenu: [
{
html: 'Custom menu',
click: function (contextmenu) {
console.info('You clicked on the custom menu');
contextmenu.show = false;
},
},
],
layers: [
{
html: '<img width="100" src="/assets/sample/layer.png">',
click: function () {
window.open('https://aimu.app');
console.info('You clicked on the custom layer');
},
style: {
position: 'absolute',
top: '20px',
right: '20px',
opacity: '.9',
},
},
],
quality: [
{
default: true,
html: 'SD 480P',
url: '/assets/sample/video.mp4?q=480',
},
{
html: 'HD 720P',
url: '/assets/sample/video.mp4?q=720',
},
],
thumbnails: {
url: '/assets/sample/thumbnails.png',
number: 60,
column: 10,
scale: 0.85,
{
html: 'Switcher',
icon: '<img width="22" height="22" src="/assets/img/state.svg">',
tooltip: 'OFF',
switch: false,
onSwitch(item) {
item.tooltip = item.switch ? 'OFF' : 'ON'
console.info('You clicked on the custom switch', item.switch)
return !item.switch
},
},
subtitle: {
url: '/assets/sample/subtitle.srt',
type: 'srt',
style: {
color: '#fe9200',
fontSize: '20px',
},
encoding: 'utf-8',
{
html: 'Slider',
icon: '<img width="22" height="22" src="/assets/img/state.svg">',
tooltip: '5x',
range: [5, 1, 10, 0.1],
onRange(item) {
return `${item.range[0]}x`
},
},
highlight: [
{
time: 15,
text: 'One more chance',
},
{
time: 30,
text: '谁でもいいはずなのに',
},
{
time: 45,
text: '夏の想い出がまわる',
},
{
time: 60,
text: 'こんなとこにあるはずもないのに',
},
{
time: 75,
text: '终わり',
},
],
controls: [
{
position: 'right',
html: 'Control',
index: 1,
tooltip: 'Control Tooltip',
style: {
marginRight: '20px',
},
click: function () {
console.info('You clicked on the custom control');
},
},
],
icons: {
loading: '<img src="/assets/img/ploading.gif">',
state: '<img width="150" height="150" src="/assets/img/state.svg">',
indicator: '<img width="16" height="16" src="/assets/img/indicator.svg">',
{
html: 'Button',
icon: '<img width="22" height="22" src="/assets/img/state.svg">',
tooltip: 'tooltip',
onClick() {
return 'Button clicked'
},
},
});
],
contextmenu: [
{
html: 'Custom menu',
click(contextmenu) {
console.info('You clicked on the custom menu')
contextmenu.show = false
},
},
],
layers: [
{
html: '<img width="100" src="/assets/sample/layer.png">',
click() {
window.open('https://aimu.app')
console.info('You clicked on the custom layer')
},
style: {
position: 'absolute',
top: '20px',
right: '20px',
opacity: '.9',
},
},
],
quality: [
{
default: true,
html: 'SD 480P',
url: '/assets/sample/video.mp4?q=480',
},
{
html: 'HD 720P',
url: '/assets/sample/video.mp4?q=720',
},
],
thumbnails: {
url: '/assets/sample/thumbnails.png',
number: 60,
column: 10,
scale: 0.85,
},
subtitle: {
url: '/assets/sample/subtitle.srt',
type: 'srt',
style: {
color: '#fe9200',
fontSize: '20px',
},
encoding: 'utf-8',
},
highlight: [
{
time: 15,
text: 'One more chance',
},
{
time: 30,
text: '谁でもいいはずなのに',
},
{
time: 45,
text: '夏の想い出がまわる',
},
{
time: 60,
text: 'こんなとこにあるはずもないのに',
},
{
time: 75,
text: '终わり',
},
],
controls: [
{
position: 'right',
html: 'Control',
index: 1,
tooltip: 'Control Tooltip',
style: {
marginRight: '20px',
},
click() {
console.info('You clicked on the custom control')
},
},
],
icons: {
loading: '<img src="/assets/img/ploading.gif">',
state: '<img width="150" height="150" src="/assets/img/state.svg">',
indicator: '<img width="16" height="16" src="/assets/img/indicator.svg">',
},
})
+22 -22
View File
@@ -1,44 +1,44 @@
// npm i artplayer-plugin-libass
// import artplayerPluginLibass from 'artplayer-plugin-libass';
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
fullscreenWeb: true,
subtitle: {
url: '/assets/sample/style-test.ass',
},
plugins: [
artplayerPluginLibass({
// debug: true,
workerUrl: 'https://unpkg.com/libass-wasm@4.1.0/dist/js/subtitles-octopus-worker.js',
// wasmUrl: 'https://unpkg.com/libass-wasm@4.1.0/dist/js/subtitles-octopus-worker.wasm',
fallbackFont: '/assets/misc/SourceHanSansCN-Bold.woff2'
}),
],
});
const art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
fullscreenWeb: true,
subtitle: {
url: '/assets/sample/style-test.ass',
},
plugins: [
artplayerPluginLibass({
// debug: true,
workerUrl: 'https://unpkg.com/libass-wasm@4.1.0/dist/js/subtitles-octopus-worker.js',
// wasmUrl: 'https://unpkg.com/libass-wasm@4.1.0/dist/js/subtitles-octopus-worker.wasm',
fallbackFont: '/assets/misc/SourceHanSansCN-Bold.woff2',
}),
],
})
// init
art.on('artplayerPluginLibass:init', (adapter) => {
console.info('artplayerPluginLibass:init', adapter);
});
console.info('artplayerPluginLibass:init', adapter)
})
// subtitle switch
art.on('artplayerPluginLibass:switch', (url) => {
console.info('artplayerPluginLibass:switch', url);
console.info('artplayerPluginLibass:switch', url)
})
// subtitle visible
art.on('artplayerPluginLibass:visible', (visible) => {
console.info('artplayerPluginLibass:visible', visible);
console.info('artplayerPluginLibass:visible', visible)
})
// subtitle timeOffset
art.on('artplayerPluginLibass:timeOffset', (timeOffset) => {
console.info('artplayerPluginLibass:timeOffset', timeOffset);
console.info('artplayerPluginLibass:timeOffset', timeOffset)
})
// destroy
art.on('artplayerPluginLibass:destroy', () => {
console.info('artplayerPluginLibass:destroy');
console.info('artplayerPluginLibass:destroy')
})
+91 -91
View File
@@ -1,98 +1,98 @@
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
poster: '/assets/sample/poster.jpg',
autoSize: true,
loop: true,
mutex: true,
setting: true,
flip: true,
lock: true,
fastForward: true,
playbackRate: true,
aspectRatio: true,
theme: '#ff0057',
fullscreen: true,
fullscreenWeb: true,
miniProgressBar: true,
autoOrientation: true,
airplay: true,
moreVideoAttr: {
'x5-video-player-type': 'h5',
'x5-video-player-fullscreen': false,
'x5-video-orientation': 'portraint',
preload: "metadata"
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
poster: '/assets/sample/poster.jpg',
autoSize: true,
loop: true,
mutex: true,
setting: true,
flip: true,
lock: true,
fastForward: true,
playbackRate: true,
aspectRatio: true,
theme: '#ff0057',
fullscreen: true,
fullscreenWeb: true,
miniProgressBar: true,
autoOrientation: true,
airplay: true,
moreVideoAttr: {
'x5-video-player-type': 'h5',
'x5-video-player-fullscreen': false,
'x5-video-orientation': 'portraint',
'preload': 'metadata',
},
thumbnails: {
url: '/assets/sample/thumbnails.png',
number: 60,
column: 10,
scale: 0.6,
},
subtitle: {
name: '中日双语',
url: '/assets/sample/subtitle.srt',
style: {
color: '#48aff0',
fontSize: '16px',
},
thumbnails: {
url: '/assets/sample/thumbnails.png',
number: 60,
column: 10,
scale: 0.6
},
layers: [
{
html: `<img width="50" src="/assets/sample/layer.png">`,
click() {
art.notice.show = '你点击了自定义层'
},
style: {
position: 'absolute',
top: '10px',
right: '10px',
opacity: '.9',
},
},
subtitle: {
name: '中日双语',
url: '/assets/sample/subtitle.srt',
style: {
color: '#48aff0',
fontSize: '16px',
},
},
layers: [
],
icons: {
loading: '<img src="/assets/img/ploading.gif">',
state: '<img width="150" height="150" src="/assets/img/state.svg">',
indicator: '<img width="16" height="16" src="/assets/img/indicator.svg">',
},
settings: [
{
width: 200,
html: '切换字幕',
tooltip: '双语',
icon: '<img width="22" height="22" src="/assets/img/subtitle.svg">',
selector: [
{
html: `<img width="50" src="/assets/sample/layer.png">`,
click: function () {
art.notice.show = "你点击了自定义层";
},
style: {
position: 'absolute',
top: '10px',
right: '10px',
opacity: '.9',
},
html: '开关',
switch: true,
tooltip: '显示',
onSwitch(item) {
item.tooltip = item.switch ? '隐藏' : '显示'
art.subtitle.show = !item.switch
return !item.switch
},
},
],
icons: {
loading: '<img src="/assets/img/ploading.gif">',
state: '<img width="150" height="150" src="/assets/img/state.svg">',
indicator: '<img width="16" height="16" src="/assets/img/indicator.svg">',
},
settings: [
{
width: 200,
html: '切换字幕',
tooltip: '双语',
icon: '<img width="22" height="22" src="/assets/img/subtitle.svg">',
selector: [
{
html: '开关',
switch: true,
tooltip: '显示',
onSwitch: function (item) {
item.tooltip = item.switch ? '隐藏' : '显示';
art.subtitle.show = !item.switch;
return !item.switch;
},
},
{
default: true,
html: '双语',
url: '/assets/sample/subtitle.srt'
},
{
html: '中文',
url: '/assets/sample/subtitle.cn.srt'
},
{
html: '日文',
url: '/assets/sample/subtitle.jp.srt'
},
],
onSelect: function (item) {
art.subtitle.switch(item.url, {
name: item.html
});
return item.html;
},
default: true,
html: '双语',
url: '/assets/sample/subtitle.srt',
},
],
});
{
html: '中文',
url: '/assets/sample/subtitle.cn.srt',
},
{
html: '日文',
url: '/assets/sample/subtitle.jp.srt',
},
],
onSelect(item) {
art.subtitle.switch(item.url, {
name: item.html,
})
return item.html
},
},
],
})
+26 -24
View File
@@ -2,33 +2,35 @@
// import mpegts from 'mpegts';
function playFlv(video, url, art) {
if (mpegts.isSupported()) {
if (art.flv) art.flv.destroy();
if (mpegts.isSupported()) {
if (art.flv)
art.flv.destroy()
const flv = mpegts.createPlayer({
type: 'flv',
url: url
});
flv.attachMediaElement(video);
flv.load();
flv.play();
const flv = mpegts.createPlayer({
type: 'flv',
url,
})
flv.attachMediaElement(video)
flv.load()
flv.play()
art.flv = flv;
art.on('destroy', () => flv.destroy());
} else {
art.notice.show = 'Unsupported playback format: flv';
}
art.flv = flv
art.on('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,
},
});
const art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.flv',
type: 'flv',
customType: {
flv: playFlv,
},
})
art.on('ready', () => {
console.info(art.flv);
});
console.info(art.flv)
})
+91 -89
View File
@@ -2,88 +2,89 @@
// import artplayerPluginMultipleSubtitles from 'artplayer-plugin-multiple-subtitles';
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
setting: true,
plugins: [
artplayerPluginMultipleSubtitles({
subtitles: [
{
name: 'chinese',
url: '/assets/sample/subtitle.cn.srt',
},
{
name: 'japanese',
url: '/assets/sample/subtitle.jp.srt',
}
],
})
],
settings: [
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
setting: true,
plugins: [
artplayerPluginMultipleSubtitles({
subtitles: [
{
width: 200,
html: 'Subtitle',
tooltip: 'Double',
icon: '<img width="22" height="22" src="/assets/img/subtitle.svg">',
selector: [
{
html: 'Display',
tooltip: 'Show',
switch: true,
onSwitch: function (item) {
item.tooltip = item.switch ? 'Hide' : 'Show';
// 显示/隐藏字幕
// Show/hide subtitles
art.subtitle.show = !item.switch;
return !item.switch;
},
},
{
html: 'Reverse',
tooltip: 'Off',
switch: false,
onSwitch: function (item) {
item.tooltip = item.switch ? 'Off' : 'On';
// 修改字幕顺序
// Change the order of subtitles
if (item.switch) {
art.plugins.multipleSubtitles.tracks(['chinese', 'japanese']);
} else {
art.plugins.multipleSubtitles.tracks(['japanese', 'chinese']);
}
return !item.switch;
},
},
{
default: true,
html: 'Double',
name: 'double',
},
{
html: 'Chinese',
name: 'chinese',
},
{
html: 'Japanese',
name: 'japanese',
},
],
onSelect: function (item) {
if (item.name === 'double') {
// 重置字幕
// Reset subtitles
art.plugins.multipleSubtitles.reset();
} else {
// 显示单个字幕
// Show single subtitle
art.plugins.multipleSubtitles.tracks([item.name]);
}
return item.html;
},
name: 'chinese',
url: '/assets/sample/subtitle.cn.srt',
},
],
});
{
name: 'japanese',
url: '/assets/sample/subtitle.jp.srt',
},
],
}),
],
settings: [
{
width: 200,
html: 'Subtitle',
tooltip: 'Double',
icon: '<img width="22" height="22" src="/assets/img/subtitle.svg">',
selector: [
{
html: 'Display',
tooltip: 'Show',
switch: true,
onSwitch(item) {
item.tooltip = item.switch ? 'Hide' : 'Show'
// 显示/隐藏字幕
// Show/hide subtitles
art.subtitle.show = !item.switch
return !item.switch
},
},
{
html: 'Reverse',
tooltip: 'Off',
switch: false,
onSwitch(item) {
item.tooltip = item.switch ? 'Off' : 'On'
// 修改字幕顺序
// Change the order of subtitles
if (item.switch) {
art.plugins.multipleSubtitles.tracks(['chinese', 'japanese'])
}
else {
art.plugins.multipleSubtitles.tracks(['japanese', 'chinese'])
}
return !item.switch
},
},
{
default: true,
html: 'Double',
name: 'double',
},
{
html: 'Chinese',
name: 'chinese',
},
{
html: 'Japanese',
name: 'japanese',
},
],
onSelect(item) {
if (item.name === 'double') {
// 重置字幕
// Reset subtitles
art.plugins.multipleSubtitles.reset()
}
else {
// 显示单个字幕
// Show single subtitle
art.plugins.multipleSubtitles.tracks([item.name])
}
return item.html
},
},
],
})
// 自定义你自己的样式,请勿复制以下代码
// Customize your own style, please do not copy the following code
@@ -98,14 +99,15 @@ const style = `
color: yellow;
font-size: 12px;
}
`;
`
const $style = document.getElementById('artplayer-subtitle-style');
const $style = document.getElementById('artplayer-subtitle-style')
if ($style) {
$style.textContent = style;
} else {
const $style = document.createElement('style');
$style.id = 'artplayer-subtitle-style';
$style.textContent = style;
document.head.appendChild($style);
}
$style.textContent = style
}
else {
const $style = document.createElement('style')
$style.id = 'artplayer-subtitle-style'
$style.textContent = style
document.head.appendChild($style)
}
+132 -130
View File
@@ -1,138 +1,140 @@
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
setting: true,
flip: true,
playbackRate: true,
aspectRatio: true,
subtitleOffset: true,
settings: [
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
setting: true,
flip: true,
playbackRate: true,
aspectRatio: true,
subtitleOffset: true,
settings: [
{
width: 200,
html: 'Subtitle',
name: 'subtitle',
tooltip: 'Bilingual',
icon: '<img width="22" height="22" src="/assets/img/subtitle.svg">',
selector: [
{
width: 200,
html: 'Subtitle',
name: 'subtitle',
tooltip: 'Bilingual',
icon: '<img width="22" height="22" src="/assets/img/subtitle.svg">',
selector: [
{
html: 'Display',
tooltip: 'Show',
switch: true,
onSwitch: function (item) {
item.tooltip = item.switch ? 'Hide' : 'Show';
art.subtitle.show = !item.switch;
return !item.switch;
},
},
{
default: true,
html: 'Bilingual',
url: '/assets/sample/subtitle.srt',
},
{
html: 'Chinese',
url: '/assets/sample/subtitle.cn.srt',
},
{
html: 'Japanese',
url: '/assets/sample/subtitle.jp.srt',
},
],
onSelect: function (item) {
art.subtitle.switch(item.url, {
name: item.html,
});
return item.html;
},
mounted: function (...args) {
console.info(args);
},
html: 'Display',
tooltip: 'Show',
switch: true,
onSwitch(item) {
item.tooltip = item.switch ? 'Hide' : 'Show'
art.subtitle.show = !item.switch
return !item.switch
},
},
{
html: 'Switcher',
icon: '<img width="22" height="22" src="/assets/img/state.svg">',
tooltip: 'OFF',
switch: false,
onSwitch: function (item) {
item.tooltip = item.switch ? 'OFF' : 'ON';
console.info('You clicked on the custom switch', item.switch);
return !item.switch;
},
mounted: function (...args) {
console.info(args);
},
default: true,
html: 'Bilingual',
url: '/assets/sample/subtitle.srt',
},
{
html: 'Slider',
icon: '<img width="22" height="22" src="/assets/img/state.svg">',
tooltip: '5x',
range: [5, 1, 10, 0.1],
onRange: function (item) {
return item.range[0] + 'x';
},
mounted: function (...args) {
console.info(args);
},
html: 'Chinese',
url: '/assets/sample/subtitle.cn.srt',
},
],
{
html: 'Japanese',
url: '/assets/sample/subtitle.jp.srt',
},
],
onSelect(item) {
art.subtitle.switch(item.url, {
name: item.html,
})
return item.html
},
mounted(...args) {
console.info(args)
},
},
{
html: 'Switcher',
icon: '<img width="22" height="22" src="/assets/img/state.svg">',
tooltip: 'OFF',
switch: false,
onSwitch(item) {
item.tooltip = item.switch ? 'OFF' : 'ON'
console.info('You clicked on the custom switch', item.switch)
return !item.switch
},
mounted(...args) {
console.info(args)
},
},
{
html: 'Slider',
icon: '<img width="22" height="22" src="/assets/img/state.svg">',
tooltip: '5x',
range: [5, 1, 10, 0.1],
onRange(item) {
return `${item.range[0]}x`
},
mounted(...args) {
console.info(args)
},
},
],
}, async () => {
const { sleep } = Artplayer.utils;
art.setting.show = true;
console.log(art.setting.builtin);
console.log(art.setting.find('aspect-ratio'));
console.log(art.setting.find('aspect-ratio2'));
await sleep(1000);
art.setting.resize();
await sleep(1000);
art.setting.inactivate(art.setting.find('subtitle'));
art.setting.remove('aspect-ratio');
try {
art.setting.remove('aspect-ratio2');
} catch (error) {
console.log(error.message);
}
await sleep(1000);
art.setting.update({
name: 'subtitle-offset',
html: 'new offset',
range: [5, -11, 11, 1],
});
await sleep(1000);
art.setting.find('subtitle-offset').range = [0, -0, 10, 1];
await sleep(1000);
art.setting.update({
name: 'subtitle-offset2',
html: 'new offset 2',
range: [5, -11, 11, 1],
onChange(item) {
return item.range[0] + 's';
},
});
await sleep(1000);
art.setting.update({
name: 'flip',
html: 'new flip',
tooltip: 'OFF',
switch: false,
});
await sleep(1000);
art.setting.find('flip').switch = true;
await sleep(1000);
art.setting.update({
name: 'flip2',
html: 'new flip2',
tooltip: 'OFF',
switch: true,
});
await sleep(1000);
try {
art.setting.add({
name: 'flip2',
html: 'new flip2',
tooltip: 'OFF',
switch: true,
});
} catch (error) {
console.log(error.message);
}
});
const { sleep } = Artplayer.utils
art.setting.show = true
console.log(art.setting.builtin)
console.log(art.setting.find('aspect-ratio'))
console.log(art.setting.find('aspect-ratio2'))
await sleep(1000)
art.setting.resize()
await sleep(1000)
art.setting.inactivate(art.setting.find('subtitle'))
art.setting.remove('aspect-ratio')
try {
art.setting.remove('aspect-ratio2')
}
catch (error) {
console.log(error.message)
}
await sleep(1000)
art.setting.update({
name: 'subtitle-offset',
html: 'new offset',
range: [5, -11, 11, 1],
})
await sleep(1000)
art.setting.find('subtitle-offset').range = [0, -0, 10, 1]
await sleep(1000)
art.setting.update({
name: 'subtitle-offset2',
html: 'new offset 2',
range: [5, -11, 11, 1],
onChange(item) {
return `${item.range[0]}s`
},
})
await sleep(1000)
art.setting.update({
name: 'flip',
html: 'new flip',
tooltip: 'OFF',
switch: false,
})
await sleep(1000)
art.setting.find('flip').switch = true
await sleep(1000)
art.setting.update({
name: 'flip2',
html: 'new flip2',
tooltip: 'OFF',
switch: true,
})
await sleep(1000)
try {
art.setting.add({
name: 'flip2',
html: 'new flip2',
tooltip: 'OFF',
switch: true,
})
}
catch (error) {
console.log(error.message)
}
})
+11 -11
View File
@@ -1,14 +1,14 @@
// npm i artplayer-plugin-thumbnail
// import artplayerPluginThumbnail from 'artplayer-plugin-thumbnail';
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
plugins: [
artplayerPluginThumbnail({
width: 160,
number: 100,
scale: 1,
}),
],
});
const art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
plugins: [
artplayerPluginThumbnail({
width: 160,
number: 100,
scale: 1,
}),
],
})
+14 -14
View File
@@ -1,4 +1,4 @@
// Depends on:
// Depends on:
// https://glomex.github.io/vast-ima-player/
// https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side
@@ -9,16 +9,16 @@
// import artplayerPluginVast from 'artplayer-plugin-vast';
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
fullscreen: true,
fullscreenWeb: true,
plugins: [
artplayerPluginVast(({ playUrl, imaPlayer, ima }) => {
// Play the ad when the video is played
art.once('play', () => {
playUrl('https://artplayer.org/assets/vast/linear-ad.xml');
});
}),
],
});
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
fullscreen: true,
fullscreenWeb: true,
plugins: [
artplayerPluginVast(({ playUrl, imaPlayer, ima }) => {
// Play the ad when the video is played
art.once('play', () => {
playUrl('https://artplayer.org/assets/vast/linear-ad.xml')
})
}),
],
})
+9 -9
View File
@@ -1,12 +1,12 @@
// npm i artplayer-plugin-vtt-thumbnail
// import artplayerPluginVttThumbnail from 'artplayer-plugin-vtt-thumbnail';
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/bbb-video.mp4',
plugins: [
artplayerPluginVttThumbnail({
vtt: '/assets/sample/bbb-thumbnails.vtt',
})
]
});
const art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/bbb-video.mp4',
plugins: [
artplayerPluginVttThumbnail({
vtt: '/assets/sample/bbb-thumbnails.vtt',
}),
],
})
+27 -25
View File
@@ -2,35 +2,37 @@
// import WebTorrent from 'webtorrent';
async function playTorrent(video, url, art) {
if (WebTorrent.WEBRTC_SUPPORT) {
if (art.torrent) art.torrent.destroy();
art.torrent = new WebTorrent();
if (WebTorrent.WEBRTC_SUPPORT) {
if (art.torrent)
art.torrent.destroy()
art.torrent = new WebTorrent()
await navigator.serviceWorker.register('/webtorrent.sw.min.js');
art.torrent.loadWorker(navigator.serviceWorker.controller);
await navigator.serviceWorker.register('/webtorrent.sw.min.js')
art.torrent.loadWorker(navigator.serviceWorker.controller)
art.torrent.add(url, (torrent) => {
const file = torrent.files.find((file) => {
return file.name.endsWith('.mp4');
});
file.streamTo(video);
});
art.torrent.add(url, (torrent) => {
const file = torrent.files.find((file) => {
return file.name.endsWith('.mp4')
})
file.streamTo(video)
})
art.on('destroy', () => art.torrent.destroy());
} else {
art.notice.show = 'Unsupported playback format: torrent';
}
art.on('destroy', () => art.torrent.destroy())
}
else {
art.notice.show = 'Unsupported playback format: torrent'
}
}
var art = new Artplayer({
container: '.artplayer-app',
url: 'magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent',
type: 'torrent',
customType: {
torrent: playTorrent,
},
});
const art = new Artplayer({
container: '.artplayer-app',
url: 'magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent',
type: 'torrent',
customType: {
torrent: playTorrent,
},
})
art.on('ready', () => {
console.info(art.torrent);
});
console.info(art.torrent)
})