使用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() 就行

相关推荐
web行路人30 分钟前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
番茄小酱00131 分钟前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
子非鱼9211 小时前
【Ajax】跨域
javascript·ajax·cors·jsonp
超雄代码狂1 小时前
ajax关于axios库的运用小案例
前端·javascript·ajax
周亚鑫2 小时前
vue3 pdf base64转成文件流打开
前端·javascript·pdf
落魄小二2 小时前
el-table 表格索引不展示问题
javascript·vue.js·elementui
y5236482 小时前
Javascript监控元素样式变化
开发语言·javascript·ecmascript
fruge2 小时前
纯css制作声波扩散动画、js+css3波纹催眠动画特效、【css3动画】圆波扩散效果、雷达光波效果完整代码
javascript·css·css3
neter.asia2 小时前
vue中如何关闭eslint检测?
前端·javascript·vue.js
嚣张农民2 小时前
JavaScript中Promise分别有哪些函数?
前端·javascript·面试