当前位置: 首页 > news >正文

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

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

      创建package.json。

    4. 新建server.js,复制一下代码
      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. 下载信令服务器的依赖。
      npm install express;
      npm install express-ws;
      npm install cors;
    6. 使用node server.js启动node的服务。
    7. 准备接收方的代码(receive.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)。
      <!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() 就行
       

相关文章:

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

首先需要一个信令服务器&#xff0c;我们使用nodejs来搭建。两个端&#xff1a;发送端和接收端。我的目录结构如下图&#xff1a;流程 创建一个文件夹 WebRTC-Test。进入文件夹中&#xff0c;新建一个node的文件夹。使用终端并进入node的目录下&#xff0c;使用 npm init 创建p…...

LeetCode 2707. Extra Characters in a String【动态规划,记忆化搜索,Trie】1735

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…...

设计模式行为型-模板模式

文章目录 一&#xff1a;模板方法设计模式概述1.1 简介1.2 定义和目的1.3 关键特点1.4 适用场景 二&#xff1a;模板方法设计模式基本原理2.1 抽象类2.1.1 定义和作用2.1.2 模板方法2.1.3 具体方法 2.2 具体类2.2.1 定义和作用2.2.2 实现抽象类中的抽象方法2.2.3 覆盖钩子方法 …...

9.3.tensorRT高级(4)封装系列-自动驾驶案例项目self-driving-车道线检测

目录 前言1. 车道线检测总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习 tensorRT 高级-自动驾驶案例项目self-driving-车道…...

django.core.exceptions.AppRegistryNotReady: Apps aren‘t loaded yet.

运行django测试用例报错django.core.exceptions.AppRegistryNotReady: Apps arent loaded yet. 解决&#xff1a;在测试文件上方加上 django.setup() django.setup()是Django框架中的一个函数。它用于在非Django环境下使用Django的各种功能、模型和设置。 在常规的Django应用…...

【C#】C#调用进程打开一个exe程序

文章目录 一、过程二、效果总结 一、过程 新建WinForm程序&#xff0c;并写入代码&#xff0c;明确要调用的程序的绝对路径&#xff08;或相对路径&#xff09;下的exe文件。 调用代码&#xff1a; 这里我调用的另一个程序的路径是&#xff1a; F:\WindowsFormsApplication2…...

宝塔面板定时监控和重启MySQL数据库(计划任务)

往期教程 如果还有不了解宝塔面板怎么使用的小伙伴&#xff0c;可以看下我总结的系列教程&#xff0c;保证从新手变老鸟&#xff1a; 【建站流程科普】 个人和企业搭建网站基本流程及六个主要步骤常见的VPS主机运维面板汇总—网站运维面板云服务器&#xff0c;VPS&#xff0…...

Beats:安装及配置 Metricbeat (二)- 8.x

这篇文章是继文章 “Beats&#xff1a;安装及配置 Metricbeat &#xff08;一&#xff09;- 8.x” 的续篇。你可以先阅读之前的那篇文章再继续阅读这篇文章。我们在这篇文章中继续之前的探讨。 使用 fingerprint 来代替证书 在实际的使用中&#xff0c;我们需要从 Elasticsear…...

Redis之哨兵模式解读

目录 基本介绍 单哨兵模式 多哨兵模式 哨兵的本质 配置哨兵模式 故障恢复原理 哨兵监控工作流程 哨兵模式缺点 基本介绍 当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多…...

题目:2644.找出可整除性得分最大的整数

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;2644. 找出可整除性得分最大的整数 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 遍历计算即可。 解题代码&#xff1a; class Solution {public int maxDivScore(int[] nums, int[] di…...

报错:axios 发送的接口请求 404

axios 发送的接口请求 404 一、问题二、分析 一、问题 二、分析 axios 发送的接口请求 404&#xff0c;根本没有把接口信息发送到后端&#xff0c;这个时候你可以查看检查一下自己的接口名字&#xff0c;或让后端配合换一个接口名字再发送一次接口请求...

三年前端还不会配置Nginx?刷完这篇就够了

什么是Nginx Nginx是一个开源的高性能HTTP和反向代理服务器。它可以用于处理静态资源、负载均衡、反向代理和缓存等任务。Nginx被广泛用于构建高可用性、高性能的Web应用程序和网站。它具有低内存消耗、高并发能力和良好的稳定性&#xff0c;因此在互联网领域非常受欢迎。 为…...

blender 场景灯光基础设置

在 blender 中&#xff0c;打光分为两个部分&#xff0c;一个是世界光&#xff0c;一个是场景光&#xff1b; 世界光&#xff1a; 世界光&#xff1a;在 Blender 中&#xff0c;世界光指的是用于设置场景整体照明的环境光。它可以通过调整颜色、强度、阴影等参数来影响场景的…...

如何查看 SQLyog 中数据库连接信息中的密码

SQLyog 数据库连接信息中的密码无法选择明文展示&#xff0c;也无法复制 可以将数据库连接信息导出到文本查看明文密码 工具--》导入/导出连接详情&#xff1a;...

【SpringSecurity】八、集成图片验证码

文章目录 1、生成图片验证码2、创建验证码过滤器3、将过滤器加入SpringSecurity过滤链4、修改登录页 SpringSecurity是通过过滤器链来完成的&#xff0c;接下来的验证码&#xff0c;可以尝试创建一个过滤器放到Security的过滤器链中&#xff0c;在自定义的过滤器中比较验证码。…...

【本地代码问题】启动程序,报错:java.lang.IllegalArgumentException: No selectors

启动程序的时候报错了 问题怎么出现的解决方式&#xff0c;注释掉jetty的内容&#xff0c;回归tomcat的使用 问题怎么出现的 我本地启动程序的时候报错了&#xff1a;报的是这个错误&#xff0c;可能和容器的选择有关吧 解决方式&#xff0c;注释掉jetty的内容&#xff0c;回…...

手写RPC框架--4.服务注册

RPC框架-Gitee代码(麻烦点个Starred, 支持一下吧) RPC框架-GitHub代码(麻烦点个Starred, 支持一下吧) 服务注册 服务注册a.添加服务节点和主机节点b.抽象注册中心c.本地服务列表 服务注册 a.添加服务节点和主机节点 主要完成服务注册和发现的功能&#xff0c;其具体流程如下&…...

oracle 解锁表

操作的前提 用 sys 用户 以 SYSDBA 角色登录 第一种解锁方式 1.查询被锁的表 select object_name,machine,s.sid,s.serial# from v$locked_object l,dba_objects o ,v$session s where l.object_id  o.object_id and l.session_ids.sid;2.查询那个session引起表被锁 sele…...

使用Dbeaver连接GaussDB

1.下载DBeaver&#xff0c;官网地址 2.安装软件&#xff0c;打开软件&#xff0c;点击数据库->驱动管理器&#xff0c;具体操作如下图&#xff1a; 3、选择新建后进行参数设置&#xff0c;如下图&#xff1a; 具体参数如下图 驱动名称: GS #随便定义 驱动类型&#…...

WSL使用技巧 / 虚拟机对比

WSL使用技巧 / 虚拟机对比 前言虚拟机比较VMware使用技巧WSL使用技巧官方文档工具安装WSL基本命令运行命令关闭卸载磁盘管理导入导出指定安装路径 前言 本文介绍了VMware和WSL的区别&#xff0c;并详细介绍了WSL的使用方法和技巧。 虚拟机比较 VMware 比较灵活&#xff0c;拥…...

LeetCode 每日一题笔记 日期:2026.05.16 题目:154. 寻找旋转排序数组中的最小值 II

LeetCode 每日一题笔记 0. 前言 日期&#xff1a;2026.05.16题目&#xff1a;154. 寻找旋转排序数组中的最小值 II难度&#xff1a;困难标签&#xff1a;数组、二分查找 1. 题目理解 问题描述&#xff1a; 给定一个可能存在重复元素的升序数组&#xff0c;经过1~n次旋转后&…...

从项目实战出发:如何用AVL Cruise 2019与MATLAB/Simulink完成一个完整的DLL联合仿真流程?

从项目实战出发&#xff1a;如何用AVL Cruise 2019与MATLAB/Simulink完成一个完整的DLL联合仿真流程&#xff1f; 在汽车工程领域&#xff0c;系统级仿真已成为开发流程中不可或缺的一环。当我们需要评估整车动力系统性能时&#xff0c;AVL Cruise作为专业车辆仿真软件&#xf…...

ArcGIS Pro脚本工具实战:5分钟用arcpy给要素批量‘改名’(保姆级参数配置指南)

ArcGIS Pro脚本工具实战&#xff1a;5分钟用arcpy给要素批量‘改名’&#xff08;保姆级参数配置指南&#xff09; 当你在处理上百个GIS图层时&#xff0c;是否曾被重复的"右键-属性-修改别名"操作折磨到崩溃&#xff1f;上周我接手一个城市管网项目&#xff0c;需要…...

C AI 编程助手:助力开发者高效编程

C AI 编程助手:助力开发者高效编程 引言 随着人工智能技术的飞速发展,编程领域也迎来了新的变革。C AI 编程助手作为一种新兴的智能编程工具,旨在帮助开发者提高编程效率,降低开发成本。本文将详细介绍C AI 编程助手的功能、优势以及应用场景,帮助开发者更好地了解这一创…...

别再手动调寄存器了!用Simulink给F28335 DSP配置ePWM,20kHz互补带死区输出一次搞定

告别寄存器调试&#xff1a;用Simulink图形化配置F28335 DSP的ePWM模块 在电机控制和电源逆变器开发中&#xff0c;PWM信号生成是核心环节。传统开发方式需要工程师反复查阅数百页的数据手册&#xff0c;手动计算并配置数十个寄存器参数&#xff0c;一个简单的死区时间设置就可…...

保姆级教程:用QGIS 3.22.16给火星遥感影像‘抠图’,从创建矢量图层到GDAL裁剪一步到位

火星地质勘探实战&#xff1a;用QGIS精准提取毅力号影像的五大核心技巧 当第一缕阳光掠过火星杰泽罗陨石坑的悬崖&#xff0c;毅力号传回的遥感影像中藏着无数科学秘密。作为太空数据分析师&#xff0c;我们常需要从广袤的火星地表影像中精确"抠"出目标区域——就像地…...

告别标注烦恼!用DINO+ViT自监督训练,5步搞定你的图像特征提取器(附代码)

5步实战DINOViT自监督训练&#xff1a;零标注构建高效图像特征提取器 在计算机视觉领域&#xff0c;数据标注一直是制约模型性能提升的瓶颈。传统监督学习需要大量人工标注数据&#xff0c;而高质量标注不仅成本高昂&#xff0c;还可能引入人为偏见。自监督学习(self-supervise…...

5大核心功能揭秘:MoneyPrinterPlus如何实现AI短视频自动化批量生产

5大核心功能揭秘&#xff1a;MoneyPrinterPlus如何实现AI短视频自动化批量生产 【免费下载链接】MoneyPrinterPlus AI一键批量生成各类短视频,自动批量混剪短视频,自动把视频发布到抖音,快手,小红书,视频号上,赚钱从来没有这么容易过! 支持本地语音模型chatTTS,fasterwhisper,G…...

Electron应用上鸿蒙PC,安装包从180MB压到45MB,我做了哪些骚操作

Electron应用上鸿蒙PC&#xff0c;安装包从180MB压到45MB&#xff0c;我做了哪些骚操作 上个月老板丢给我一个任务&#xff1a;把现有的Electron应用搬到鸿蒙PC上。我花了两天把代码跑通了&#xff0c;build了一版安装包&#xff0c;一看体积——180MB。老板看了一眼&#xff0…...

SAP EWM实战:从产品到处理单位,两种库存转移操作保姆级教程

SAP EWM库存转移实战指南&#xff1a;产品与处理单位的精准操作 在仓库管理的日常工作中&#xff0c;库存转移是最基础却最容易出错的环节之一。特别是对于刚接触SAP EWM系统的管理员来说&#xff0c;面对不同形态的物料——散件产品和带包装的处理单位(HU)&#xff0c;往往会产…...