LoginSignup
2
0

More than 5 years have passed since last update.

canvas 要素が実 DOM に存在するときしか HTMLCanvasElement.captureStream の MediaStream が発生しない問題

Last updated at Posted at 2016-12-20

canvas 要素が実 DOM に存在するときしか HTMLCanvasElement.captureStream の MediaStream が発生しない問題

HTMLCanvasElement.captureStream を使えば canvas 上のアニメーションから MediaStream を作ることができる。

しかし、 GoogleChrome 55.0.2883.95 (64-bit) で確認したところ、
対象となる canvas が実 DOM 上に存在しない場合 MediaStream が止まってしまう。
display: none; もダメである。

サンプルコード

const ctx = document.createElement("canvas").getContext("2d");
const cnv_stream = ctx.canvas.captureStream(60);
const url_cnv = URL.createObjectURL(cnv_stream);
const video_cnv = document.createElement("video");
let flag = true;

ctx.canvas.width  = 400;
ctx.canvas.height = 300;

video_cnv.src = url_cnv;
video_cnv.controls = true;
video_cnv.play();

document.body.appendChild(video_cnv);

setInterval(renderer, 1000/5);
setInterval(toggle, 3000);

function renderer(){
    ctx.canvas.width = ctx.canvas.width;
  ctx.arc(
  Math.random()*ctx.canvas.width,
  Math.random()*ctx.canvas.height,
  10, 0, 2*Math.PI);
  ctx.fill();
}

function toggle(){
  if(flag) document.body.appendChild(ctx.canvas);
  else     document.body.removeChild(ctx.canvas);  
  flag = !flag;
}

原因

canvas でのオフスクリーンレンダリングをキャプチャできないのは問題である。
おそらくバグだと思うが確認を取っていないため不明である。

対処法

visibility: hidden; を使う。大きさを持つので width: 0%; も併せて使う。

const ctx = document.createElement("canvas").getContext("2d");
const cnv_stream = ctx.canvas.captureStream(60);
const url_cnv = URL.createObjectURL(cnv_stream);
const video_cnv = document.createElement("video");
let flag = true;

ctx.canvas.width  = 400;
ctx.canvas.height = 300;

video_cnv.src = url_cnv;
video_cnv.controls = true;
video_cnv.play();

setInterval(toggle, 3000);
setInterval(renderer, 1000/5);

document.body.appendChild(video_cnv);
document.body.appendChild(ctx.canvas);

function renderer(){
    ctx.canvas.width = ctx.canvas.width;
  ctx.arc(
  Math.random()*ctx.canvas.width,
  Math.random()*ctx.canvas.height,
  10, 0, 2*Math.PI);
  ctx.fill();
}

function toggle(){
  if(flag){
    ctx.canvas.style.visibility = "";
    ctx.canvas.style.width = "";
  }else{
    ctx.canvas.style.visibility = "hidden";
    ctx.canvas.style.width = "0%";
  }
  flag = !flag;
}
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0