I have a canvas that I want to have it's stream and send it to another user by webrtc. I can get the stream of it and show that in video tag.
var canvas = document.createElement("CANVAS");
var stream = canvas.captureStream(25);
var track = stream.getVideoTracks()[0];
console.log(track);
As you can see in track Object there is a property named canvas
. It causes an Error in my code because I use a library that need a MediaStreamTrack
not MediaStreamTrack
that contains a canvas
property.
Is there a way to get rid of that canvas
property?
I've already tried delete the property but it didn't work. And also I used this below code but still doesn't work.
var canvas = document.createElement("CANVAS");
var stream = canvas.captureStream(25);
var track = stream.getVideoTracks()[0];
var {canvas, ...rest} = track;
console.log(canvas);
console.log(rest);
I think the CanvasCaptureMediaStreamTrack
is a readOnly variable.
What can I do?
It would probably be good to update your library, because if it fails because of that added property, it will fail again some time in the future when new properties will be added to this interface.
You can overwrite this property and set it to undefined
, using Object.defineProperty
:
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const stream = canvas.captureStream(25);
const track = stream.getVideoTracks()[0];
Object.defineProperty( track, "canvas", { value: undefined } );
console.log( track.canvas, "canvas" in track ); // undefined true
You can delete this property on the CanvasCaptureMediaStreamTrack
prototype (and thus remove it from all instances):
if( window.CanvasCaptureMediaStreamTrack ) {
delete CanvasCaptureMediaStreamTrack.prototype.canvas
}
else { // Firefox has this property on `stream`
delete CanvasCaptureMediaStream.prototype.canvas;
}
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const stream = canvas.captureStream(25);
const track = stream.getVideoTracks()[0];
console.log( track.canvas, "canvas" in track ); // undefined false
You could even pass a Proxy instead,
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const stream = canvas.captureStream(25);
const track = stream.getVideoTracks()[0];
const prox = new Proxy( track, {
get( target, key ) {
if( key === "canvas" ) {
return undefined;
}
return target[ key ];
}
});
console.log( prox.canvas, "canvas" in prox, prox.kind ); // undefined false video
But really, that you have to resort on this is just very bad smell. For one I highly doubt that your library will work with current Firefox which still uses a deprecated CanvasCaptureMediaStream
interface instead of the CanvasCaptureMediaStreamTrack
one.
And if you really need to convert a CanvasCaptureMediaStreamTrack
to a bare MediaStreamTrack
, then you can make the browser work twice as needed:
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const stream = canvas.captureStream(25);
// we need to draw something on the canvas
// for the <video> to start reading our MediaStream
ctx.fillRect(10,10,10,10);
const video = document.createElement("video");
video.muted = true;
video.srcObject = stream;
video.play().then(() => {
const video_stream = video.captureStream ? video.captureStream() :
video.mozCaptureStream();
const track = video_stream.getVideoTracks()[0]
console.log( track.toString(), track ); // [object MediaStreamTrack], {...}
}).catch(console.error);