2017-07-30 230 views
0

我能够使用socket.io发送流blob到节点js服务器。但是,它在更新视频播放器中的blob数据时闪烁。我希望它运行平稳。如何在不眨眼视频播放器的情况下发送数据。这里是我的服务器代码如何发送getusermedia录制的流到服务器nodejs实时

var express = require("express"); 
var app = express(); 
var http = require("http").Server(app); 
var io = require("socket.io")(http); 
var fs = require("fs") 

app.use(express.static('public')) 
app.get("/", function(req, res){ 
res.sendFile(__dirname+ "/public/index.html"); 
}); 


io.on("connection", function(socket) { 
    console.log("A user is connected"); 
    socket.on("send", function(data){ 
    console.log(data); 
    socket.emit("data", data); 
    }); 
    socket.on("disconnect", function() { 
    console.log("A user is disconnected"); 
    }); 
}); 


http.listen(3000, function(){ 
    console.log("Server is started at port 3000\nTo close use Ctrl+C"); 
}); 

这里是我的客户端代码,

<html> 
<head><title>Testing</title> 
<script src="socket.io/socket.io.js"></script> 
<script type="text/javascript" src="MediaStreamRecorder.js"></script> 
</head> 
<body> 
<video autoplay="true" id="video"></video> 
<script type="text/javascript"> 
var socket = io(); 
      window.URL.createObjectURL = window.URL.createObjectURL || window.URL.webkitCreateObjectURL || window.URL.mozCreateObjectURL || window.URL.msCreateObjectURL;    
      socket.on("data", function(data){ 
        var binaryData = []; 
        binaryData.push(data); 
        videoElement = document.getElementById('video'); 
        videoElement.src = window.URL.createObjectURL(new Blob(binaryData, {type: "video/webm"})); 
      }); 

       var mediaConstraints = { 
         video: true 
        }; 
       navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; 

        navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError); 

        function onMediaSuccess(stream) { 
         var arrayOfStreams = [stream]; 
         var medias = new MediaStreamRecorder(stream); 
         medias.ondataavailable = function(blob) { 
          socket.emit("send", blob); 
         }; 
         medias.start(); 
        } 

        function onMediaError(e) { 
         console.error('media error', e); 
        } 
</script> 
</body> 
</html> 

我有变化的时间片值MediaStreamRecorder API 500默认。所以,在500毫秒后发送数据到服务器。但在网页中闪烁。我必须这样做才能实现。任何帮助将不胜感激。

回答

1

但是,它在更新视频播放器中的blob数据时闪烁。

您正在更改<video>元素的.src

URL.createObjectURL()MediaStreamRecorder没有必要。

而是改变<video>.src你可以一次传递MediaStream对象并设置<video>元素.srcObject到传递的MediaStream

videoElement = document.getElementById("video"); 

function onMediaSuccess(stream) { 
    if (videoElement.srcObject === null) { 
    videoElement.srcObject = stream 
    } 
} 

var videoElement = document.getElementById("video"); 
 

 
videoElement.oncanplay = function() { 
 
    videoElement.play(); 
 
} 
 

 
var media = document.createElement("video"); 
 

 
media.src = "https://nickdesaulniers.github.io/netfix/demo/frag_bunny.mp4"; 
 

 
media.oncanplay = function() { 
 
    media.play(); 
 
    var stream = media.captureStream(); 
 
    onMediaSuccess(stream); 
 
} 
 

 
function onMediaSuccess(stream) { 
 
    if (videoElement.srcObject === null) { 
 
    videoElement.srcObject = stream 
 
    } 
 
}
<video id="video"></video>

如果要求发送Blob你可以使用MediaSource,使用FileReaderfetch()转换BlobArrayBuffer和追加ArrayBufferSourceBuffer,看Unable to stream video over a websocket to Firefox

0

您正在使用使用TCP连接的socket.io。如果你想让你的应用程序像Skype一样实时,你必须使用UDP连接。

如果一帧滞后,那么你的应用程序应该忽略这一点,但在你的情况下,你使用的是TCP连接,因此它总是按顺序传递。防火墙也是TCP连接的一个问题。你说你试图将超时设置为500毫秒,这对于实时应用来说太大了,这就是为什么你的视频闪烁。

如果你愿意放弃TCP连接,我有一个小的解决方案。我试过这个,它工作正常。

https://www.youtube.com/watch?v=ieBtXwHvoNk

只是一个问题是,在这种情况下,你不能在WAN发送你的数据包直接,你可以很容易的WebSockets做。你必须在你的服务器上实现STUN/TURN或类似的东西。

如果您仍然有一些疑虑,然后看到这个github上的问题,并阅读所有的答复:https://github.com/socketio/socket.io/issues/1175

我希望这会有所帮助。

相关问题