이 예제 크롬 단순히 탭을 흐리게 캔버스 스트림을 중지하기 때문에 현재는 완전히, 파이어 폭스에서 작동은 ... (아마 this bug 관련,하지만 잘 내 타이머가 작동 아닌 것 같다) ... 기록
[편집] : 그들은 this bug 고정,하지만 더 이상 FF로 인해 this one이 (e10s에 의해 발생했기 때문에 실제로 지금) 만 크롬에서 작동합니다.
는 프레임이 어느 것도 MediaRecorder에, 그것을 렌더링 된 때 알려주의 MediaStream에 어떤 이벤트가 될 것 같지 않습니다.
MediaStream의 currentTime
속성 (현재 FF로만 제공됨)도 captureStream()
메서드에서 전달 된 fps 인수와 함께 변경되지 않는 것처럼 보입니다.
하지만 현재 탭에 포커스가 맞지 않을 때 (예 : rAF의 경우) 주파수가 느려지지 않는 신뢰할 수있는 타이머가 필요합니다.
다행히도 WebAudio API는 화면 새로 고침 빈도가 아닌 하드웨어 시계를 기반으로 high precision timer입니다.
그래서 우리는 시간 초과 루프를 사용할 수있어 탭이 흐릿 해져도 주파수를 유지할 수 있습니다.
/*
\t An alternative timing loop, based on AudioContext's clock
\t @arg callback : a callback function
\t \t with the audioContext's currentTime passed as unique argument
\t @arg frequency : float in ms;
\t @returns : a stop function
\t
*/
function audioTimerLoop(callback, frequency) {
// AudioContext time parameters are in seconds
var freq = frequency/1000;
var aCtx = new AudioContext();
// Chrome needs our oscillator node to be attached to the destination
// So we create a silent Gain Node
var silence = aCtx.createGain();
silence.gain.value = 0;
silence.connect(aCtx.destination);
onOSCend();
var stopped = false;
function onOSCend() {
osc = aCtx.createOscillator();
osc.onended = onOSCend;
osc.connect(silence);
osc.start(0);
osc.stop(aCtx.currentTime + freq);
callback(aCtx.currentTime);
if (stopped) {
osc.onended = function() {
return;
};
}
};
// return a function to stop our loop
return function() {
stopped = true;
};
}
function start() {
// start our loop @25fps
var stopAnim = audioTimerLoop(anim, 1000/25);
// maximum stream rate set as 25 fps
cStream = canvas.captureStream(25);
let chunks = [];
var recorder = new MediaRecorder(cStream);
recorder.ondataavailable = e => chunks.push(e.data);
recorder.onstop = e => {
// we can stop our loop
stopAnim();
var url = URL.createObjectURL(new Blob(chunks));
var v = document.createElement('video');
v.src = url;
v.controls = true;
document.body.appendChild(v);
}
recorder.start();
// stops the recorder in 20s, try to change tab during this time
setTimeout(function() {
recorder.stop();
}, 20000)
}
// make something move on the canvas
var ctx = canvas.getContext('2d');
var x = 0;
function anim() {
x = (x + 2) % (canvas.width + 100);
ctx.fillStyle = 'ivory';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'red';
ctx.fillRect(x - 50, 20, 50, 50)
};
start();
<canvas id="canvas" width="500" height="200"></canvas>
의 Nota 베네 :
이 예에서, 나는 초당 25에 주파수를 설정하지만, 우리는 초당 60 프레임으로 설정할 수 있으며, 심지어 내 옛날 노트북에서 제대로 작동하는 것 같다 최소한 간단한 애니메이션으로.
흥미로운 창의적인 솔루션입니다. 나는 그것으로 실험 할 것이다. 감사! – Brad