2017-04-17 4 views
1

오픈 소스 JavaScript 라이브러리 MediaStreamRecorder을 사용하여 Mozilla Firefox 및 Chrome에서 오디오 및 비디오 webRTC 호출을 녹음하고 있습니다.MediaStreamRecorder가 ondataavailable 이벤트를 발생시키지 않습니다.

호출이 성공적으로 녹음되고 있지만 다음과 같은 문제가 있습니다.

multiStreamRecorder.start()에서 1 초 (1000ms)의 시간 간격을 사용하면 multiStreamRecorder.ondataavailable 이벤트가 실행되지 않습니다. 그래서 오류가 없거나 콘솔에 로그인하지 않습니다.

그러나 1.5 초 (1500ms) 이상의 시간 간격을 사용하면 multiStreamRecorder.ondataavailable 이벤트가 발생하고 모든 것이 정상적으로 작동합니다.

(만 비디오 케이스에) 나는 단 1 초 (1000ms)으로 깜박임에 간격을 유지하려는.

var ws; 

function start() { 

    ws = new WebSocket("wss://xyz/"); 

    ws.onopen = function() { 
     console.log("WebSocket has been opened!"); 
    }; 

    ws.onmessage = function (message) { 
     console.log("A messsage is received from WebSocket Server.", message); 
    }; 

    ws.onclose = function (e) { 
     console.log('WebSocket is closed. Reconnection will be attempted in 5 second.', e.reason); 
     setTimeout(function() { 
      start(); 
     }, 5000); 
    }; 

    ws.onerror = function (err) { 
     console.error('WebSocket encountered an error: ', err.message, 'Closing WebSocket'); 
     ws.close(); 
    }; 

} 

start(); 


function startRecording(localStream, remoteStream) { 

    if (localStream != null && remoteStream != null) { 

     multiStreamRecorder = new MultiStreamRecorder([localStream, remoteStream], "video/webm"); 
     multiStreamRecorder.mimeType = "video/webm"; 

     multiStreamRecorder.ondataavailable = function (blob) { 

      console.log("sending blob to websocket server", blob); 
      ws.send(blob); 

     }; 

     // It doesn't work with the 1000ms time interval 
     multiStreamRecorder.start(1500); 

    } 
    else{ 
     console.error("One or more streams are null."); 
    } 

} 

답변

1

카메라가 워밍업되는 데 1 초가 충분하지 않다고 생각됩니다. 레코더를 즉시 스트림에 연결할 수는 있지만 재생/녹음 준비가되지 않은 것으로 보입니다.

비디오 요소에는 데이터 준비가 완료 될 때까지 기다리는 데 사용할 수있는 .onloadedmetadata이 있습니다. 레코더는 그렇지 않습니다.

var haveLoadedMetadata = stream => { 
 
    let preview = document.createElement("video"); 
 
    preview.srcObject = stream; 
 
    return new Promise(resolve => preview.onloadedmetadata = resolve); 
 
}; 
 

 
var start = ms => navigator.mediaDevices.getUserMedia({video: true}) 
 
    .then(stream => haveLoadedMetadata(stream) 
 
    .then(() => record(stream, ms)) 
 
    .then(recording => { 
 
     stop(stream); 
 
     video.src = link.href = URL.createObjectURL(new Blob(recording)); 
 
     link.download = "recording.webm"; 
 
     link.innerHTML = "Download recording"; 
 
     log("Playing "+ recording[0].type +" recording:"); 
 
    })) 
 
    .catch(log); 
 

 
var record = (stream, ms) => { 
 
    var rec = new MediaRecorder(stream), data = []; 
 
    rec.ondataavailable = e => data.push(e.data); 
 
    rec.start(); 
 
    log(rec.state + " for "+ (ms/1000) +" seconds..."); 
 
    var stopped = new Promise((y, n) => (rec.onstop = y, rec.onerror = e => n(e.error || e.name))); 
 
    return Promise.all([stopped, wait(ms).then(() => rec.stop())]) 
 
    .then(() => data); 
 
}; 
 

 
var stop = stream => stream.getTracks().forEach(track => track.stop()); 
 
var wait = ms => new Promise(resolve => setTimeout(resolve, ms)); 
 
var log = msg => div.innerHTML += "<br>" + msg;
<button onclick="start(1000)">Record 1 second!</button> 
 
<div id="div"></div><br> 
 
<video id="video" height="120" width="160" autoplay></video> 
 
<a id="link"></a>

이 (크롬과 파이어 폭스 모두 직접 MediaRecorder을 구현, 그래서 나는 것을 사용하여 대답했습니다) :

(크롬에 대한 https fiddle 사용)하지만 당신은 하나를 만들 수 있습니다.

+0

'MediaRecorder.ondataavailable' 창이 최소화되거나 브라우저 탭이 전환 된 후에 실행되지 않습니다 ...이를 막을 수있는 방법이 있습니까? 또는 라이브러리의 본질에 있다면 탭을 전환하고 다시 컴백하면 어떻게 프로세스를 재개 할 수 있습니까? –

+0

도서관에 대해 잘 모르겠습니다. [my fiddle] (https://jsfiddle.net/jib1/b0x7n7pe/)에서 원시 파일을 사용하며 탭 전환이나 최소화로 인해 fazed하지 않습니다. 예 : 10 초를 기록하도록 수정하십시오. WFM. – jib

관련 문제