基于webrtc的小型直播教室

github地址 (好用就star哦!): https://github.com/RobbieXie/WebRTC-Classroom

一、 相关技术栈

+ WebRTC - P2P媒体流传输
+ coturn - ICE, STUN, TURN服务器
+ NodeJs + SocketIO - 实现webrtc信令功能与基本IM功能
+ H5 Web API: 视频音频流获取 Navigator, MediaStream, etc.
+ Vue.js - 前端框架

直播间demo:

二、运行步骤

  1. 安装项目依赖

    npm install

  2. 打包

    npm run-script build

  3. 运行

    npm start

  4. 如果想外网实现直播,需要注意以下两点:

    a) 本地获取视频流,需要https域名,或者chrome->设置->信任你的站点 否则navigator.mediaDevices为undifined。

    设置方法chrome打开: chrome://flags/#unsafely-treat-insecure-origin-as-secure

    b) 服务器部署coturn,保证P2P正确寻址,否则clients间可能因为内网隔离找不到对方。 可以docker一步部署, 具体步骤参见kurento-coturn

    docker run --network=host kurento/coturn

三、项目结构

项目中有一些express模板文件没来得及删,下面将核心代码目录结构进行介绍:(本项目编写前推荐观看b站云加老师免费课程,过一遍5个小时,收益匪浅。课程link,课程源码)

  • root

    • bin

      • www #socketio服务
    • FrontProjects
      • commons

        • components

          • ClientLists #聊天室人员列表
          • MessageList #聊天框实现
        • Barrange.js #弹幕简单实现
        • Dialog.js #对话框modal框
      • Student
        • controller #学生相关逻辑
        • view
      • Teacher
        • controller #老师相关逻辑
        • view
        • net #管理与client的链接
    • public #一些依赖与打包后文件
      • vue, socketio, … libs
      • packed js, htmls
    • source
      • SocketIOSupport.js
    • package.json #依赖管理
    • webpack.config.js #打包配置

四、原理介绍

  1. WebRTC
    webrtc 是google推出的基于浏览器的实时语音-视频通讯架构。其典型的应用场景为:浏览器之间端到端(p2p)实时视频对话,但由于网络环境的复杂性(比如:路由器/交换机/防火墙等),浏览器与浏览器很多时候无法建立p2p连接,只能通过公网上的中继服务器(也就是所谓的turn服务器)中转。示例图如下:

    Fig1. webrtc通信结构

    上图中的Relay server即为turn中继服务器,而STUN server的作用是通过收集NAT背后peer端(即:躲在路由器或交换机后的电脑)对外暴露出来的ip和端口,找到一条可穿透路由器的链路,俗称“打洞”。stun/turn服务器通常要部署在公网上,能被所有peer端访问到,coturn开源项目同时实现了stun和turn服务的功能,是webrtc应用的必备首选,通信流程如下图所示:(引自 blog)

    Fig1.2 webrtc通信流程

    (1) Client A 创建一个 PeerConnection 对象,然后打开本地音视频设备,将音视频数据封装成 MediaStream 添加到 PeerConnection 中;

    (2) Client A 调用 PeerConnection 的CreateOffer 方法创建一个 offer 的 SDP 对象,SDP 对象中保存当前音视频的相关参数;

    (3) Client A 调用 SetLocalDescription 方法将 SDP 保存起来;

    (4) Client A 通过信令机制将自己的 SDP 发送给 Client B;

    (5) Client B 接收到 Client A 发送过来的 offer SDP对象,通过自己的 PeerConnection 的 SetRemoteDescription 方法将其保存起来;

    (6) Client B 调用 PeerConnection 的 CreateAnswer 方法创建一个应答的 SDP 对象;

    (7) Client B 调用 SetLocalDescription 方法保存 answer SDP 对象;

    (8) Client B 通过信令机制将自己的 SDP 发送给 Client A;

    (9) Client A 调用 PeerConnection 对象的 SetRemoteDescription 方法保存 Client B 发来的 SDP;

    (10) 在 SDP 信息的 offer/answer 流程中,Client A 和Client B 已经根据 SDP 信息创建好相应的音频Channel和视频Channel 并开启 Candidate 数据的收集,Candidate 数据可以简单地理解成 Client 端的 IP 地址信息(本地 IP 地址、公网IP地址、Relay 服务端分配的地址);

    (11) Client A 收集到自己的 Candidate 信息后,PeerConnection 会通过 OnIceCandidate 接口给 Client A 发送通知;

    (12) Client A 将收集到的 Candidate 信息通过信令机制发送给 Client B;

    (13) Client B 通过 PeerConnection 的 AddIceCandidate 方法将 Client A 的 Candidate 保存起来;

    (14) Client B 收集自己的 Candidate 信息,PeerConnection 通过 OnIceCandidate 接口给 Client B 发送通知;

    (15) Client B 将收集到的 Candidate 信息通过信令机制发送给 Client A;

    (16) Client A 通过 PeerConnection 的 AddIceCandidate 方法将 Client B Candidate 保存起来。

    至此,Client A 和 Client B 就建立了点对点的连接。备注:通信双方都必须有自己独立的 PeerConnection 对象。引自blog

    coturn部署: 为了简化部署,我采用了docker部署,第二章中有介绍,如果想手动部署,可参见coturn ubuntu deploy。

    coturn部署后测试地址 https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ice

    ,切记要出现relay done。(!!!本人在此耽误了整整一天)。

    Fig1.3 测试你的coturn

  2. H5 Web API 获取本地视频音频

    • Navigator 官方文档

    • MediaStream 官方文档

    //获取本机设备
    await navigator.mediaDevices.enumerateDevices()
    # (6) [InputDeviceInfo, InputDeviceInfo, InputDeviceInfo, MediaDeviceInfo, MediaDeviceInfo, MediaDeviceInfo]//获取屏幕流
    await navigator.mediaDevices.getDisplayMedia({audio: true, video: true});//获取camera
    await navigator.mediaDevices.getUserMedia({audio: true, video: true})
    

    合并多个媒体流multistreamsmixer

  3. SocketIO实现简单信令系统,及聊天功能

    SocketIO 在项目中充当 Fig1.2中的 Signal Server 的职责, 负责告知双方client的SDP(Session Description Protocol)、(IceCandidate)信息,此外还提供一些IM功能(创建、加入房间、发送消息等)。具体逻辑比较简单,看代码即可,此处不再赘述。

  4. 弹幕实现

    弹幕基于 div 下生成 span 子节点并通过定时器修改 span.style.left 的值来简单实现。此外还有更好的实现方式,由于不是本项目重点,可自行搜索。

  5. 一些其他可能遇见的问题

    • RTCPeerConnection iceserver配置

      let servers = {'iceServers': [{'url': 'stun:your_hostname',},{'url': 'turn:your_hostname','username': 'your_username','credential': 'your_pwd'}]
      };
      this._offerPc = new RTCPeerConnection(servers);
    • socketio 反向代理配置
      // '/live/' 为反向代理的path
      this._socket = io('wss://your_hostname', { path: '/live/socket.io'})
      

特别说明

本文来自于多篇老师的博客与自己的一些思考,刚接触这个领域,欢迎大家有问题通过issue指出,也欢迎一起完善这个小demo。如果觉得还不错,记得 Star

基于webrtc的小型直播平台相关推荐

  1. 基于WebRTC的互动直播实践

    互动直播已经逐渐成为直播的主要形式.映客直播资深音视频工程师叶峰峰在LiveVideoStackCon 2018大会的演讲中详细介绍了INKE自研连麦整体设计思路.如何基于WebRTC搭建互动直播SD ...

  2. 直播软件自动化测试,基于SRS-Bench工具的直播平台性能测试

    摘要:性能测试通过自动化的测试工具模拟正常.异常场景来对系统的各项性能指标进行测试.通过性能测试可以分析一个系统能力.瓶颈.关键问题等.本文结合直播平台的部分场景,使用开源SRS-Bench工具对直播 ...

  3. 基于Java毕业设计在线直播平台源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计在线直播平台源码+系统+mysql+lw文档+部署软件 基于Java毕业设计在线直播平台源码+系统+mysql+lw文档+部署软件 本源码技术栈: 项目架构:B/S架构 开发语言: ...

  4. 开源直播推流sdk_基于WebRTC的互动直播实践

    互动直播已经逐渐成为直播的主要形式.映客直播资深音视频工程师叶峰峰在LiveVideoStackCon 2018大会的演讲中详细介绍了INKE自研连麦整体设计思路.如何基于WebRTC搭建互动直播SD ...

  5. 七牛云徐晶:基于 WebRTC 架构的直播课堂实践

    8 月 18 日下午,在七牛云架构师实践日第三十期,七牛云教育行业产品研发总监徐晶进行了<基于 WebRTC 架构的直播课堂实践>为题的实战分享. 本文是对演讲内容的实录整理. 作者简介: ...

  6. srs流媒体服务器windows_基于SRS构建的直播平台的监控系统的搭建思路与实现方法...

    市面直播平台百家争鸣,直播监控系统是判断一个直播平台是否完善的必要条件.文章简要介绍了笔者搭建的一套基于SRS的直播平台,并从设计思路.实现方法与实现过程等方面重点介绍了针对此直播平台建设的监控系统, ...

  7. 支持mp4的rtsp服务器,基于Windows服务器,从0开始搭建一个基于RTSP协议的直播平台...

    作案工具下载 EasyDarwin 服务端程序,用来接受推流和拉流 FFmpeg 可以用来推流视频数据到服务端,也可以从服务端拉流下来播放,也可以从一个服务端拉流下来,转推到另一个服务端去. Easy ...

  8. [SRS+docker]实现直播服务器 3 基于webRTC协议的srs低延迟直播研究

    目录 前言 低延迟研究 设备兼容性 webRtc调试 播放器 体系结构 结论 问题 rtc_player.html点击播放报错 局域网RTC黑屏 附件 前言 上一篇我们通过单机版的srs服务器,验证了 ...

  9. Python-Django毕业设计基于的小型房屋租赁平台(程序+Lw)

    该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行 环境配置: Pychram社区版+ python3.7.7 + Mysql5.7 + HBuilderX+list pip+N ...

最新文章

  1. netty加载html文件的原理,Netty+html聊天室入门
  2. arm-linux-gcc makefile,ARM-LINUX-GCC简易万能makefile
  3. Basic脚本解释器移植到STM32
  4. 关于Html中jsp调用Android中方法无效的一点建议
  5. Android之TrafficStats实现流量实时监测
  6. linux单网卡多拨Adsl,ROS单线多拨pppoe
  7. ocs 2007技巧:查看存档服务记录的消息内容
  8. pythonselenium提高爬虫效率_[编程经验] Python中使用selenium进行动态爬虫
  9. web通讯录之登录注册界面
  10. Spring Boot第一个简单返回html页面的程序
  11. LeetCode58. 最后一个单词的长度
  12. 使用expect编写脚本
  13. Linux系统故障排查和修复技巧
  14. Java多线程-生产者消费者问题(多个消费者多个生产者)
  15. 计算机应用基础实操题怎么操,计算机基础实操试题
  16. cisco防火墙(Cisco防火墙型号asa)
  17. 深入支付宝支付扫描支付-跳转支付宝二维码页面支付与自定义生成二维码支付-2跳转固定的支付宝页面进行扫码支付
  18. 高、低成本MEMS惯导系统姿态、位置、速度更新算法的对比
  19. JDK8之Optional
  20. 深度学习实战教程(1)--手机跑目标检测(YOLO,从DarkNet到Caffe再到NCNN完整打通)

热门文章

  1. L016-老男孩Linux高端运维课程-linux系统文件权限体系实战深入讲解
  2. 新天龙官网服务器更新消息,《经典怀旧·新天龙八部》8月5日全服更新维护公告...
  3. CSS基础-04-浏览器调试
  4. Java+Swing捕鱼达人源码
  5. xxl-job项目的默认的用户名密码
  6. 控制用计算机应具有特点,国开(中央电大)专科《可编程控制器应用》网上形考、机考试题及答案...
  7. 人脸识别 闸机开发分享
  8. 计算机二级软件VC++6.0下载地址
  9. 【第162期】游戏策划:几年面试下来,发现自我介绍是有窍门的
  10. JAVA停车场管理系统(ArrayList、栈操作)