Node.js WebRTC屏幕共享

时间:2020-07-21 11:06:40

标签: node.js socket.io webrtc screensharing

我在使用webRTC屏幕共享时遇到了问题。当一个人共享他的屏幕时,另一个人看不到共享的屏幕流,并要求他再次共享屏幕。我正在使用带有socket.io的node.js express服务器。我正在使用Google chrome。如果它不是本地的,则需要HTTPS连接。

这是Web应用程序代码`

(function() {
      const socket = io.connect(window.location.origin);
      const localVideo = document.querySelector('.localVideo');
      const remoteVideos = document.querySelector('.remoteVideos');
      const peerConnections = {};
      var url_string =window.location.href
      var url = new URL(url_string);
      var de = url.searchParams.get("key");
      let room = de
      let getUserMediaAttempts = 5;
      let gettingUserMedia = false;
      let getdisplaymedia=true;
      const config = {
        'iceServers': [{
          'urls': ['stun:stun.l.google.com:19302']
        }]
      };
      /** @type {MediaStreamConstraints} */
      const constraints = {
        audio: true,
        video: { facingMode: "user" }
      };
      socket.on('bye', function(id) {
        handleRemoteHangup(id);
      });
    
      if (room && !!room) {
        socket.emit('join', room);
      }
    
      window.onunload = window.onbeforeunload = function() {
        socket.close();
      };
    
      socket.on('ready', function (id) {
        if (!(localVideo instanceof HTMLVideoElement) || !localVideo.srcObject) {
          return;
        }
        const peerConnection = new RTCPeerConnection(config);
        peerConnections[id] = peerConnection;
        if (localVideo instanceof HTMLVideoElement) {
          peerConnection.addStream(localVideo.srcObject);
        }
        peerConnection.createOffer()
        .then(sdp => peerConnection.setLocalDescription(sdp))
        .then(function () {
          socket.emit('offer', id, peerConnection.localDescription);
        });
        peerConnection.onaddstream = event => handleRemoteStreamAdded(event.stream, id);
        peerConnection.onicecandidate = function(event) {
          if (event.candidate) {
            socket.emit('candidate', id, event.candidate);
          }
        };
      });
    
      socket.on('offer', function(id, description) {
        const peerConnection = new RTCPeerConnection(config);
        peerConnections[id] = peerConnection;
        if (localVideo instanceof HTMLVideoElement) {
          peerConnection.addStream(localVideo.srcObject);
        }
        peerConnection.setRemoteDescription(description)
        .then(() => peerConnection.createAnswer())
        .then(sdp => peerConnection.setLocalDescription(sdp))
        .then(function () {
          socket.emit('answer', id, peerConnection.localDescription);
        });
        peerConnection.onaddstream = event => handleRemoteStreamAdded(event.stream, id);
        peerConnection.onicecandidate = function(event) {
          if (event.candidate) {
            socket.emit('candidate', id, event.candidate);
          }
        };
      });
    
      socket.on('candidate', function(id, candidate) {
        peerConnections[id].addIceCandidate(new RTCIceCandidate(candidate))
        .catch(e => console.error(e));
      });
    
      socket.on('answer', function(id, description) {
        peerConnections[id].setRemoteDescription(description);
      });
    
      function getUserMediaSuccess(stream) {
        gettingUserMedia = false;
        if (localVideo instanceof HTMLVideoElement) {
          !localVideo.srcObject && (localVideo.srcObject = stream);
        }
        socket.emit('ready');
      }
    
      function handleRemoteStreamAdded(stream, id) {
        const remoteVideo = document.createElement('video');
        remoteVideo.srcObject = stream;
        remoteVideo.setAttribute("id", id.replace(/[^a-zA-Z]+/g, "").toLowerCase());
        remoteVideo.setAttribute("playsinline", "true");
        remoteVideo.setAttribute("autoplay", "true");
        remoteVideos.appendChild(remoteVideo);
        if (remoteVideos.querySelectorAll("video").length === 1) {
          remoteVideos.setAttribute("class", "one remoteVideos");
        } else {
          remoteVideos.setAttribute("class", "remoteVideos");
        }
      }
    
      function getUserMediaError(error) {
        console.error(error);
    
        gettingUserMedia = false;
        (--getUserMediaAttempts > 0) && setTimeout(getUserMediaDevices, 1000);
      }
    
      function getUserMediaDevices() {
        if (localVideo instanceof HTMLVideoElement) {
    
          if (localVideo.srcObject) {
            getUserMediaSuccess(localVideo.srcObject);
          } else if (!gettingUserMedia && !localVideo.srcObject) {
            gettingUserMedia = true;
            navigator.mediaDevices.getDisplayMedia(constraints)
            .then(getUserMediaSuccess)
            .catch(getUserMediaError);
          }
        }
      }
    
      function handleRemoteHangup(id) {
        peerConnections[id] && peerConnections[id].close();
        delete peerConnections[id];
        document.querySelector("#" + id.replace(/[^a-zA-Z]+/g, "").toLowerCase()).remove();
        if (remoteVideos.querySelectorAll("video").length === 1) {
          remoteVideos.setAttribute("class", "one remoteVideos");
        } else {
          remoteVideos.setAttribute("class", "remoteVideos");
        }
      }
    
      getUserMediaDevices();
    })();

这是node.js代码`

const credentials = require('./credentials');
const express = require('express');
const app = express();
let server;
let port;
if (credentials.key && credentials.cert) {
  const https = require('https');
  server = https.createServer(credentials, app);
  port = 443;
} else {
  const http = require('http');
  server = http.createServer(app);
  port = 1517;
}
const io = require('socket.io')(server);
const RoomService = require('./RoomService')(io);
io.sockets.on('connection', RoomService.listen);
io.sockets.on('error', e => console.log(e));
app.use(express.static(__dirname + '/public'));
app.get('*', function(req, res) {
    res.sendFile(${__dirname}/public/index.html);
});
server.listen(port, () => console.log(Server is running on port ${port}));

1 个答案:

答案 0 :(得分:2)

好吧,这是固定代码,您可以使用yuu,只需流getDisplayMedia值

  (function() {
  const socket = io.connect(window.location.origin);
  const localVideo = document.querySelector('.localVideo');
  const remoteVideos = document.querySelector('.remoteVideos');
  const peerConnections = {};
  var url_string =window.location.href
  var url = new URL(url_string);
  var de = url.searchParams.get("key");
  let room = de
  let getUserMediaAttempts = 5;
  let gettingUserMedia = false;
  let getdisplaymedia=true;
  /** @type {RTCConfiguration} */
  const config = {
    'iceServers': [{
      'urls': ['stun:stun.l.google.com:19302']
    }]
  };
  /** @type {MediaStreamConstraints} */
  const constraints = {
    audio: true,
    video: { facingMode: "user" }
  };
  socket.on('full', function(room) {
    alert('Room ' + room + ' is full');
  });
  socket.on('bye', function(id) {
    handleRemoteHangup(id);
  });

  if (room && !!room) {
    socket.emit('join', room);
  }

  window.onunload = window.onbeforeunload = function() {
    socket.close();
  };

  socket.on('ready', function (id) {
    if (!(localVideo instanceof HTMLVideoElement) || !localVideo.srcObject) {
      return;
    }
    const peerConnection = new RTCPeerConnection(config);
    peerConnections[id] = peerConnection;
    if (localVideo instanceof HTMLVideoElement) {
      peerConnection.addStream(localVideo.srcObject);
    }
    peerConnection.createOffer()
    .then(sdp => peerConnection.setLocalDescription(sdp))
    .then(function () {
      socket.emit('offer', id, peerConnection.localDescription);
    });
    peerConnection.onaddstream = event => handleRemoteStreamAdded(event.stream, id);
    peerConnection.onicecandidate = function(event) {
      if (event.candidate) {
        socket.emit('candidate', id, event.candidate);

      }
    };
  });

  socket.on('offer', function(id, description) {
    const peerConnection = new RTCPeerConnection(config);
    peerConnections[id] = peerConnection;
    if (localVideo instanceof HTMLVideoElement) {
      peerConnection.addStream(localVideo.srcObject);
    }
    peerConnection.setRemoteDescription(description)
    .then(() => peerConnection.createAnswer())
    .then(sdp => peerConnection.setLocalDescription(sdp))
    .then(function () {
      socket.emit('answer', id, peerConnection.localDescription);
    });
    peerConnection.onaddstream = event => handleRemoteStreamAdded(event.stream, id);
    peerConnection.onicecandidate = function(event) {
      if (event.candidate) {
        socket.emit('candidate', id, event.candidate);
      }
    };
  });

  socket.on('candidate', function(id, candidate) {
    peerConnections[id].addIceCandidate(new RTCIceCandidate(candidate))
    .catch(e => console.error(e));
  });

  socket.on('answer', function(id, description) {
    peerConnections[id].setRemoteDescription(description);
  });

  function getUserMediaSuccess(stream) {
    gettingUserMedia = false;
    if (localVideo instanceof HTMLVideoElement) {
      !localVideo.srcObject && (localVideo.srcObject = stream);
    }
    socket.emit('ready');
  }

  function handleRemoteStreamAdded(stream, id) {
    const remoteVideo = document.createElement('video');
    remoteVideo.srcObject = stream;
    remoteVideo.setAttribute("id", id.replace(/[^a-zA-Z]+/g, "").toLowerCase());
    remoteVideo.setAttribute("playsinline", "true");
    remoteVideo.setAttribute("autoplay", "true");
    remoteVideos.appendChild(remoteVideo);
    if (remoteVideos.querySelectorAll("video").length === 1) {
      remoteVideos.setAttribute("class", "one remoteVideos");
    } else {
      remoteVideos.setAttribute("class", "remoteVideos");
    }
  }

  function getUserMediaError(error) {
    console.error(error);

    gettingUserMedia = false;
    (--getUserMediaAttempts > 0) && setTimeout(getUserMediaDevices, 1000);
  }

function getUserMediaDevices() {
var constraints = { audio: true, video: { width: 1280, height: 720 } }; 

navigator.mediaDevices.getDisplayMedia(constraints)
.then(function(mediaStream) {
  var video = document.querySelector('video');
  video.srcObject = mediaStream;
  video.onloadedmetadata = function(e) {
    video.play();
    getUserMediaSuccess(video.srcObject)  
  };
})
.catch(function(err) { console.log(err.name + ": " + err.message); }); // always check for errors at the end.
}

  function handleRemoteHangup(id) {
    peerConnections[id] && peerConnections[id].close();
    delete peerConnections[id];
    document.querySelector("#" + id.replace(/[^a-zA-Z]+/g, "").toLowerCase()).remove();
    if (remoteVideos.querySelectorAll("video").length === 1) {
      remoteVideos.setAttribute("class", "one remoteVideos");
    } else {
      remoteVideos.setAttribute("class", "remoteVideos");
    }
  }

  getUserMediaDevices();
})();