Open mrcatman opened 5 years ago
I use the code to stream video to my own RTMP server (not Facebook's).
Please note the terms in the LICENSE file.
Even if i use CaptureStream from a video element, not a one, the stream also stops. Are there any workarounds for this case?
The only workaround I've found is to have your application popup in its own window. This is a Chromium bug, in my opinion. The browser should keep rendering elements that have a capture stream.
This is explicitly a chrome bug. It's also variable dependent on platform.
Closing.
Update... i just found a fix for this today.
I might implement this in the example if someone begs / needs. :) It's pretty simple to do though.
Please I really need this bug fixed :) I can't run canvas stream in the background
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"></script>
<script>
var fps = 50;
function pushStream () {
console.log("pushStream");
const ws = new WebSocket("ws://edge1.xxxxx.com:3000");
ws.addEventListener('open', (e) => {
//--------------------------------------- KAMERA ----------------------------- \\
var canvas_w = 1280;
var canvas_h = 720;
var canvas = document.getElementById('konfiumStudio');
var ctx = canvas.getContext('2d');
var canvasContext = canvas.getContext("2d");
var canvasStream = canvas.captureStream(30);
var webcamShare_w = 256;
var webcamShare_h = 144;
var webcamShare_x = canvas_w - webcamShare_w - 5;
var webcamShare_y = 5;
var screenShare_x = 5;
var screenShare_y = 5;
var screenShare_w = canvas_w - webcamShare_w - 8;
var screenShare_h = canvas_h - 10;
/* cihaz listesi */
webcamPlayer = null;
screenPlayer = null;
function SelectTemplate($select) {
if ($select == 1) {
temp1();
}
}
function temp1() {
screenShare_x = 0;
screenShare_y = 0;
screenShare_w = 1280;
screenShare_h = 720;
}
var video = document.querySelector("#videoElement");
webcamPlayer = document.createElement("video");
if (navigator.mediaDevices.getUserMedia) {
webcamPlayer.muted = true;
webcamPlayer.poster = '';
navigator.mediaDevices.getUserMedia({ audio: true , video: {width: 320, height: 180, facingMode: "user"} })
.then(function (stream) {
mediaRecorder = new MediaRecorder(stream, {
mimeType: 'video/webm;codecs=h264',
audioBitsPerSecond : 128000,
videoBitsPerSecond : 256000
});
var stopAnim = audioTimerLoop(1000 / fps);
mediaRecorder.addEventListener('stop', ws.close.bind(ws));
mediaRecorder.addEventListener('dataavailable', (e) => {
ws.send(e.data);
});
mediaRecorder.onstop = e => {
// we can stop our loop
// stopAnim();
}
mediaRecorder.start(150); // Start recording, and dump data every second
webcamPlayer.srcObject = stream;
webcamPlayer.play();
webcamPlayer.addEventListener('play', function() {
var $this = this; //cache
(function loop() {
if (!$this.paused && !$this.ended) {
ctx.drawImage(webcamPlayer, webcamShare_x, webcamShare_y, webcamShare_w , webcamShare_h);
setTimeout(loop, 1000 / 30); // drawing at 30fps
//addaudio();
}
})();
}, 0);
})
.catch(function (err0r) {
console.log("Bazi seyler ters gitti gibi ama arastiracagiz ... : "+err0r);
});
}
//--------------------------------------- KAMERA ----------------------------- \\
console.log('WebSocket Open', e);
mediaStream = document.querySelector('canvas').captureStream(fps); // 30 FPS
mediaRecorder = new MediaRecorder(mediaStream, {
mimeType: 'video/webm;codecs=h264',
audioBitsPerSecond : 128000,
videoBitsPerSecond : 3000000
});
var stopAnim = audioTimerLoop(1000 / fps);
mediaRecorder.addEventListener('stop', ws.close.bind(ws));
mediaRecorder.addEventListener('dataavailable', (e) => {
// ws.send(e.data);
});
mediaRecorder.onstop = e => {
// we can stop our loop
// stopAnim();
}
mediaRecorder.start(1000); // Start recording, and dump data every second
});
ws.addEventListener('close', (e) => {
console.log('WebSocket Close', e);
mediaRecorder.stop();
});
}
function audioTimerLoop( frequency) {
var freq = frequency / 1000; // AudioContext time parameters are in seconds
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; // A flag to know when we'll stop the loop
function onOSCend() {
var osc = aCtx.createOscillator();
osc.onended = onOSCend; // so we can loop
osc.connect(silence);
osc.start(0); // start it now
osc.stop(aCtx.currentTime + freq); // stop it next frame
// callback(aCtx.currentTime); // one frame is done
if (stopped) { // user broke the loop
osc.onended = function() {
aCtx.close(); // clear the audioContext
return;
};
}
};
// return a function to stop our loop
return function() {
stopped = true;
};
}
</script>
</head>
<body>
<canvas width="1280" height="720" style="background: #37383a;" id="konfiumStudio"> </canvas>
<nav>
<button onclick="pushStream()">Go Live</button>
</nav>
</body>
</html>
canvas is still not working efficiently in the background
I use the code to stream video to my own RTMP server (not Facebook's). When the tab where the stream comes from is in background (i.e. the other tab is active), the browser (Chrome) stops sending the video to the server (but audio, which comes from an AudioContext, keeps sending). Even if i use CaptureStream from a video element, not a