MediaRecorder crashes tab with WebGL canvas. Works fine on Android chrome.
Reported by
cgfarm...@gmail.com,
May 6 2017
|
|||||
Issue descriptionUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36 Steps to reproduce the problem: 1. Setup a mediaRecorder attached to a getUserMedia stream that is piped onto a material texture in WebGL. 2. Start the recorder with the MediaStream and notice no data pipes into onDataAvailable. What is the expected behavior? - MediaStream sends data to ondataavailable event of MediaRecorder upon starting. - onerror event of MediaRecorder should fire with issues pertaining to the recorder not receiving data. What went wrong? Chrome freezes. I cannot reproduce on a Pixel XL, latest. Same exact code. Did this work before? N/A Does this work in other browsers? N/A Chrome version: 58.0.3029.96 Channel: stable OS Version: OS X 10.12.1 Flash Version: This seems related to: https://bugs.chromium.org/p/chromium/issues/detail?id=654910&q=component%3ABlink%3EMediaRecording%20&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified But that one is more audio specific. I'm seeing this mostly with a WebGL canvas.
,
May 8 2017
@ cgfarmer4-- Could you please provide us the sample media file to reproduce the issue , that would hep us in triaging the issue better. Thanks!
,
May 8 2017
I'm not sure what you mean by sample media file? I'm creating the media via Web APIs and saving it to webm from the browser.
Here's how to reproduce if it wasn't clear.
1. Setup a WebGL renderer using THREE.js.
new THREE.WebGLRenderer({ antialias:true });
2. Call navigator.getUserMedia and get the user's webcam + microphone.
navigator.getUserMedia(constraints,
function(stream) {
window.stream = stream;
this.userVideo.src = stream;
3. Upon success, attach videoOut to a canvas element that draws the video on animation.
// User Media Video
this.video = document.getElementById('gum');
this.video.load();
this.video.play();
// Create Canvas Element for Video
this.videoImage = document.createElement('canvas');
this.videoImage.width = width;
this.videoImage.height = height;
4. Use that canvas to paint the material on the cube in the WebGL scene.
// Add Image Element for Video
this.videoImageContext = this.videoImage.getContext('2d');
this.videoImageContext.fillStyle = '#000000';
this.videoImageContext.fillRect(0, 0, this.videoImage.width, this.videoImage.height);
// Create the Video Texture for the Cube
this.videoTexture = new THREE.Texture(this.videoImage);
this.videoTexture.minFilter = THREE.LinearFilter;
this.videoTexture.magFilter = THREE.LinearFilter;
// Create the Material for The Cube from the texture
const movieMaterial = new THREE.MeshBasicMaterial({
map: this.videoTexture,
overdraw: true,
side:THREE.DoubleSide
});
//Cube
const geometry = new THREE.BoxGeometry(200, 200, 200);
const material = new THREE.MeshBasicMaterial({
color: 0xff0000,
wireframe: true
});
//Exterior Mesh on Cube
this.mesh = new THREE.Mesh(geometry, movieMaterial);
this.scene.add(this.mesh);
5. Call MediaStream from the WebGL canvas, not the video canvas also get the audio tracks from userMedia that we assigned to window.stream.
let canvasStream = this.canvas.captureStream();
const options = {
audioBitsPerSecond : 128000,
videoBitsPerSecond : 2500000,
mimeType : 'video/webm'
};
this.outputStreamBlobs = [];
let createMediaStream = window.webkitMediaStream || window.MediaStream;
let outputStream = new createMediaStream();
[ window.stream.getAudioTracks(), canvasStream.getVideoTracks() ].forEach(function(stream) {
stream.forEach(function(track) {
outputStream.addTrack(track);
});
});
this.outputRecorder = new MediaRecorder(outputStream);
this.outputRecorder.onstop = this.recordStop.bind(this);
this.outputRecorder.ondataavailable = this.recordData.bind(this);
this.outputRecorder.start(10); // collect 10ms of data
this.outputRecorder.onerror = function (err) {
console.log(err);
}
6. Failure and page lock in Chrome desktop. Perect execution on PixelXL.
,
May 8 2017
Thank you for providing more feedback. Adding requester "hdodda@chromium.org" to the cc list and removing "Needs-Feedback" label. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
May 8 2017
Here is the render loop in requestAnimationFrame for recording:
if (this.video.readyState === this.video.HAVE_ENOUGH_DATA)
{
this.videoImageContext.save();
this.videoImageContext.translate(this.videoImage.width, 0);
this.videoImageContext.scale(-1, 1);
this.videoImageContext.drawImage(this.video, 0, 0);
if (this.videoTexture) {
this.videoTexture.needsUpdate = true;
}
this.videoImageContext.restore();
}
this.mesh.rotation.x += 0.01;
this.mesh.rotation.y += 0.02;
this.renderer.render(this.scene, this.camera);
,
May 8 2017
Can you go to chrome://crashes/ after this happens and share the CrashID and ServerID? Also, there has been a couple fixes re MediaRecorder in 59. Can you try on the latest canary to see if you can still repro?
,
May 10 2017
Obviously as soon as you ask me to reproduce with the one piece I didn't get, I can now no longer reproduce with this scenario. I will open a new one with the crash log should I encounter this issue again.
,
May 10 2017
Thanks. Feel free to reopen this issue as well if you can repro again. |
|||||
►
Sign in to add a comment |
|||||
Comment 1 by cgfarm...@gmail.com
, May 6 20171.2 MB
1.2 MB View Download