2016-11-18 77 views

回答

3

這個例子目前僅完全適用於火狐,因爲鉻乾脆停止時的標籤模糊畫布流... (可能與this bug,但很好,我計時器似乎是工作,但不是記錄...)

[編輯]:它實際上現在只能在Chrome,因爲他們有固定的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>

諾塔Bene的
在這個例子中,我將頻率設置爲25fps的,但我們可以將其設置爲60fps的,它似乎甚至在我的舊筆記本電腦正常工作,至少用這樣一個簡單的動畫。

+0

有趣的創意解決方案。我會試驗它。謝謝! – Brad