diff --git a/dev/convert.html b/dev/convert.html
index bc1f9d1..79b7ae3 100644
--- a/dev/convert.html
+++ b/dev/convert.html
@@ -48,6 +48,7 @@
target
});
+ let ctx = null;
const conversion = await Mediabunny.Conversion.init({
input: new Mediabunny.Input({
formats: Mediabunny.ALL_FORMATS,
@@ -56,6 +57,7 @@
output,
audio: (_, n) => ({
discard: n > 1,
+ //codec: 'opus',
/*
process: (sample) => {
return sample;
@@ -97,7 +99,7 @@
},
*/
video: () => ({
- /*
+ //discard: true,
process: (sample) => {
if (!ctx) {
// Create a canvas for image compositing
@@ -108,13 +110,14 @@
ctx = canvas.getContext('2d');
}
+ console.log(ctx.canvas.width, ctx.canvas.height);
+
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
- sample.draw(ctx, 0, 0);
- ctx.drawImage(watermark, 32, 32);
+ sample.drawWithFit(ctx, { fit: 'fill' });
+ //ctx.drawImage(watermark, 32, 32);
return ctx.canvas;
},
- */
//width: 300,
//alpha: 'keep',
//width: 320,
@@ -170,8 +173,8 @@
}
},
trim: {
- start: 0,
- end: 10
+ //start: 0,
+ //end: 10
},
});
console.log(conversion);
diff --git a/src/conversion.ts b/src/conversion.ts
index abf820a..0cabe1a 100644
--- a/src/conversion.ts
+++ b/src/conversion.ts
@@ -182,7 +182,8 @@ export type ConversionVideoOptions = {
* corrections.
*
* Must return a {@link VideoSample} or a `CanvasImageSource`, an array of them, or `null` for dropping the frame.
- * When non-timestamped data is returned, the timestamp and duration from the source sample will be used.
+ * When non-timestamped data is returned, the timestamp and duration from the source sample will be used. Rotation
+ * metadata of the returned sample will be ignored.
*
* This function can also be used to manually resize frames. When doing so, you should signal the post-process
* dimensions using the `processedWidth` and `processedHeight` fields, which enables the encoder to better know what
@@ -873,7 +874,10 @@ export class Conversion {
|| trackOptions.process !== undefined;
let needsRerender = width !== originalWidth
|| height !== originalHeight
- || (totalRotation !== 0 && !outputSupportsRotation)
+ // TODO This is suboptimal: Forcing a rerender when both rotation and process are set is not
+ // performance-optimal, but right now there's no other way because we can't change the track rotation
+ // metadata after the output has already started. Should be possible with API changes in v2, though!
+ || (totalRotation !== 0 && (!outputSupportsRotation || trackOptions.process !== undefined))
|| !!crop;
const alpha = trackOptions.alpha ?? 'discard';
diff --git a/src/sample.ts b/src/sample.ts
index 805aebe..35d7800 100644
--- a/src/sample.ts
+++ b/src/sample.ts
@@ -552,7 +552,6 @@ export class VideoSample implements Disposable {
dHeight,
);
- // Restore the previous transformation state
context.restore();
}
@@ -644,6 +643,8 @@ export class VideoSample implements Disposable {
dy = (canvasHeight - newHeight) / 2;
}
+ context.save();
+
const aspectRatioChange = rotation % 180 === 0 ? 1 : newWidth / newHeight;
context.translate(canvasWidth / 2, canvasHeight / 2);
context.rotate(rotation * Math.PI / 180);
@@ -655,6 +656,8 @@ export class VideoSample implements Disposable {
// Important that we don't use .draw() here since that would take rotation into account, but we wanna handle it
// ourselves here
context.drawImage(this.toCanvasImageSource(), sx, sy, sWidth, sHeight, dx, dy, newWidth, newHeight);
+
+ context.restore();
}
/** @internal */