使用js搭建简易的WebRTC实现视频直播

  1. 首先需要一个信令服务器,我们使用nodejs来搭建。两个端:发送端和接收端。
  2. 我的目录结构如下图:
  3. 流程
    1. 创建一个文件夹 WebRTC-Test。

    2. 进入文件夹中,新建一个node的文件夹。

    3. 使用终端并进入node的目录下,使用

      npm init
      

      创建package.json。

    4. 新建server.js,复制一下代码

      javascript 复制代码
      const app = require('express')();
      const wsInstance = require('express-ws')(app);
      
      const cors = require('cors');
      app.use(cors({ origin: 'http://localhost:3000' }));
      
      app.ws('/', ws => {
      	ws.on('message', data => {
      		// 未做业务处理,收到消息后直接广播
      		wsInstance.getWss().clients.forEach(server => {
      			if (server !== ws) {
      				server.send(data);
      				console.log(data,)
      			}
      		});
      	});
      });
      
      console.log("服务启动: http://localhost:8080");
      app.listen(8080, '0.0.0.0');
    5. 下载信令服务器的依赖。

      javascript 复制代码
      npm install express;
      npm install express-ws;
      npm install cors;
    6. 使用node server.js启动node的服务。

    7. 准备接收方的代码(receive.html)。

      html 复制代码
      <!DOCTYPE html>
      <html lang="zh-CN">
      
      <head>
          <meta charset="UTF-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
          <title>Receiver</title>
      </head>
      
      <body>
          <video autoplay id="remote"></video>
      </body>
      <script>
          const remoteVideo = document.querySelector('#remote')
      
          const socket = new WebSocket('ws://localhost:8080');
          socket.onopen = function () {
              console.log("Socket Success")
          }
          let buddy = new RTCPeerConnection()
      
      
          // 如果接收到对方的视频
          socket.onmessage = function (e) {
              const { type, sdp, iceCandidate } = JSON.parse(e.data)
              console.log(type)
              switch (type) {
                  case "offer":
                      buddy.setRemoteDescription(
                          new RTCSessionDescription({ type, sdp })
                      )
                      buddy.createAnswer().then(answer => {
                          buddy.setLocalDescription(answer)
                          socket.send(JSON.stringify(answer))
                      })
                      break;
      
                  case "offer_ice":
                      buddy.addIceCandidate(iceCandidate)
                      break;
      
                  default:
                      break;
              }
          }
      
          buddy.ontrack = function (e) {
              remote.srcObject = e.streams[0]
          }
      
          buddy.onicecandidate = function (e) {
              if (e.candidate) {
                  socket.send(JSON.stringify({
                      type: "answer_ice",
                      iceCandidate: e.candidate
                  }))
              }
          }
      
      </script>
      
      </html>
    8. 准备发送方的代码(send.html)。

      html 复制代码
      <!DOCTYPE html>
      <html lang="zh-CN">
      
      <head>
          <meta charset="UTF-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
          <title>Send</title>
      </head>
      
      <body>
          <script>
              const socket = new WebSocket('ws://localhost:8080');
              socket.onopen = function () {
                  console.log("Socket Success")
              }
              let peer = new RTCPeerConnection()
      
              navigator.mediaDevices.getUserMedia({
                  video: true,
                  audio: true
              }).then(stream => {
                  stream.getTracks().forEach(track => {
                      peer.addTrack(track, stream);
                  })
      
                  peer.createOffer().then(offer => {
                      peer.setLocalDescription(offer);
                      socket.send(JSON.stringify(offer));
                  })
              })
      
              peer.onicecandidate = function (e) {
                  if (e.candidate) {
                      socket.send(JSON.stringify({
                          type: "offer_ice",
                          iceCandidate: e.candidate
                      }))
                  }
              }
      
              // 如果接收到对方的视频
              socket.onmessage = function (e) {
                  const { type, sdp, iceCandidate } = JSON.parse(e.data)
                  console.log(type)
                  switch (type) {
                      case "answer":
                          peer.setRemoteDescription(
                              new RTCSessionDescription({ type, sdp })
                          )
                          break;
      
                      case "answer_ice":
                          peer.addIceCandidate(iceCandidate)
                          break;
      
                      default:
                          break;
                  }
              }
          </script>
      </body>
      
      </html>
    9. 使用vscode的插件live server启动两个html文件。
      下载live server插件。

      启动live server。

      启动后两个端口号。

    10. 等全部启动后,查看接收端的页面,要等一段时间,可以看到摄像头拍到的画面。
      接受端播放不了,在浏览器控制台中输入 remoteVideo.play() 就行

相关推荐
旭日猎鹰28 分钟前
Flutter踩坑记录(二)-- GestureDetector+Expanded点击无效果
前端·javascript·flutter
一条晒干的咸魚1 小时前
【Web前端】创建我的第一个 Web 表单
服务器·前端·javascript·json·对象·表单
花海少爷1 小时前
第十章 JavaScript的应用课后习题
开发语言·javascript·ecmascript
sinat_384241092 小时前
在有网络连接的机器上打包 electron 及其依赖项,在没有网络连接的机器上安装这些离线包
javascript·arcgis·electron
小牛itbull2 小时前
ReactPress vs VuePress vs WordPress
开发语言·javascript·reactpress
请叫我欧皇i2 小时前
html本地离线引入vant和vue2(详细步骤)
开发语言·前端·javascript
533_2 小时前
[vue] 深拷贝 lodash cloneDeep
前端·javascript·vue.js
GIS瞧葩菜2 小时前
局部修改3dtiles子模型的位置。
开发语言·javascript·ecmascript
zhang-zan3 小时前
nodejs操作selenium-webdriver
前端·javascript·selenium
ZBY520313 小时前
【Vue】 npm install amap-js-api-loader指南
javascript·vue.js·npm