mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-27 10:53:50 +02:00
Add longer variant to VideoSample.draw
This commit is contained in:
+13
-6
@@ -16,13 +16,20 @@
|
||||
source
|
||||
});
|
||||
|
||||
const videoTrack = await input.getPrimaryVideoTrack();
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = 1920;
|
||||
canvas.height = 1080;
|
||||
canvas.style.background = 'ghostwhite';
|
||||
const ctx = canvas.getContext('2d');
|
||||
document.body.append(canvas);
|
||||
|
||||
const sink = new Mediabunny.EncodedPacketSink(videoTrack);
|
||||
for await (const packet of sink.packets()) {
|
||||
if (packet.timestamp >= 2) break;
|
||||
console.log(packet);
|
||||
}
|
||||
const videoTrack = await input.getPrimaryVideoTrack();
|
||||
const sink = new Mediabunny.VideoSampleSink(videoTrack);
|
||||
|
||||
const sample = await sink.getSample(3);
|
||||
console.log(sample);
|
||||
|
||||
sample.draw(ctx, 1500, 500, 50, 50, 0, 0);
|
||||
|
||||
/*
|
||||
let timestamps = [];
|
||||
|
||||
@@ -309,17 +309,29 @@ The `VideoFrame` returned by this method **must** be closed separately from the
|
||||
|
||||
---
|
||||
|
||||
It's also common to draw video samples to a `<canvas>` element or an `OffscreenCanvas`. For this, you can use the following method:
|
||||
It's also common to draw video samples to a `<canvas>` element or an `OffscreenCanvas`. For this, you can use the following methods:
|
||||
```ts
|
||||
draw(
|
||||
context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,
|
||||
dx: number,
|
||||
dy: number,
|
||||
dWidth?: number,
|
||||
dHeight?: number,
|
||||
dWidth?: number, // defaults to displayWidth
|
||||
dHeight?: number, // defaults to displayHeight
|
||||
): void;
|
||||
|
||||
draw(
|
||||
context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,
|
||||
sx: number,
|
||||
sy: number,
|
||||
sWidth: number,
|
||||
sHeight: number,
|
||||
dx: number,
|
||||
dy: number,
|
||||
dWidth?: number, // defaults to sWidth
|
||||
dHeight?: number, // defaults to sHeight
|
||||
): void;
|
||||
```
|
||||
This method is similar to [drawImage](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage) and paints the video frame at the given position with the given dimensions. If the dimensions aren't specified, they will default to the display dimensions. This method will automatically draw the frame with the correct rotation based on its `rotation` property.
|
||||
These methods behave like [drawImage](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage) and paint the video frame at the given position with the given dimensions. This method will automatically draw the frame with the correct rotation based on its `rotation` property.
|
||||
|
||||
If you want to draw the raw underlying image to a canvas directly (without respecting the rotation metadata), then you can use the following method:
|
||||
```ts
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "mediabunny",
|
||||
"version": "1.0.6",
|
||||
"version": "1.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "mediabunny",
|
||||
"version": "1.0.6",
|
||||
"version": "1.1.0",
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"@types/dom-mediacapture-transform": "^0.1.11",
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "mediabunny",
|
||||
"author": "Vanilagy",
|
||||
"version": "1.0.6",
|
||||
"version": "1.1.0",
|
||||
"description": "Pure TypeScript media toolkit for reading, writing, and converting media files, directly in the browser.",
|
||||
"type": "module",
|
||||
"main": "./dist/bundles/mediabunny.cjs",
|
||||
|
||||
@@ -737,6 +737,7 @@ class VideoDecoderWrapper extends DecoderWrapper<VideoSample> {
|
||||
// Round the timestamps to the time resolution
|
||||
sample.setTimestamp(Math.round(sample.timestamp * this.timeResolution) / this.timeResolution);
|
||||
sample.setDuration(Math.round(sample.duration * this.timeResolution) / this.timeResolution);
|
||||
sample.setRotation(this.rotation);
|
||||
|
||||
this.onSample(sample);
|
||||
}
|
||||
|
||||
+111
-2
@@ -366,9 +366,79 @@ export class VideoSample {
|
||||
context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,
|
||||
dx: number,
|
||||
dy: number,
|
||||
dWidth: number = this.displayWidth,
|
||||
dHeight: number = this.displayHeight,
|
||||
dWidth?: number,
|
||||
dHeight?: number,
|
||||
): void;
|
||||
/**
|
||||
* Draws the video sample to a 2D canvas context. Rotation metadata will be taken into account.
|
||||
*
|
||||
* @param sx - The x-coordinate of the top left corner of the sub-rectangle of the source image to draw into the
|
||||
* destination context.
|
||||
* @param sy - The y-coordinate of the top left corner of the sub-rectangle of the source image to draw into the
|
||||
* destination context.
|
||||
* @param sWidth - The width of the sub-rectangle of the source image to draw into the destination context.
|
||||
* @param sHeight - The height of the sub-rectangle of the source image to draw into the destination context.
|
||||
* @param dx - The x-coordinate in the destination canvas at which to place the top-left corner of the source image.
|
||||
* @param dy - The y-coordinate in the destination canvas at which to place the top-left corner of the source image.
|
||||
* @param dWidth - The width in pixels with which to draw the image in the destination canvas.
|
||||
* @param dHeight - The height in pixels with which to draw the image in the destination canvas.
|
||||
*/
|
||||
draw(
|
||||
context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,
|
||||
sx: number,
|
||||
sy: number,
|
||||
sWidth: number,
|
||||
sHeight: number,
|
||||
dx: number,
|
||||
dy: number,
|
||||
dWidth?: number,
|
||||
dHeight?: number,
|
||||
): void;
|
||||
draw(
|
||||
context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,
|
||||
arg1: number,
|
||||
arg2: number,
|
||||
arg3?: number,
|
||||
arg4?: number,
|
||||
arg5?: number,
|
||||
arg6?: number,
|
||||
arg7?: number,
|
||||
arg8?: number,
|
||||
) {
|
||||
let sx = 0;
|
||||
let sy = 0;
|
||||
let sWidth = this.displayWidth;
|
||||
let sHeight = this.displayHeight;
|
||||
let dx = 0;
|
||||
let dy = 0;
|
||||
let dWidth = this.displayWidth;
|
||||
let dHeight = this.displayHeight;
|
||||
|
||||
if (arg5 !== undefined) {
|
||||
sx = arg1!;
|
||||
sy = arg2!;
|
||||
sWidth = arg3!;
|
||||
sHeight = arg4!;
|
||||
dx = arg5;
|
||||
dy = arg6!;
|
||||
|
||||
if (arg7 !== undefined) {
|
||||
dWidth = arg7;
|
||||
dHeight = arg8!;
|
||||
} else {
|
||||
dWidth = sWidth;
|
||||
dHeight = sHeight;
|
||||
}
|
||||
} else {
|
||||
dx = arg1;
|
||||
dy = arg2;
|
||||
|
||||
if (arg3 !== undefined) {
|
||||
dWidth = arg3;
|
||||
dHeight = arg4!;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(
|
||||
(typeof CanvasRenderingContext2D !== 'undefined' && context instanceof CanvasRenderingContext2D)
|
||||
|| (
|
||||
@@ -378,6 +448,18 @@ export class VideoSample {
|
||||
)) {
|
||||
throw new TypeError('context must be a CanvasRenderingContext2D or OffscreenCanvasRenderingContext2D.');
|
||||
}
|
||||
if (!Number.isFinite(sx)) {
|
||||
throw new TypeError('sx must be a number.');
|
||||
}
|
||||
if (!Number.isFinite(sy)) {
|
||||
throw new TypeError('sy must be a number.');
|
||||
}
|
||||
if (!Number.isFinite(sWidth) || sWidth < 0) {
|
||||
throw new TypeError('sWidth must be a non-negative number.');
|
||||
}
|
||||
if (!Number.isFinite(sHeight) || sHeight < 0) {
|
||||
throw new TypeError('sHeight must be a non-negative number.');
|
||||
}
|
||||
if (!Number.isFinite(dx)) {
|
||||
throw new TypeError('dx must be a number.');
|
||||
}
|
||||
@@ -395,6 +477,29 @@ export class VideoSample {
|
||||
throw new Error('VideoSample is closed.');
|
||||
}
|
||||
|
||||
// The provided sx,sy,sWidth,sHeight refer to the final rotated image, but that's not actually how the image is
|
||||
// stored. Therefore, we must map these back onto the original, pre-rotation image.
|
||||
if (this.rotation === 90) {
|
||||
[sx, sy, sWidth, sHeight] = [
|
||||
sy,
|
||||
this.codedHeight - sx - sWidth,
|
||||
sHeight,
|
||||
sWidth,
|
||||
];
|
||||
} else if (this.rotation === 180) {
|
||||
[sx, sy] = [
|
||||
this.codedWidth - sx - sWidth,
|
||||
this.codedHeight - sy - sHeight,
|
||||
];
|
||||
} else if (this.rotation === 270) {
|
||||
[sx, sy, sWidth, sHeight] = [
|
||||
this.codedWidth - sy - sHeight,
|
||||
sx,
|
||||
sHeight,
|
||||
sWidth,
|
||||
];
|
||||
}
|
||||
|
||||
const source = this.toCanvasImageSource();
|
||||
|
||||
context.save();
|
||||
@@ -412,6 +517,10 @@ export class VideoSample {
|
||||
|
||||
context.drawImage(
|
||||
source,
|
||||
sx,
|
||||
sy,
|
||||
sWidth,
|
||||
sHeight,
|
||||
-dWidth / 2,
|
||||
-dHeight / 2,
|
||||
dWidth,
|
||||
|
||||
Reference in New Issue
Block a user