mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-28 18:41:20 -08:00
feat: add Picture-in-Picture plugin for ArtPlayer
- Introduced `artplayer-plugin-pip` to enable Picture-in-Picture functionality. - Updated `artplayer.d.ts` to export new types related to the plugin. - Added example usage of the plugin in `pip.js`. - Created TypeScript definitions for the plugin in `artplayer-plugin-pip.d.ts`. - Implemented the plugin logic in `index.js` with necessary styles and event handling. - Updated documentation to include the new plugin and its usage. - Added README and package.json for the new plugin.
This commit is contained in:
1 parent
bd071b2d63
commit
c23520a4a6
12 files changed
+853
-279
No files matched your search
@@ -0,0 +1,18 @@
|
|||||||
|
// npm i artplayer-plugin-pip
|
||||||
|
// import artplayerPluginPip from 'artplayer-plugin-pip';
|
||||||
|
|
||||||
|
let art = new Artplayer({
|
||||||
|
container: '.artplayer-app',
|
||||||
|
url: '/assets/sample/video.mp4',
|
||||||
|
plugins: [
|
||||||
|
artplayerPluginPip({
|
||||||
|
width: 480,
|
||||||
|
height: 270,
|
||||||
|
placeholder: `Playing in Document Picture-in-Picture`,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
art.on('document-pip', (state) => {
|
||||||
|
console.log('Document Picture-in-Picture', state)
|
||||||
|
})
|
||||||
+283
-279
@@ -1,305 +1,309 @@
|
|||||||
(function () {
|
(function () {
|
||||||
Artplayer.DEBUG = true;
|
Artplayer.DEBUG = true
|
||||||
|
|
||||||
if (Artplayer.utils.isMobile) {
|
if (Artplayer.utils.isMobile) {
|
||||||
window.location.href = './mobile.html' + location.search;
|
window.location.href = `./mobile.html${location.search}`
|
||||||
|
}
|
||||||
|
|
||||||
|
let $codeMirror = document.querySelector('.codeMirrorWrap')
|
||||||
|
let $lib = document.querySelector('.libsInput')
|
||||||
|
let $run = document.querySelector('.run')
|
||||||
|
let $popups = document.querySelector('.popups')
|
||||||
|
let $console = document.querySelector('.console')
|
||||||
|
let $prod = document.querySelector('#prod')
|
||||||
|
let $ts = document.querySelector('#ts')
|
||||||
|
let $code = document.querySelector('#code')
|
||||||
|
let $log = document.querySelector('#log')
|
||||||
|
let $file = document.querySelector('#file')
|
||||||
|
let $editor = document.querySelector('#editor')
|
||||||
|
|
||||||
|
window.consoleLog($console)
|
||||||
|
|
||||||
|
$prod.checked = localStorage.getItem('prod') === 'true'
|
||||||
|
$ts.checked = localStorage.getItem('ts') === 'true'
|
||||||
|
$code.checked = localStorage.getItem('code') === 'true'
|
||||||
|
$log.checked = localStorage.getItem('log') === 'true'
|
||||||
|
|
||||||
|
if ($code.checked) {
|
||||||
|
$editor.style.display = 'none'
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($log.checked) {
|
||||||
|
$console.style.display = 'none'
|
||||||
|
}
|
||||||
|
|
||||||
|
let editor = null
|
||||||
|
let loadedLibs = []
|
||||||
|
require.config({ paths: { vs: './assets/js/vs' } })
|
||||||
|
require(['vs/editor/editor.main'], async () => {
|
||||||
|
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
|
||||||
|
noSemanticValidation: true,
|
||||||
|
noSyntaxValidation: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
|
||||||
|
target: monaco.languages.typescript.ScriptTarget.ES6,
|
||||||
|
allowNonTsExtensions: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
let libUris = [
|
||||||
|
'./assets/ts/artplayer-plugin-ads.d.ts',
|
||||||
|
'./assets/ts/artplayer-plugin-asr.d.ts',
|
||||||
|
'./assets/ts/artplayer-plugin-ambilight.d.ts',
|
||||||
|
'./assets/ts/artplayer-plugin-auto-thumbnail.d.ts',
|
||||||
|
'./assets/ts/artplayer-plugin-chapter.d.ts',
|
||||||
|
'./assets/ts/artplayer-plugin-chromecast.d.ts',
|
||||||
|
'./assets/ts/artplayer-plugin-danmuku-mask.d.ts',
|
||||||
|
'./assets/ts/artplayer-plugin-danmuku.d.ts',
|
||||||
|
'./assets/ts/artplayer-plugin-dash-control.d.ts',
|
||||||
|
'./assets/ts/artplayer-plugin-hls-control.d.ts',
|
||||||
|
'./assets/ts/artplayer-plugin-iframe.d.ts',
|
||||||
|
'./assets/ts/artplayer-plugin-libass.d.ts',
|
||||||
|
'./assets/ts/artplayer-plugin-multiple-subtitles.d.ts',
|
||||||
|
'./assets/ts/artplayer-plugin-vast.d.ts',
|
||||||
|
'./assets/ts/artplayer-plugin-vtt-thumbnail.d.ts',
|
||||||
|
'./assets/ts/artplayer-plugin-pip.d.ts',
|
||||||
|
'./assets/ts/artplayer.d.ts',
|
||||||
|
]
|
||||||
|
|
||||||
|
for (let index = 0; index < libUris.length; index++) {
|
||||||
|
let libUri = libUris[index]
|
||||||
|
let libSource = await (await fetch(libUri)).text()
|
||||||
|
monaco.languages.typescript.javascriptDefaults.addExtraLib(libSource, libUri)
|
||||||
|
monaco.editor.createModel(libSource, 'typescript', monaco.Uri.parse(libUri))
|
||||||
}
|
}
|
||||||
|
|
||||||
var $codeMirror = document.querySelector('.codeMirrorWrap');
|
var disposable = monaco.editor.onDidCreateEditor(() => {
|
||||||
var $lib = document.querySelector('.libsInput');
|
disposable.dispose()
|
||||||
var $run = document.querySelector('.run');
|
setTimeout(initApp, 1000)
|
||||||
var $popups = document.querySelector('.popups');
|
})
|
||||||
var $console = document.querySelector('.console');
|
|
||||||
var $prod = document.querySelector('#prod');
|
|
||||||
var $ts = document.querySelector('#ts');
|
|
||||||
var $code = document.querySelector('#code');
|
|
||||||
var $log = document.querySelector('#log');
|
|
||||||
var $file = document.querySelector('#file');
|
|
||||||
var $editor = document.querySelector('#editor');
|
|
||||||
|
|
||||||
window['consoleLog']($console);
|
editor = monaco.editor.create($codeMirror, {
|
||||||
|
theme: 'vs-dark',
|
||||||
|
folding: true,
|
||||||
|
automaticLayout: true,
|
||||||
|
quickSuggestions: {
|
||||||
|
other: true,
|
||||||
|
comments: true,
|
||||||
|
strings: true,
|
||||||
|
},
|
||||||
|
model: monaco.editor.createModel(
|
||||||
|
[
|
||||||
|
'var art = new Artplayer({',
|
||||||
|
'\tcontainer: \'.artplayer-app\',',
|
||||||
|
'\turl: \'/assets/sample/video.mp4\',',
|
||||||
|
'});',
|
||||||
|
].join('\n'),
|
||||||
|
$ts.checked ? 'typescript' : 'javascript',
|
||||||
|
),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
$prod.checked = localStorage.getItem('prod') === 'true';
|
function getURLParameters(url) {
|
||||||
$ts.checked = localStorage.getItem('ts') === 'true';
|
return (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce((a, v) => {
|
||||||
$code.checked = localStorage.getItem('code') === 'true';
|
return (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a
|
||||||
$log.checked = localStorage.getItem('log') === 'true';
|
}, {})
|
||||||
|
}
|
||||||
|
|
||||||
if ($code.checked) {
|
function getExt(url) {
|
||||||
$editor.style.display = 'none';
|
if (url.includes('?')) {
|
||||||
|
return getExt(url.split('?')[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($log.checked) {
|
if (url.includes('#')) {
|
||||||
$console.style.display = 'none';
|
return getExt(url.split('#')[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
var editor = null;
|
return url.trim().toLowerCase().split('.').pop()
|
||||||
var loadedLibs = [];
|
}
|
||||||
require.config({ paths: { vs: './assets/js/vs' } });
|
|
||||||
require(['vs/editor/editor.main'], async function () {
|
|
||||||
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
|
|
||||||
noSemanticValidation: true,
|
|
||||||
noSyntaxValidation: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
|
function loadScript(url) {
|
||||||
target: monaco.languages.typescript.ScriptTarget.ES6,
|
return new Promise((resolve, reject) => {
|
||||||
allowNonTsExtensions: true,
|
let define2 = window.define
|
||||||
});
|
window.define = undefined
|
||||||
|
let script = document.createElement('script')
|
||||||
|
script.type = 'text/javascript'
|
||||||
|
script.src = url
|
||||||
|
script.onload = function () {
|
||||||
|
window.define = define2
|
||||||
|
resolve(url)
|
||||||
|
}
|
||||||
|
script.onerror = function () {
|
||||||
|
reject(new Error(`Loading script failed:${url}`))
|
||||||
|
}
|
||||||
|
document.querySelector('head').appendChild(script)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
var libUris = [
|
function loadStyle(url) {
|
||||||
'./assets/ts/artplayer-plugin-ads.d.ts',
|
return new Promise((resolve, reject) => {
|
||||||
'./assets/ts/artplayer-plugin-asr.d.ts',
|
let link = document.createElement('link')
|
||||||
'./assets/ts/artplayer-plugin-ambilight.d.ts',
|
link.rel = 'stylesheet'
|
||||||
'./assets/ts/artplayer-plugin-auto-thumbnail.d.ts',
|
link.href = url
|
||||||
'./assets/ts/artplayer-plugin-chapter.d.ts',
|
link.onload = function () {
|
||||||
'./assets/ts/artplayer-plugin-chromecast.d.ts',
|
resolve(url)
|
||||||
'./assets/ts/artplayer-plugin-danmuku-mask.d.ts',
|
}
|
||||||
'./assets/ts/artplayer-plugin-danmuku.d.ts',
|
link.onerror = function () {
|
||||||
'./assets/ts/artplayer-plugin-dash-control.d.ts',
|
reject(new Error(`Loading style failed:${url}`))
|
||||||
'./assets/ts/artplayer-plugin-hls-control.d.ts',
|
}
|
||||||
'./assets/ts/artplayer-plugin-iframe.d.ts',
|
document.querySelector('head').appendChild(link)
|
||||||
'./assets/ts/artplayer-plugin-libass.d.ts',
|
})
|
||||||
'./assets/ts/artplayer-plugin-multiple-subtitles.d.ts',
|
}
|
||||||
'./assets/ts/artplayer-plugin-vast.d.ts',
|
|
||||||
'./assets/ts/artplayer-plugin-vtt-thumbnail.d.ts',
|
function loadLib(libs) {
|
||||||
'./assets/ts/artplayer.d.ts',
|
let libPromise = []
|
||||||
];
|
let libsDecode = decodeURIComponent(libs || '')
|
||||||
|
libsDecode
|
||||||
for (let index = 0; index < libUris.length; index++) {
|
.split(/\r?\n/)
|
||||||
var libUri = libUris[index];
|
.filter((url) => {
|
||||||
var libSource = await (await fetch(libUri)).text();
|
return !loadedLibs.includes(url)
|
||||||
monaco.languages.typescript.javascriptDefaults.addExtraLib(libSource, libUri);
|
})
|
||||||
monaco.editor.createModel(libSource, 'typescript', monaco.Uri.parse(libUri));
|
.forEach((url) => {
|
||||||
|
let ext = getExt(url)
|
||||||
|
if (ext === 'js') {
|
||||||
|
libPromise.push(loadScript(url))
|
||||||
}
|
}
|
||||||
|
else if (ext === 'css') {
|
||||||
var disposable = monaco.editor.onDidCreateEditor(function () {
|
libPromise.push(loadStyle(url))
|
||||||
disposable.dispose();
|
|
||||||
setTimeout(initApp, 1000);
|
|
||||||
});
|
|
||||||
|
|
||||||
editor = monaco.editor.create($codeMirror, {
|
|
||||||
theme: 'vs-dark',
|
|
||||||
folding: true,
|
|
||||||
automaticLayout: true,
|
|
||||||
quickSuggestions: {
|
|
||||||
other: true,
|
|
||||||
comments: true,
|
|
||||||
strings: true,
|
|
||||||
},
|
|
||||||
model: monaco.editor.createModel(
|
|
||||||
[
|
|
||||||
'var art = new Artplayer({',
|
|
||||||
"\tcontainer: '.artplayer-app',",
|
|
||||||
"\turl: '/assets/sample/video.mp4',",
|
|
||||||
'});',
|
|
||||||
].join('\n'),
|
|
||||||
$ts.checked ? 'typescript' : 'javascript',
|
|
||||||
),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function getURLParameters(url) {
|
|
||||||
return (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(function (a, v) {
|
|
||||||
return (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a;
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getExt(url) {
|
|
||||||
if (url.includes('?')) {
|
|
||||||
return getExt(url.split('?')[0]);
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
$lib.value = libsDecode
|
||||||
|
return Promise.all(libPromise)
|
||||||
|
}
|
||||||
|
|
||||||
if (url.includes('#')) {
|
function runExample(name) {
|
||||||
return getExt(url.split('#')[0]);
|
fetch(`./assets/example/${name}.js`)
|
||||||
}
|
.then((response) => {
|
||||||
|
return response.text()
|
||||||
|
})
|
||||||
|
.then((text) => {
|
||||||
|
editor.setValue(text)
|
||||||
|
runCode()
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return url.trim().toLowerCase().split('.').pop();
|
function loadCode(code, example) {
|
||||||
|
if (example) {
|
||||||
|
runExample(example)
|
||||||
}
|
}
|
||||||
|
else if (code) {
|
||||||
function loadScript(url) {
|
editor.setValue(decodeURIComponent(code).trim())
|
||||||
return new Promise(function (resolve, reject) {
|
runCode()
|
||||||
var define2 = window.define;
|
|
||||||
window.define = undefined;
|
|
||||||
var script = document.createElement('script');
|
|
||||||
script.type = 'text/javascript';
|
|
||||||
script.src = url;
|
|
||||||
script.onload = function () {
|
|
||||||
window.define = define2;
|
|
||||||
resolve(url);
|
|
||||||
};
|
|
||||||
script.onerror = function () {
|
|
||||||
reject(new Error('Loading script failed:' + url));
|
|
||||||
};
|
|
||||||
document.querySelector('head').appendChild(script);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
function loadStyle(url) {
|
runExample('index')
|
||||||
return new Promise(function (resolve, reject) {
|
|
||||||
var link = document.createElement('link');
|
|
||||||
link.rel = 'stylesheet';
|
|
||||||
link.href = url;
|
|
||||||
link.onload = function () {
|
|
||||||
resolve(url);
|
|
||||||
};
|
|
||||||
link.onerror = function () {
|
|
||||||
reject(new Error('Loading style failed:' + url));
|
|
||||||
};
|
|
||||||
document.querySelector('head').appendChild(link);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function loadLib(libs) {
|
function runCode() {
|
||||||
var libPromise = [];
|
[...Artplayer.instances].forEach((art) => {
|
||||||
var libsDecode = decodeURIComponent(libs || '');
|
art.destroy(true)
|
||||||
libsDecode
|
})
|
||||||
.split(/\r?\n/)
|
const value = editor.getValue()
|
||||||
.filter(function (url) {
|
eval(value)
|
||||||
return !loadedLibs.includes(url);
|
window.art = Artplayer.instances[0]
|
||||||
})
|
}
|
||||||
.forEach(function (url) {
|
|
||||||
var ext = getExt(url);
|
function initApp() {
|
||||||
if (ext === 'js') {
|
let _getURLParameters = getURLParameters(window.location.href)
|
||||||
libPromise.push(loadScript(url));
|
let code = _getURLParameters.code
|
||||||
} else if (ext === 'css') {
|
let libs = _getURLParameters.libs
|
||||||
libPromise.push(loadStyle(url));
|
example = _getURLParameters.example
|
||||||
}
|
|
||||||
});
|
loadLib(libs)
|
||||||
$lib.value = libsDecode;
|
.then((result) => {
|
||||||
return Promise.all(libPromise);
|
loadedLibs = loadedLibs.concat(result)
|
||||||
|
loadCode(code, example)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function restart() {
|
||||||
|
let libs = encodeURIComponent($lib.value)
|
||||||
|
let code = encodeURIComponent(editor.getValue())
|
||||||
|
let url = `${window.location.origin + window.location.pathname}?libs=${libs}&code=${code}`
|
||||||
|
history.pushState(null, null, url)
|
||||||
|
initApp()
|
||||||
|
}
|
||||||
|
|
||||||
|
function readFile(file) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.onload = () => resolve(reader.result)
|
||||||
|
reader.readAsText(file)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
$run.addEventListener('click', () => {
|
||||||
|
restart()
|
||||||
|
})
|
||||||
|
|
||||||
|
$popups.addEventListener('click', function (event) {
|
||||||
|
if (event.target === this) {
|
||||||
|
this.style.display = 'none'
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
function runExample(name) {
|
$prod.addEventListener('change', () => {
|
||||||
fetch('./assets/example/' + name + '.js')
|
localStorage.setItem('prod', $prod.checked ? 'true' : 'false')
|
||||||
.then(function (response) {
|
window.location.reload()
|
||||||
return response.text();
|
})
|
||||||
})
|
|
||||||
.then(function (text) {
|
$ts.addEventListener('change', () => {
|
||||||
editor.setValue(text);
|
localStorage.setItem('ts', $ts.checked ? 'true' : 'false')
|
||||||
runCode();
|
window.location.reload()
|
||||||
})
|
})
|
||||||
.catch(function (err) {
|
|
||||||
console.error(err);
|
$code.addEventListener('change', () => {
|
||||||
});
|
localStorage.setItem('code', $code.checked ? 'true' : 'false')
|
||||||
|
window.location.reload()
|
||||||
|
})
|
||||||
|
|
||||||
|
$log.addEventListener('change', () => {
|
||||||
|
localStorage.setItem('log', $log.checked ? 'true' : 'false')
|
||||||
|
window.location.reload()
|
||||||
|
})
|
||||||
|
|
||||||
|
$file.addEventListener('change', async () => {
|
||||||
|
for (let index = 0; index < $file.files.length; index++) {
|
||||||
|
const file = $file.files[index]
|
||||||
|
const name = file.name.toLowerCase().trim()
|
||||||
|
if (name.endsWith('.css')) {
|
||||||
|
const text = await readFile(file)
|
||||||
|
const $style = document.createElement('style')
|
||||||
|
$style.textContent = text
|
||||||
|
document.body.appendChild($style)
|
||||||
|
$lib.value = `\n[${name}]`
|
||||||
|
$lib.value = $lib.value.trim()
|
||||||
|
}
|
||||||
|
if (name.endsWith('.js')) {
|
||||||
|
const text = await readFile(file)
|
||||||
|
const $script = document.createElement('script')
|
||||||
|
$script.textContent = text
|
||||||
|
document.body.appendChild($script)
|
||||||
|
$lib.value = `\n[${name}]`
|
||||||
|
$lib.value = $lib.value.trim()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
function loadCode(code, example) {
|
window.addEventListener('error', (err) => {
|
||||||
if (example) {
|
console.error(err)
|
||||||
runExample(example);
|
})
|
||||||
} else if (code) {
|
|
||||||
editor.setValue(decodeURIComponent(code).trim());
|
window.addEventListener('unhandledrejection', (err) => {
|
||||||
runCode();
|
console.error(err)
|
||||||
} else {
|
})
|
||||||
runExample('index');
|
|
||||||
}
|
document.addEventListener('keydown', (event) => {
|
||||||
|
if ((event.ctrlKey || event.metaKey) && event.key === 's') {
|
||||||
|
event.preventDefault()
|
||||||
|
restart()
|
||||||
}
|
}
|
||||||
|
})
|
||||||
function runCode() {
|
})()
|
||||||
[...Artplayer.instances].forEach(function (art) {
|
|
||||||
art.destroy(true);
|
|
||||||
});
|
|
||||||
const value = editor.getValue();
|
|
||||||
eval(value);
|
|
||||||
window.art = Artplayer.instances[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
function initApp() {
|
|
||||||
var _getURLParameters = getURLParameters(window.location.href),
|
|
||||||
code = _getURLParameters.code,
|
|
||||||
libs = _getURLParameters.libs;
|
|
||||||
example = _getURLParameters.example;
|
|
||||||
|
|
||||||
loadLib(libs)
|
|
||||||
.then(function (result) {
|
|
||||||
loadedLibs = loadedLibs.concat(result);
|
|
||||||
loadCode(code, example);
|
|
||||||
})
|
|
||||||
.catch(function (err) {
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function restart() {
|
|
||||||
var libs = encodeURIComponent($lib.value);
|
|
||||||
var code = encodeURIComponent(editor.getValue());
|
|
||||||
var url = window.location.origin + window.location.pathname + '?libs=' + libs + '&code=' + code;
|
|
||||||
history.pushState(null, null, url);
|
|
||||||
initApp();
|
|
||||||
}
|
|
||||||
|
|
||||||
function readFile(file) {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const reader = new FileReader();
|
|
||||||
reader.onload = () => resolve(reader.result);
|
|
||||||
reader.readAsText(file);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
$run.addEventListener('click', function () {
|
|
||||||
restart();
|
|
||||||
});
|
|
||||||
|
|
||||||
$popups.addEventListener('click', function (event) {
|
|
||||||
if (event.target === this) {
|
|
||||||
this.style.display = 'none';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$prod.addEventListener('change', function () {
|
|
||||||
localStorage.setItem('prod', $prod.checked ? 'true' : 'false');
|
|
||||||
window.location.reload();
|
|
||||||
});
|
|
||||||
|
|
||||||
$ts.addEventListener('change', function () {
|
|
||||||
localStorage.setItem('ts', $ts.checked ? 'true' : 'false');
|
|
||||||
window.location.reload();
|
|
||||||
});
|
|
||||||
|
|
||||||
$code.addEventListener('change', function () {
|
|
||||||
localStorage.setItem('code', $code.checked ? 'true' : 'false');
|
|
||||||
window.location.reload();
|
|
||||||
});
|
|
||||||
|
|
||||||
$log.addEventListener('change', function () {
|
|
||||||
localStorage.setItem('log', $log.checked ? 'true' : 'false');
|
|
||||||
window.location.reload();
|
|
||||||
});
|
|
||||||
|
|
||||||
$file.addEventListener('change', async function () {
|
|
||||||
for (let index = 0; index < $file.files.length; index++) {
|
|
||||||
const file = $file.files[index];
|
|
||||||
const name = file.name.toLowerCase().trim()
|
|
||||||
if (name.endsWith('.css')) {
|
|
||||||
const text = await readFile(file);
|
|
||||||
const $style = document.createElement('style');
|
|
||||||
$style.textContent = text;
|
|
||||||
document.body.appendChild($style);
|
|
||||||
$lib.value = `\n[${name}]`;
|
|
||||||
$lib.value = $lib.value.trim();
|
|
||||||
}
|
|
||||||
if (name.endsWith('.js')) {
|
|
||||||
const text = await readFile(file);
|
|
||||||
const $script = document.createElement('script');
|
|
||||||
$script.textContent = text;
|
|
||||||
document.body.appendChild($script);
|
|
||||||
$lib.value = `\n[${name}]`;
|
|
||||||
$lib.value = $lib.value.trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
window.addEventListener('error', function (err) {
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
window.addEventListener('unhandledrejection', function (err) {
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener('keydown', function (event) {
|
|
||||||
if ((event.ctrlKey || event.metaKey) && event.key === 's') {
|
|
||||||
event.preventDefault();
|
|
||||||
restart();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
interface Option {
|
||||||
|
width?: number
|
||||||
|
height?: number
|
||||||
|
placeholder?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Result {
|
||||||
|
name: 'artplayerPluginPip'
|
||||||
|
}
|
||||||
|
|
||||||
|
declare const artplayerPluginPip: (option: Option) => (art: Artplayer) => Result
|
||||||
|
|
||||||
|
export default artplayerPluginPip
|
||||||
|
|
||||||
|
export = artplayerPluginPip;
|
||||||
|
export as namespace artplayerPluginPip;
|
||||||
Vendored
+2
@@ -1054,6 +1054,8 @@ export interface ComponentOption {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export type { Config, Events, I18n, Icons, Option, Player, Setting, SettingOption, Subtitle, Template, Utils }
|
||||||
|
|
||||||
export default class Artplayer extends Player {
|
export default class Artplayer extends Player {
|
||||||
constructor(option: Option, readyCallback?: (this: Artplayer, art: Artplayer) => unknown)
|
constructor(option: Option, readyCallback?: (this: Artplayer, art: Artplayer) => unknown)
|
||||||
|
|
||||||
|
|||||||
@@ -111,6 +111,9 @@
|
|||||||
<a
|
<a
|
||||||
href="/?libs=./uncompiled/artplayer-plugin-asr/index.js&example=asr">artplayer-plugin-asr</a>
|
href="/?libs=./uncompiled/artplayer-plugin-asr/index.js&example=asr">artplayer-plugin-asr</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="/?libs=./uncompiled/artplayer-plugin-pip/index.js&example=pip">artplayer-plugin-pip</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="title">Proxys</li>
|
<li class="title">Proxys</li>
|
||||||
|
|||||||
@@ -0,0 +1,321 @@
|
|||||||
|
// modules are defined as an array
|
||||||
|
// [ module function, map of requires ]
|
||||||
|
//
|
||||||
|
// map of requires is short require name -> numeric require
|
||||||
|
//
|
||||||
|
// anything defined in a previous bundle is accessed via the
|
||||||
|
// orig method which is the require for previous bundles
|
||||||
|
|
||||||
|
(function (
|
||||||
|
modules,
|
||||||
|
entry,
|
||||||
|
mainEntry,
|
||||||
|
parcelRequireName,
|
||||||
|
externals,
|
||||||
|
distDir,
|
||||||
|
publicUrl,
|
||||||
|
devServer
|
||||||
|
) {
|
||||||
|
/* eslint-disable no-undef */
|
||||||
|
var globalObject =
|
||||||
|
typeof globalThis !== 'undefined'
|
||||||
|
? globalThis
|
||||||
|
: typeof self !== 'undefined'
|
||||||
|
? self
|
||||||
|
: typeof window !== 'undefined'
|
||||||
|
? window
|
||||||
|
: typeof global !== 'undefined'
|
||||||
|
? global
|
||||||
|
: {};
|
||||||
|
/* eslint-enable no-undef */
|
||||||
|
|
||||||
|
// Save the require from previous bundle to this closure if any
|
||||||
|
var previousRequire =
|
||||||
|
typeof globalObject[parcelRequireName] === 'function' &&
|
||||||
|
globalObject[parcelRequireName];
|
||||||
|
|
||||||
|
var importMap = previousRequire.i || {};
|
||||||
|
var cache = previousRequire.cache || {};
|
||||||
|
// Do not use `require` to prevent Webpack from trying to bundle this call
|
||||||
|
var nodeRequire =
|
||||||
|
typeof module !== 'undefined' &&
|
||||||
|
typeof module.require === 'function' &&
|
||||||
|
module.require.bind(module);
|
||||||
|
|
||||||
|
function newRequire(name, jumped) {
|
||||||
|
if (!cache[name]) {
|
||||||
|
if (!modules[name]) {
|
||||||
|
if (externals[name]) {
|
||||||
|
return externals[name];
|
||||||
|
}
|
||||||
|
// if we cannot find the module within our internal map or
|
||||||
|
// cache jump to the current global require ie. the last bundle
|
||||||
|
// that was added to the page.
|
||||||
|
var currentRequire =
|
||||||
|
typeof globalObject[parcelRequireName] === 'function' &&
|
||||||
|
globalObject[parcelRequireName];
|
||||||
|
if (!jumped && currentRequire) {
|
||||||
|
return currentRequire(name, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are other bundles on this page the require from the
|
||||||
|
// previous one is saved to 'previousRequire'. Repeat this as
|
||||||
|
// many times as there are bundles until the module is found or
|
||||||
|
// we exhaust the require chain.
|
||||||
|
if (previousRequire) {
|
||||||
|
return previousRequire(name, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try the node require function if it exists.
|
||||||
|
if (nodeRequire && typeof name === 'string') {
|
||||||
|
return nodeRequire(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
var err = new Error("Cannot find module '" + name + "'");
|
||||||
|
err.code = 'MODULE_NOT_FOUND';
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
localRequire.resolve = resolve;
|
||||||
|
localRequire.cache = {};
|
||||||
|
|
||||||
|
var module = (cache[name] = new newRequire.Module(name));
|
||||||
|
|
||||||
|
modules[name][0].call(
|
||||||
|
module.exports,
|
||||||
|
localRequire,
|
||||||
|
module,
|
||||||
|
module.exports,
|
||||||
|
globalObject
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache[name].exports;
|
||||||
|
|
||||||
|
function localRequire(x) {
|
||||||
|
var res = localRequire.resolve(x);
|
||||||
|
return res === false ? {} : newRequire(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolve(x) {
|
||||||
|
var id = modules[name][1][x];
|
||||||
|
return id != null ? id : x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Module(moduleName) {
|
||||||
|
this.id = moduleName;
|
||||||
|
this.bundle = newRequire;
|
||||||
|
this.require = nodeRequire;
|
||||||
|
this.exports = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
newRequire.isParcelRequire = true;
|
||||||
|
newRequire.Module = Module;
|
||||||
|
newRequire.modules = modules;
|
||||||
|
newRequire.cache = cache;
|
||||||
|
newRequire.parent = previousRequire;
|
||||||
|
newRequire.distDir = distDir;
|
||||||
|
newRequire.publicUrl = publicUrl;
|
||||||
|
newRequire.devServer = devServer;
|
||||||
|
newRequire.i = importMap;
|
||||||
|
newRequire.register = function (id, exports) {
|
||||||
|
modules[id] = [
|
||||||
|
function (require, module) {
|
||||||
|
module.exports = exports;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only insert newRequire.load when it is actually used.
|
||||||
|
// The code in this file is linted against ES5, so dynamic import is not allowed.
|
||||||
|
// INSERT_LOAD_HERE
|
||||||
|
|
||||||
|
Object.defineProperty(newRequire, 'root', {
|
||||||
|
get: function () {
|
||||||
|
return globalObject[parcelRequireName];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
globalObject[parcelRequireName] = newRequire;
|
||||||
|
|
||||||
|
for (var i = 0; i < entry.length; i++) {
|
||||||
|
newRequire(entry[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mainEntry) {
|
||||||
|
// Expose entry point to Node, AMD or browser globals
|
||||||
|
// Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
|
||||||
|
var mainExports = newRequire(mainEntry);
|
||||||
|
|
||||||
|
// CommonJS
|
||||||
|
if (typeof exports === 'object' && typeof module !== 'undefined') {
|
||||||
|
module.exports = mainExports;
|
||||||
|
|
||||||
|
// RequireJS
|
||||||
|
} else if (typeof define === 'function' && define.amd) {
|
||||||
|
define(function () {
|
||||||
|
return mainExports;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})({"55Mmu":[function(require,module,exports,__globalThis) {
|
||||||
|
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
|
||||||
|
parcelHelpers.defineInteropFlag(exports);
|
||||||
|
parcelHelpers.export(exports, "default", ()=>artplayerPluginPip);
|
||||||
|
function artplayerPluginPip(userOptions = {}) {
|
||||||
|
const options = {
|
||||||
|
width: 480,
|
||||||
|
height: 270,
|
||||||
|
placeholder: `Playing in Document Picture-in-Picture`,
|
||||||
|
...userOptions
|
||||||
|
};
|
||||||
|
return (art)=>{
|
||||||
|
if (!('documentPictureInPicture' in window)) {
|
||||||
|
art.notice.show = 'Document Picture-in-Picture is not supported';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { proxy, icons, i18n, template: { $container }, constructor: { utils: { append, tooltip } } } = art;
|
||||||
|
const state = {
|
||||||
|
win: null,
|
||||||
|
originalParent: null,
|
||||||
|
originalNext: null,
|
||||||
|
currentDoc: null,
|
||||||
|
placeholder: null
|
||||||
|
};
|
||||||
|
function copyStylesTo(targetDoc) {
|
||||||
|
const baseStyle = `
|
||||||
|
html, body { margin:0; padding:0; width:100%; height:100%; background:#000; overflow:hidden; }
|
||||||
|
#__art_dpip_root { position:absolute; inset:0; display:flex; }
|
||||||
|
#__art_dpip_root > * { width:100% !important; height:100% !important; }
|
||||||
|
`;
|
||||||
|
const $style = document.querySelector('#artplayer-style');
|
||||||
|
const clone = targetDoc.createElement('style');
|
||||||
|
clone.textContent = baseStyle + $style.textContent;
|
||||||
|
targetDoc.head.appendChild(clone);
|
||||||
|
const meta = targetDoc.createElement('meta');
|
||||||
|
meta.name = 'viewport';
|
||||||
|
meta.content = 'width=device-width,initial-scale=1';
|
||||||
|
targetDoc.head.appendChild(meta);
|
||||||
|
}
|
||||||
|
async function open() {
|
||||||
|
if (state.win) return;
|
||||||
|
try {
|
||||||
|
const pipWin = await window.documentPictureInPicture.requestWindow({
|
||||||
|
width: options.width,
|
||||||
|
height: options.height
|
||||||
|
});
|
||||||
|
state.win = pipWin;
|
||||||
|
state.currentDoc = pipWin.document;
|
||||||
|
state.placeholder = document.createElement('div');
|
||||||
|
state.placeholder.className = 'artplayer-pip-placeholder';
|
||||||
|
state.placeholder.style.cssText = `display:flex;justify-content:center;align-items:center;width:100%;height:100%;`;
|
||||||
|
state.placeholder.textContent = options.placeholder;
|
||||||
|
state.originalParent = $container.parentNode;
|
||||||
|
state.originalNext = $container.nextSibling;
|
||||||
|
state.originalParent.insertBefore(state.placeholder, state.originalNext);
|
||||||
|
const root = pipWin.document.createElement('div');
|
||||||
|
root.id = '__art_dpip_root';
|
||||||
|
pipWin.document.body.appendChild(root);
|
||||||
|
copyStylesTo(pipWin.document);
|
||||||
|
const adopted = pipWin.document.adoptNode($container);
|
||||||
|
root.appendChild(adopted);
|
||||||
|
state.currentDoc = pipWin.document;
|
||||||
|
const onResize = ()=>art.resize?.();
|
||||||
|
const onPageHide = ()=>close();
|
||||||
|
pipWin.addEventListener('resize', onResize);
|
||||||
|
pipWin.addEventListener('pagehide', onPageHide);
|
||||||
|
state.cleanup = ()=>{
|
||||||
|
pipWin.removeEventListener('resize', onResize);
|
||||||
|
pipWin.removeEventListener('pagehide', onPageHide);
|
||||||
|
};
|
||||||
|
art.emit('document-pip', true);
|
||||||
|
} catch (err) {
|
||||||
|
art.notice.show = 'Document Picture-in-Picture open failed';
|
||||||
|
console.warn('[artplayer-plugin-pip] open failed:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function restoreToOriginalDocument() {
|
||||||
|
if (!state.placeholder) return;
|
||||||
|
const backDoc = state.placeholder.ownerDocument || document;
|
||||||
|
const adoptedBack = backDoc.adoptNode($container);
|
||||||
|
state.originalParent.insertBefore(adoptedBack, state.placeholder);
|
||||||
|
state.placeholder.remove();
|
||||||
|
state.placeholder = null;
|
||||||
|
state.currentDoc = backDoc;
|
||||||
|
}
|
||||||
|
function close() {
|
||||||
|
if (!state.win) return;
|
||||||
|
try {
|
||||||
|
state.cleanup?.();
|
||||||
|
restoreToOriginalDocument();
|
||||||
|
state.win.close();
|
||||||
|
state.win = null;
|
||||||
|
art.emit('document-pip', false);
|
||||||
|
} catch (err) {
|
||||||
|
art.notice.show = 'Document Picture-in-Picture close failed';
|
||||||
|
console.warn('[artplayer-plugin-pip] close failed:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function toggle() {
|
||||||
|
if (state.win) close();
|
||||||
|
else open();
|
||||||
|
}
|
||||||
|
art.controls.add({
|
||||||
|
name: 'document-pip',
|
||||||
|
position: 'right',
|
||||||
|
index: 40,
|
||||||
|
tooltip: art.i18n.get('PIP Mode'),
|
||||||
|
mounted: ($control)=>{
|
||||||
|
append($control, icons.pip);
|
||||||
|
proxy($control, 'click', toggle);
|
||||||
|
art.on('document-pip', (value)=>{
|
||||||
|
tooltip($control, i18n.get(value ? 'Exit PIP Mode' : 'PIP Mode'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
art.on('destroy', close);
|
||||||
|
return {
|
||||||
|
name: 'artplayerPluginPip',
|
||||||
|
open,
|
||||||
|
close,
|
||||||
|
toggle
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (typeof window !== 'undefined') window.artplayerPluginPip = artplayerPluginPip;
|
||||||
|
|
||||||
|
},{"@parcel/transformer-js/src/esmodule-helpers.js":"8oCsH"}],"8oCsH":[function(require,module,exports,__globalThis) {
|
||||||
|
exports.interopDefault = function(a) {
|
||||||
|
return a && a.__esModule ? a : {
|
||||||
|
default: a
|
||||||
|
};
|
||||||
|
};
|
||||||
|
exports.defineInteropFlag = function(a) {
|
||||||
|
Object.defineProperty(a, '__esModule', {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
};
|
||||||
|
exports.exportAll = function(source, dest) {
|
||||||
|
Object.keys(source).forEach(function(key) {
|
||||||
|
if (key === 'default' || key === '__esModule' || Object.prototype.hasOwnProperty.call(dest, key)) return;
|
||||||
|
Object.defineProperty(dest, key, {
|
||||||
|
enumerable: true,
|
||||||
|
get: function() {
|
||||||
|
return source[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return dest;
|
||||||
|
};
|
||||||
|
exports.export = function(dest, destName, get) {
|
||||||
|
Object.defineProperty(dest, destName, {
|
||||||
|
enumerable: true,
|
||||||
|
get: get
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
},{}]},["55Mmu"], "55Mmu", "parcelRequire4dc0", {})
|
||||||
|
|
||||||
|
//# sourceMappingURL=index.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"mappings":"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","sources":["packages/artplayer-plugin-pip/src/index.js","node_modules/@parcel/transformer-js/src/esmodule-helpers.js"],"sourcesContent":["export default function artplayerPluginPip(userOptions = {}) {\n const options = {\n width: 480,\n height: 270,\n placeholder: `Playing in Document Picture-in-Picture`,\n ...userOptions,\n }\n\n return (art) => {\n if (!('documentPictureInPicture' in window)) {\n art.notice.show = 'Document Picture-in-Picture is not supported'\n return\n }\n\n const { proxy, icons, i18n, template: { $container }, constructor: { utils: { append, tooltip } } } = art\n\n const state = {\n win: null,\n originalParent: null,\n originalNext: null,\n currentDoc: null,\n placeholder: null,\n }\n\n function copyStylesTo(targetDoc) {\n const baseStyle = `\n html, body { margin:0; padding:0; width:100%; height:100%; background:#000; overflow:hidden; }\n #__art_dpip_root { position:absolute; inset:0; display:flex; }\n #__art_dpip_root > * { width:100% !important; height:100% !important; }\n `\n\n const $style = document.querySelector('#artplayer-style')\n const clone = targetDoc.createElement('style')\n clone.textContent = baseStyle + $style.textContent\n targetDoc.head.appendChild(clone)\n\n const meta = targetDoc.createElement('meta')\n meta.name = 'viewport'\n meta.content = 'width=device-width,initial-scale=1'\n targetDoc.head.appendChild(meta)\n }\n\n async function open() {\n if (state.win)\n return\n\n try {\n consLine truncated
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# artplayer-plugin-pip
|
||||||
|
|
||||||
|
pip plugin for ArtPlayer
|
||||||
|
|
||||||
|
## Demo
|
||||||
|
|
||||||
|
[https://artplayer.org](https://artplayer.org/?libs=./uncompiled/artplayer-plugin-pip/index.js&example=pip)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT © Harvey Zack
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "artplayer-plugin-pip",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "pip plugin for ArtPlayer",
|
||||||
|
"author": "Harvey Zack <laozhaochaguan@gmail.com>",
|
||||||
|
"license": "MIT",
|
||||||
|
"homepage": "https://artplayer.org",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/zhw2590582/ArtPlayer.git"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/zhw2590582/ArtPlayer/issues"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"html5",
|
||||||
|
"video",
|
||||||
|
"player"
|
||||||
|
],
|
||||||
|
"main": "dist/artplayer-plugin-pip.js",
|
||||||
|
"types": "types/artplayer-plugin-pip.d.ts",
|
||||||
|
"legacy": "dist/artplayer-plugin-pip.legacy.js",
|
||||||
|
"browserslist": "last 1 Chrome version"
|
||||||
|
}
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
export default function artplayerPluginPip(userOptions = {}) {
|
||||||
|
const options = {
|
||||||
|
width: 480,
|
||||||
|
height: 270,
|
||||||
|
placeholder: `Playing in Document Picture-in-Picture`,
|
||||||
|
...userOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
return (art) => {
|
||||||
|
if (!('documentPictureInPicture' in window)) {
|
||||||
|
art.notice.show = 'Document Picture-in-Picture is not supported'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const { proxy, icons, i18n, template: { $container }, constructor: { utils: { append, tooltip } } } = art
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
win: null,
|
||||||
|
originalParent: null,
|
||||||
|
originalNext: null,
|
||||||
|
currentDoc: null,
|
||||||
|
placeholder: null,
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyStylesTo(targetDoc) {
|
||||||
|
const baseStyle = `
|
||||||
|
html, body { margin:0; padding:0; width:100%; height:100%; background:#000; overflow:hidden; }
|
||||||
|
#__art_dpip_root { position:absolute; inset:0; display:flex; }
|
||||||
|
#__art_dpip_root > * { width:100% !important; height:100% !important; }
|
||||||
|
`
|
||||||
|
|
||||||
|
const $style = document.querySelector('#artplayer-style')
|
||||||
|
const clone = targetDoc.createElement('style')
|
||||||
|
clone.textContent = baseStyle + $style.textContent
|
||||||
|
targetDoc.head.appendChild(clone)
|
||||||
|
|
||||||
|
const meta = targetDoc.createElement('meta')
|
||||||
|
meta.name = 'viewport'
|
||||||
|
meta.content = 'width=device-width,initial-scale=1'
|
||||||
|
targetDoc.head.appendChild(meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function open() {
|
||||||
|
if (state.win)
|
||||||
|
return
|
||||||
|
|
||||||
|
try {
|
||||||
|
const pipWin = await window.documentPictureInPicture.requestWindow({
|
||||||
|
width: options.width,
|
||||||
|
height: options.height,
|
||||||
|
})
|
||||||
|
|
||||||
|
state.win = pipWin
|
||||||
|
state.currentDoc = pipWin.document
|
||||||
|
|
||||||
|
state.placeholder = document.createElement('div')
|
||||||
|
state.placeholder.className = 'artplayer-pip-placeholder'
|
||||||
|
state.placeholder.style.cssText = `display:flex;justify-content:center;align-items:center;width:100%;height:100%;`
|
||||||
|
state.placeholder.textContent = options.placeholder
|
||||||
|
state.originalParent = $container.parentNode
|
||||||
|
state.originalNext = $container.nextSibling
|
||||||
|
state.originalParent.insertBefore(state.placeholder, state.originalNext)
|
||||||
|
|
||||||
|
const root = pipWin.document.createElement('div')
|
||||||
|
root.id = '__art_dpip_root'
|
||||||
|
pipWin.document.body.appendChild(root)
|
||||||
|
|
||||||
|
copyStylesTo(pipWin.document)
|
||||||
|
|
||||||
|
const adopted = pipWin.document.adoptNode($container)
|
||||||
|
root.appendChild(adopted)
|
||||||
|
state.currentDoc = pipWin.document
|
||||||
|
|
||||||
|
const onResize = () => art.resize?.()
|
||||||
|
const onPageHide = () => close()
|
||||||
|
|
||||||
|
pipWin.addEventListener('resize', onResize)
|
||||||
|
pipWin.addEventListener('pagehide', onPageHide)
|
||||||
|
|
||||||
|
state.cleanup = () => {
|
||||||
|
pipWin.removeEventListener('resize', onResize)
|
||||||
|
pipWin.removeEventListener('pagehide', onPageHide)
|
||||||
|
}
|
||||||
|
|
||||||
|
art.emit('document-pip', true)
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
art.notice.show = 'Document Picture-in-Picture open failed'
|
||||||
|
console.warn('[artplayer-plugin-pip] open failed:', err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function restoreToOriginalDocument() {
|
||||||
|
if (!state.placeholder)
|
||||||
|
return
|
||||||
|
const backDoc = state.placeholder.ownerDocument || document
|
||||||
|
const adoptedBack = backDoc.adoptNode($container)
|
||||||
|
state.originalParent.insertBefore(adoptedBack, state.placeholder)
|
||||||
|
state.placeholder.remove()
|
||||||
|
state.placeholder = null
|
||||||
|
state.currentDoc = backDoc
|
||||||
|
}
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
if (!state.win)
|
||||||
|
return
|
||||||
|
try {
|
||||||
|
state.cleanup?.()
|
||||||
|
restoreToOriginalDocument()
|
||||||
|
state.win.close()
|
||||||
|
state.win = null
|
||||||
|
art.emit('document-pip', false)
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
art.notice.show = 'Document Picture-in-Picture close failed'
|
||||||
|
console.warn('[artplayer-plugin-pip] close failed:', err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
if (state.win) {
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
art.controls.add({
|
||||||
|
name: 'document-pip',
|
||||||
|
position: 'right',
|
||||||
|
index: 40,
|
||||||
|
tooltip: art.i18n.get('PIP Mode'),
|
||||||
|
mounted: ($control) => {
|
||||||
|
append($control, icons.pip)
|
||||||
|
proxy($control, 'click', toggle)
|
||||||
|
art.on('document-pip', (value) => {
|
||||||
|
tooltip($control, i18n.get(value ? 'Exit PIP Mode' : 'PIP Mode'))
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
art.on('destroy', close)
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: 'artplayerPluginPip',
|
||||||
|
open,
|
||||||
|
close,
|
||||||
|
toggle,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
window.artplayerPluginPip = artplayerPluginPip
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
.artplayer-plugin-pip {
|
||||||
|
//
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import type Artplayer from 'artplayer'
|
||||||
|
|
||||||
|
interface Option {
|
||||||
|
width?: number
|
||||||
|
height?: number
|
||||||
|
placeholder?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Result {
|
||||||
|
name: 'artplayerPluginPip'
|
||||||
|
}
|
||||||
|
|
||||||
|
declare const artplayerPluginPip: (option: Option) => (art: Artplayer) => Result
|
||||||
|
|
||||||
|
export default artplayerPluginPip
|
||||||
Reference in new issue
Block a user