feat: artplayerProxyCanvas

This commit is contained in:
Harvey Zack committed 2024-09-15 10:39:11 +08:00
1 parent 22dce779d1
commit 710f9477f8
4 files changed
+173 -182

No files matched your search

+90 -88
View File
@@ -1,74 +1,83 @@
export default function artplayerProxyCanvas(callback) {
export default function artplayerProxyCanvas() {
return (art) => {
const { option, constructor } = art;
const { createElement, def, append } = constructor.utils;
const { createElement, def } = constructor.utils;
let animationId = null;
const canvas = createElement('canvas');
const ctx = canvas.getContext('2d');
const video = createElement('video');
video.playsInline = true;
window.video = video;
const track = createElement('track');
track.default = true;
track.kind = 'metadata';
append(video, track);
let animationFrame = null;
const canvasProperties = {};
const canvasKeys = ['width', 'height'];
const { propertys, methods, prototypes, events } = constructor.config;
const keys = [...propertys, ...methods, ...prototypes];
const videoKeys = [...propertys, ...methods, ...prototypes];
const originalCanvasProperties = {};
['width', 'height'].forEach((prop) => {
originalCanvasProperties[prop] = Object.getOwnPropertyDescriptor(HTMLCanvasElement.prototype, prop);
});
initCanvasProperties();
proxyVideoToCanvas();
setupEventListeners();
setupArtPlayerEvents();
keys.forEach((key) => {
if (key === 'width' || key === 'height') {
def(canvas, key, {
get() {
return originalCanvasProperties[key].get.call(this);
},
set(value) {
originalCanvasProperties[key].set.call(this, value);
video[key] = value;
},
});
} else {
def(canvas, key, {
get() {
const value = video[key];
return typeof value === 'function' ? value.bind(video) : value;
},
set(value) {
video[key] = value;
},
return canvas;
function initCanvasProperties() {
canvasKeys.forEach((prop) => {
canvasProperties[prop] = Object.getOwnPropertyDescriptor(HTMLCanvasElement.prototype, prop);
});
}
function proxyVideoToCanvas() {
videoKeys.forEach((key) => {
if (canvasKeys.includes(key)) {
def(canvas, key, {
get() {
return canvasProperties[key].get.call(this);
},
set(value) {
canvasProperties[key].set.call(this, value);
},
});
} else {
def(canvas, key, {
get() {
const value = video[key];
return typeof value === 'function' ? value.bind(video) : value;
},
set(value) {
video[key] = value;
},
});
}
});
}
function setupEventListeners() {
setTimeout(() => {
events.forEach((event) => {
art.proxy(video, event, (event) => {
art.emit(`video:${event.type}`, event);
});
});
});
}
async function draw() {
try {
const bitmap = await createImageBitmap(video);
ctx.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
bitmap.close();
art.emit('artplayerProxyCanvas:draw', ctx);
} catch (error) {
art.emit('artplayerProxyCanvas:error', error);
}
});
}
setTimeout(() => {
for (let index = 0; index < events.length; index++) {
const event = events[index];
art.proxy(video, event, (event) => {
art.emit(`video:${event.type}`, event);
});
}
});
async function animation() {
await draw();
animationId = requestAnimationFrame(animation);
}
const draw = () => {
console.log(video.currentTime);
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
art.emit('artplayerProxyCanvas:draw', ctx);
};
const animation = () => {
draw();
animationFrame = requestAnimationFrame(animation);
};
const resize = () => {
function resize() {
const player = art.template?.$player;
if (!player || option.autoSize) return;
@@ -95,39 +104,32 @@ export default function artplayerProxyCanvas(callback) {
Object.assign(canvas.style, {
padding: `${paddingTop}px ${paddingLeft}px`,
});
};
art.on('video:loadedmetadata', async () => {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
});
art.on('video:play', () => {
console.log('video:play');
cancelAnimationFrame(animationFrame);
animationFrame = requestAnimationFrame(animation);
});
art.on('video:pause', () => {
cancelAnimationFrame(animationFrame);
});
art.on('resize', () => {
resize();
draw();
});
art.on('destroy', () => {
cancelAnimationFrame(animationFrame);
});
if (typeof callback === 'function') {
callback.call(art, video, option.url, art);
} else {
video.src = option.url;
}
return canvas;
function setupArtPlayerEvents() {
art.on('video:loadedmetadata', async () => {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
});
art.on('video:play', () => {
cancelAnimationFrame(animationId);
animationId = requestAnimationFrame(animation);
});
art.on('video:pause', () => {
cancelAnimationFrame(animationId);
});
art.on('resize', () => {
resize();
draw();
});
art.on('destroy', () => {
cancelAnimationFrame(animationId);
});
}
};
}