【问题标题】:How to send getusermedia recorded stream to server nodejs realtime如何将getusermedia记录的流实时发送到服务器nodejs
【发布时间】:2017-07-30 16:44:11
【问题描述】:

我能够使用 socket.io 将流 blob 发送到节点 js 服务器。但是,在更新视频播放器中的 blob 数据时它会闪烁。我希望它运行顺畅。如何在不闪烁视频播放器的情况下发送数据。这是我的服务器代码

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 毫秒后向服务器发送数据。但在网页中闪烁。我必须这样做才能使其成为实时。任何帮助将不胜感激。

【问题讨论】:

    标签: javascript node.js socket.io webrtc mediastream


    【解决方案1】:

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

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

    如果你愿意放弃 TCP 连接,我有一个小解决方案。我试过了,效果很好。

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

    只有一个问题是,在这种情况下,您不能像在 websockets 中那样轻松地在 WAN 上发送数据包。你必须在你的服务器上实现 STUN/TURN 或类似的东西。

    如果您仍有疑问,请查看此 github 问题并阅读所有回复:https://github.com/socketio/socket.io/issues/1175

    我希望这会有所帮助。

    【讨论】:

      【解决方案2】:

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

      您正在更改&lt;video&gt; 元素的.src

      URL.createObjectURL()MediaStreamRecorder 不是必需的。

      您可以传递一次MediaStream 对象并将&lt;video&gt; 元素.srcObject 设置为传递的MediaStream,而不是更改&lt;video&gt; 元素的.src

      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
        }
      }
      &lt;video id="video"&gt;&lt;/video&gt;

      如果需要发送Blob,您可以使用MediaSource,使用FileReaderfetch()Blob 转换为ArrayBuffer,并将ArrayBuffer 附加到SourceBuffer,请参阅@987654322 @。

      【讨论】:

        猜你喜欢
        • 2011-04-24
        • 2015-02-27
        • 1970-01-01
        • 2013-12-27
        • 2014-02-25
        • 2012-08-12
        • 2021-12-03
        • 1970-01-01
        相关资源
        最近更新 更多