Add artplayer-plugin-ambilight package and demo

This commit is contained in:
Harvey Zack committed 2024-10-19 13:53:36 +08:00
1 parent 406d71b53c
commit 5dfe50c719
10 files changed
+501

No files matched your search

@@ -0,0 +1,11 @@
# artplayer-plugin-ambilight
ambilight plugin for ArtPlayer
## Demo
[https://artplayer.org](https://artplayer.org/?libs=./uncompiled/artplayer-plugin-ambilight/index.js&example=ambilight)
## License
MIT © Harvey Zack
@@ -0,0 +1,24 @@
{
"license": "MIT",
"version": "1.0.0",
"name": "artplayer-plugin-ambilight",
"types": "types/artplayer-plugin-ambilight.d.ts",
"description": "ambilight plugin for ArtPlayer",
"main": "dist/artplayer-plugin-ambilight.js",
"legacy": "dist/artplayer-plugin-ambilight.legacy.js",
"author": "Harvey Zack <laozhaochaguan@gmail.com>",
"browserslist": "last 1 Chrome version",
"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"
]
}
@@ -0,0 +1,119 @@
export default function artplayerPluginAmbilight(option = {}) {
return (art) => {
const { $video } = art.template;
const { createElement, addClass, setStyles } = art.constructor.utils;
const { blur = '50px', opacity = 0.5, frequency = 10, duration = 0.3 } = option;
const $ambilight = createElement('div');
const gridItems = createGridItems($ambilight);
setupAmbilight($ambilight, $video);
setupGridItems(gridItems, blur, opacity, duration);
const updateColors = createColorUpdater($video, gridItems, frequency);
let animationFrameId = null;
function start() {
if (!animationFrameId) {
updateColors();
}
}
function stop() {
if (animationFrameId) {
cancelAnimationFrame(animationFrameId);
animationFrameId = null;
}
}
art.on('ready', start);
art.on('destroy', stop);
return {
name: 'artplayerPluginAmbilight',
start,
stop,
};
function createGridItems($ambilight) {
$ambilight.innerHTML = Array(9).fill('<div></div>').join('');
return Array.from($ambilight.children);
}
function setupAmbilight($ambilight, $video) {
addClass($ambilight, 'artplayer-plugin-ambilight');
$video.parentNode.insertBefore($ambilight, $video);
setStyles($ambilight, {
position: 'absolute',
top: 0,
left: 0,
zIndex: 9,
inset: 0,
display: 'grid',
gridTemplateColumns: '1fr 1fr 1fr',
gridTemplateRows: '1fr 1fr 1fr',
});
}
function setupGridItems(gridItems, blur, opacity, duration) {
gridItems.forEach(($item) => {
setStyles($item, {
opacity,
filter: `blur(${blur})`,
transition: `background-color ${duration}s ease`,
});
});
}
function createColorUpdater($video, gridItems, frequency) {
const canvas = createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 3;
canvas.height = 3;
function getAverageColor(x, y, w, h) {
ctx.drawImage($video, x, y, w, h, 0, 0, 1, 1);
const [r, g, b] = ctx.getImageData(0, 0, 1, 1).data;
return `rgb(${r}, ${g}, ${b})`;
}
let lastUpdateTime = 0;
return function updateColors() {
const now = performance.now();
if (now - lastUpdateTime < 1000 / frequency || !art.playing) {
animationFrameId = requestAnimationFrame(updateColors);
return;
}
lastUpdateTime = now;
const w = $video.videoWidth / 3;
const h = $video.videoHeight / 3;
const colors = [
[0, 0],
[w, 0],
[2 * w, 0],
[0, h],
[w, h],
[2 * w, h],
[0, 2 * h],
[w, 2 * h],
[2 * w, 2 * h],
].map(([x, y]) => getAverageColor(x, y, w, h));
gridItems.forEach(($item, index) => {
$item.style.backgroundColor = colors[index];
});
animationFrameId = requestAnimationFrame(updateColors);
};
}
};
}
if (typeof window !== 'undefined') {
window['artplayerPluginAmbilight'] = artplayerPluginAmbilight;
}
@@ -0,0 +1,20 @@
import type Artplayer from 'artplayer';
export = artplayerPluginAmbilight;
export as namespace artplayerPluginAmbilight;
type Option = {
blur: string;
opacity: number;
frequency: number;
zIndex: number;
duration: number;
};
type Result = {
name: 'artplayerPluginAmbilight';
start: () => void;
stop: () => void;
};
declare const artplayerPluginAmbilight: (option: Option) => (art: Artplayer) => Result;
@@ -77,6 +77,7 @@ const config = {
{ text: 'Chromecast', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-chromecast/index.js&example=chromecast'},
{ text: 'Vast 广告', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-vast/index.js&example=vast'},
{ text: '视频章节', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-chapter/index.js&example=chapter'},
{ text: '视频背光', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-ambilight/index.js&example=ambilight'},
]
},
{
@@ -144,6 +145,7 @@ const config = {
{ text: 'Chromecast', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-chromecast/index.js&example=chromecast'},
{ text: 'Vast', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-vast/index.js&example=vast'},
{ text: 'Video Chapters', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-chapter/index.js&example=chapter'},
{ text: 'Video Ambilight', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-ambilight/index.js&example=ambilight'},
]
},
{