Скажем, у меня есть холст:
<canvas height = "500" width = "500"></canvas>
Я могу захватить видео с него с помощью captureStream.
Итак, если у меня есть элемент видео, я могу передать ему захваченный поток и увидеть, что я рисую, отраженное в видео:
<video autoplay height = "500" width = "500"></video>
const video = document.querySelector("video");
const canvas = document.querySelector("canvas");
const stream = canvas.captureStream(25);
video.srcObject = stream;
video.play();
Я также могу получить OffscreenCanvas из этого холста и перенести в другой кадр.
const iframe = document.querySelector("iframe");
const offscreen = canvas.transferControlToOffscreen();
iframe.contentWindow.postMessage(
{
type: "canvasTransfer",
canvas: offscreen
},
"*",
[offscreen]
);
И выполните операцию рисования из iframe в песочнице.
Кажется, это отлично работает в Chrome, но в Firefox CaptureStream не работает, и я получаю следующую ошибку:
[Exception... "Component not initialized" nsresult: "0xc1f30001 (NS_ERROR_NOT_INITIALIZED)" location: "JS frame :: https://2rlmz5.csb.app/src/index.js :: $csb$eval :: line 16" data: no]
Есть известное разрешение? Любая помощь высоко ценится.
В Firefox есть открытая ошибка, связанная с этим. На данный момент в Firefox captureStream
будет сброшен, если контекст canvas
не инициализирован. Вызов getContext
перед вызовом captureStream
исправляет эту ошибку:
const canvas = document.querySelector("canvas");
canvas.getContext('2d');
const stream = canvas.captureStream(25);
<canvas height = "500" width = "500"></canvas>
Но проблема здесь в том, что transferControlToOffscreen
не работает, если контекст холста инициализирован, и наоборот, если transferControlToOffscreen
был вызван первым, то контекст холста может быть инициализирован только вне экрана.
Таким образом, единственное решение — дождаться исправления этой ошибки.
POC: jsfiddle.net/9ug4k8am (не имеет отношения, но эта рабочий пример выявляет новую ошибку в FF, где fillStyle
игнорируется, я оставлю ее сломанной для потомков...)
Ух ты, открыт с 7 лет. Большое спасибо за ваше объяснение и обходной путь.
Одним из некрасивых обходных путей может быть регулярная отправка ImageBitmap из OffscreenCanvas в главное окно, рисование их в контексте ImageBitmapRenderer и захват MediaStream из его холста.