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

相关推荐
quitv25 分钟前
react脚手架配置别名
前端·javascript·react.js
Gazer_S2 小时前
【现代前端框架中本地图片资源的处理方案】
前端·javascript·chrome·缓存·前端框架
贺今宵4 小时前
通过$attrs传递的未指定名称的modelValue值在子组件中修改
前端·javascript
lifire_H8 小时前
Canvas在视频应用中的技术解析
前端·javascript·音视频
十八朵郁金香10 小时前
深入理解 JavaScript 中的 this 指向
开发语言·前端·javascript
贵州晓智信息科技10 小时前
使用 Three.js 转换 GLSL 粒子效果着色器
开发语言·javascript·着色器
linkcoco11 小时前
记录h5使用navigator.mediaDevices.getUserMedia录制音视频
前端·javascript·vue·音视频·js
Mh11 小时前
代码提交校验及提交规范的实践方案
前端·javascript·架构
昨日余光11 小时前
仅需三分钟,使用Vue3.x版本组件式风格实现一个消息提示组件!
前端·javascript·css·vue.js·typescript·html
软件开发技术深度爱好者11 小时前
验证码介绍及生成与验证(HTML + JavaScript实现)
javascript