mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-10-02 21:33:52 +02:00
Avoid opaque canvases in case of Firefox (fixes #117)
This commit is contained in:
+10
-3
@@ -18,6 +18,7 @@ import {
|
|||||||
getInt24,
|
getInt24,
|
||||||
getUint24,
|
getUint24,
|
||||||
insertSorted,
|
insertSorted,
|
||||||
|
isFirefox,
|
||||||
isSafari,
|
isSafari,
|
||||||
last,
|
last,
|
||||||
mapAsyncGenerator,
|
mapAsyncGenerator,
|
||||||
@@ -1199,14 +1200,20 @@ export class CanvasSink {
|
|||||||
this._nextCanvasIndex = (this._nextCanvasIndex + 1) % this._canvasPool.length;
|
this._nextCanvasIndex = (this._nextCanvasIndex + 1) % this._canvasPool.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
const context
|
const context = canvas.getContext('2d', {
|
||||||
= canvas.getContext('2d', { alpha: false }) as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;
|
alpha: isFirefox(), // Firefox has VideoFrame glitches with opaque canvases
|
||||||
|
}) as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;
|
||||||
assert(context);
|
assert(context);
|
||||||
|
|
||||||
context.resetTransform();
|
context.resetTransform();
|
||||||
|
|
||||||
if (!canvasIsNew) {
|
if (!canvasIsNew) {
|
||||||
context.clearRect(0, 0, this._width, this._height);
|
if (isFirefox()) {
|
||||||
|
context.fillStyle = 'black';
|
||||||
|
context.fillRect(0, 0, this._width, this._height);
|
||||||
|
} else {
|
||||||
|
context.clearRect(0, 0, this._width, this._height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sample.drawWithFit(context, {
|
sample.drawWithFit(context, {
|
||||||
|
|||||||
+19
-4
@@ -18,7 +18,16 @@ import {
|
|||||||
VideoCodec,
|
VideoCodec,
|
||||||
} from './codec';
|
} from './codec';
|
||||||
import { OutputAudioTrack, OutputSubtitleTrack, OutputTrack, OutputVideoTrack } from './output';
|
import { OutputAudioTrack, OutputSubtitleTrack, OutputTrack, OutputVideoTrack } from './output';
|
||||||
import { assert, assertNever, CallSerializer, clamp, promiseWithResolvers, setInt24, setUint24 } from './misc';
|
import {
|
||||||
|
assert,
|
||||||
|
assertNever,
|
||||||
|
CallSerializer,
|
||||||
|
clamp,
|
||||||
|
isFirefox,
|
||||||
|
promiseWithResolvers,
|
||||||
|
setInt24,
|
||||||
|
setUint24,
|
||||||
|
} from './misc';
|
||||||
import { Muxer } from './muxer';
|
import { Muxer } from './muxer';
|
||||||
import { SubtitleParser } from './subtitles';
|
import { SubtitleParser } from './subtitles';
|
||||||
import { toAlaw, toUlaw } from './pcm';
|
import { toAlaw, toUlaw } from './pcm';
|
||||||
@@ -248,12 +257,18 @@ class VideoEncoderWrapper {
|
|||||||
canvasIsNew = true;
|
canvasIsNew = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const context = this.resizeCanvas.getContext('2d', { alpha: false }) as
|
const context = this.resizeCanvas.getContext('2d', {
|
||||||
CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;
|
alpha: isFirefox(), // Firefox has VideoFrame glitches with opaque canvases
|
||||||
|
}) as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;
|
||||||
assert(context);
|
assert(context);
|
||||||
|
|
||||||
if (!canvasIsNew) {
|
if (!canvasIsNew) {
|
||||||
context.clearRect(0, 0, this.codedWidth, this.codedHeight);
|
if (isFirefox()) {
|
||||||
|
context.fillStyle = 'black';
|
||||||
|
context.fillRect(0, 0, this.codedWidth, this.codedHeight);
|
||||||
|
} else {
|
||||||
|
context.clearRect(0, 0, this.codedWidth, this.codedHeight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
videoSample.drawWithFit(context, { fit: sizeChangeBehavior });
|
videoSample.drawWithFit(context, { fit: sizeChangeBehavior });
|
||||||
|
|||||||
@@ -642,6 +642,15 @@ export const isSafari = () => {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let isFirefoxCache: boolean | null = null;
|
||||||
|
export const isFirefox = () => {
|
||||||
|
if (isFirefoxCache !== null) {
|
||||||
|
return isFirefoxCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isFirefoxCache = typeof navigator !== 'undefined' && navigator.userAgent?.includes('Firefox');
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* T or a promise that resolves to T.
|
* T or a promise that resolves to T.
|
||||||
* @group Miscellaneous
|
* @group Miscellaneous
|
||||||
|
|||||||
+6
-2
@@ -15,6 +15,7 @@ import {
|
|||||||
toDataView,
|
toDataView,
|
||||||
toUint8Array,
|
toUint8Array,
|
||||||
SetRequired,
|
SetRequired,
|
||||||
|
isFirefox,
|
||||||
} from './misc';
|
} from './misc';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -228,7 +229,10 @@ export class VideoSample {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const canvas = new OffscreenCanvas(width, height);
|
const canvas = new OffscreenCanvas(width, height);
|
||||||
const context = canvas.getContext('2d', { alpha: false, willReadFrequently: true });
|
const context = canvas.getContext('2d', {
|
||||||
|
alpha: isFirefox(), // Firefox has VideoFrame glitches with opaque canvases
|
||||||
|
willReadFrequently: true,
|
||||||
|
});
|
||||||
assert(context);
|
assert(context);
|
||||||
|
|
||||||
// Draw it to a canvas
|
// Draw it to a canvas
|
||||||
@@ -343,7 +347,7 @@ export class VideoSample {
|
|||||||
dest.set(this._data);
|
dest.set(this._data);
|
||||||
} else {
|
} else {
|
||||||
const canvas = this._data;
|
const canvas = this._data;
|
||||||
const context = canvas.getContext('2d', { alpha: false });
|
const context = canvas.getContext('2d');
|
||||||
assert(context);
|
assert(context);
|
||||||
|
|
||||||
const imageData = context.getImageData(0, 0, this.codedWidth, this.codedHeight);
|
const imageData = context.getImageData(0, 0, this.codedWidth, this.codedHeight);
|
||||||
|
|||||||
Reference in New Issue
Block a user