Kurentoterminal顺序为了录制屏幕录像

我试图用kurento媒体服务器录制networking摄像头, kurento是我在后端使用的function:

 var startScreen = (sessionId, ws, sdpOffer, callback) => { console.log("Start screen") getKurentoClient((error, kurentoClient) => { if (error) { return callback(error) } kurentoClient.create('MediaPipeline', (error, pipeline) => { if (error) { return callback(error) } var recordParams = { stopOnEndOfStream: true, mediaProfile: 'WEBM_VIDEO_ONLY', uri: 'file:///PATH/TO/VIDEO/screen.webm' } pipeline.create('RecorderEndpoint', recordParams, (error, recorder) => { if (error) return callback(error) screenRecorder = recorder recorder.record(() => console.log("recording")) pipeline.create('WebRtcEndpoint', (error, webRtcEndpoint) => { if (error) { pipeline.release() return callback(error) } screenRtcEndpoint = webRtcEndpoint if (candidatesQueue[sessionId]) { while(candidatesQueue[sessionId].length) { var candidate = candidatesQueue[sessionId].shift() webRtcEndpoint.addIceCandidate(candidate) } } webRtcEndpoint.on('OnIceCandidate', (event) => { var candidate = kurento.register.complexTypes.IceCandidate(event.candidate) ws.send(JSON.stringify({ id: 'iceCandidateScreen', candidate: candidate })) }) webRtcEndpoint.processOffer(sdpOffer, (error, sdpAnswer) => { if (error) { pipeline.release() return callback(error) } sessions[sessionId] = { 'pipeline': pipeline, 'webRtcEndpoint': webRtcEndpoint } webRtcEndpoint.connect(webRtcEndpoint, error => { if (error) { return callback(error) } console.log("Connect webrtcEndpoint") webRtcEndpoint.connect(screenRecorder, error => { if (error) { return callback(error) } console.log("connect to the screen recorder") }) callback(null, sdpAnswer) }) }) webRtcEndpoint.gatherCandidates((error) => { if (error) { return callback(error) } }) }) }) }) }) } 

pipe道看起来像这样:

 mediaPipeline -> recorderEndpoint and recorder.record -> WebRtcEndpoint connect webrtcendpoint -> connect recorder endpoint 

在前端我做到这一点:

 mediaConstrains = { audio: false, video: { mandatory: { maxWidth: 640, maxHeight: 480, maxFrameRate: 15, minFrameRate: 1 } } } var getMediaConstrains = () => mediaConstrains var setMediaConstrains = (config) => { mediaConstrains = config } var startScreen = () => { var options = { mediaConstrains: mediaConstrains, onicecandidate: onIceCandidate, configuration: { iceServers: [ {'url': 'turn:numb.viagenie.ca:3478', 'username': 'email@email.com', 'credential': 'passwordrandom'} ] } } webRtcPeerScreen = kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(options, function (error) { if (error) { return onError(error) } this.generateOffer(onOfferScreen) }) } 

这是只为截屏不工作,我使用几乎完全相同的代码来logging一个摄像头,其完全正常工作,这是停止function:

 var stop = () => { if (webRtcPeerWebcam && webRtcPeerScreen) { webRtcPeerWebcam.dispose() webRtcPeerWebcam = null webRtcPeerScreen.dispose() webRtcPeerScreen = null var message = { id: 'stop' } sendMessage(message) } } 

我在前端处理stream水线的地方,但是我把这个消息发送到后端,然后这个wss消息调用这个函数:

 var stop = (sessionId) => { if (sessions[sessionId]) { var pipeline = sessions[sessionId].pipeline pipeline.release() delete sessions[sessionId] delete candidatesQueue[sessionId] } } 

我认为这可能是为什么这不logging屏幕录像或者我连接pipe道不正确的问题

不pipe怎样,谢谢!

PD:我在KMS日志中发现了这个:

 KurentoMediaElementImpl MediaElementImpl.cpp:434 mediaFlowOutStateChange() <kmswebrtcendpoint373> Media N OT Flowing OUT in pad default with type video 

第一个也是最重要的问题是,在SDP谈判之前,你正在处理候选人,并收集候选人。 这是行不通的,所以我认为你的webrtc根本不工作,不pipe你如何连接端点。

其次,在WebRtcEndpoint之前创buildlogging器,然后调用record 。 录像机没有任何连接,没有媒体stream入。 build议您在将WebRtcEndpoint连接到刻录机以及介质stream动后调用record方法。 为此,可以像这样向事件MediaStateChanged添加一个侦听器

 webRtcEndpoint.on('MediaStateChanged', function (event) { if ((event.oldState !== event.newState) && (event.newState === 'CONNECTED')) { // Start recording recorderEndpoint.record(); } }); 

将WebRtcEndpoint创build后立即连接到刻录机。

另外,正如一个侧面说明,这条线是没有意义的,因为端点是sendonly

 webRtcEndpoint.connect(webRtcEndpoint, error => { 

总而言之,这就是我所build议的。 不要忘了填写你可能会发现的任何空白,因为没有从OnIceCandidate等填充callback,它将无法正常工作。

 var startScreen = (sessionId, ws, sdpOffer, callback) => { console.log("Start screen") getKurentoClient((error, kurentoClient) => { if (error) { return callback(error) } kurentoClient.create('MediaPipeline', (error, pipeline) => { pipeline.create('RecorderEndpoint', recordParams, (error, recorder) => { pipeline.create('WebRtcEndpoint', (error, webRtcEndpoint) => { webRtcEndpoint.connect(screenRecorder, error => { webRtcEndpoint.processOffer(sdpOffer, (error, sdpAnswer) => { // The SDP negotiation must be completed before processing candidates callback(null, sdpAnswer) if (candidatesQueue[sessionId]) { while (candidatesQueue[sessionId].length) { var candidate = candidatesQueue[sessionId].shift() webRtcEndpoint.addIceCandidate(candidate) } } webRtcEndpoint.on('MediaStateChanged', function(event) { // This will start recording right after media starts flowing if ((event.oldState !== event.newState) && (event.newState === 'CONNECTED')) { // Start recording recorderEndpoint.record(); } }) webRtcEndpoint.on('OnIceCandidate', (event) => { /* your code here */ }) // Candidates must be gathered after the negotiation is completed, and the // event handler is bound webRtcEndpoint.gatherCandidates((error) => { /* your code here */ }) }) }) }) }) }) }) } 

RecorderEndpoint在释放之前调用stop方法是非常值得推荐的,否则不能保证媒体已经写入文件。

根据您使用的KMS版本,您甚至可以等待事件(已Stopped ),确保所有媒体都已经写入文件。

此外,您的代码似乎没有连接WebrtcEndpointRecorderEndpoint ,检查了这一点。

编辑:

您还应该检查RecorderEndpoint是否正确接收媒体以及WebRtcEndpoint是否从networking接收。 您可以使用MediaFlowOutStateChangeMediaFlowInStateChange以及isMediaFlowingIn isMediaFlowingOut方法(请参阅接受参数的kmd )