基于WebRTC搭建直播平台

直播可以说是近年来最火的互联网项目,各大直播平台如雨后春笋般先后兴起,转眼间主播这一行业也成为最赚钱的代名词。那我们就来从0开始搭建一个直播平台吧。

WebRTC

WebRTC,名称源自网页实时通信(Web Real-Time Communication)。是一个支持网页浏览器进行实时语音对话或视频对话的技术,谷歌于2010年收购获得。2011年5月开放了工程的源代码,成为下一代视频通话的标准。

优点

WebRTC作为一个面向网页浏览器的实时语音视频技术,主要有以下几个优点:

  • 具有良好的通用性,几乎在任何平台都可以正常使用。
  • 其使用的Interactive Connectivity Establishment(ICE)能让各个设备之间自动匹配当前最好的通讯方式,这是很多别的技术都不具备的。
  • 具备全双工的能力,即双向通讯(P2P),不仅可作为单向直播使用还能完成电子视频会议的双向音视频对话。
  • 为Google旗下,具有良好的发展前景,最重要的:开源

开始使用

导包

这里没有直接使用官方的原生库进行编译,因为太麻烦了,网上已经有组织提供了编译好的版本可以供我们直接使用,对库的提供者不是很了解,不知道是属于什么性质的,但是几乎市面上所有的Android端都是采用该库所以应该没有什么问题。有兴趣的也可以自己去官网编译。

implementation 'io.pristine:libjingle:11139@aar'

官网网址如下:

https://webrtc.org/native-code/android/

快速开始

以下步骤都是经过分类和优化后整理出来的,加上注释,大多都能读懂,因此就不详细解释了。如有不清楚的地方可以留言问我。

  • 初始化,Peer连接工厂类:

    //初始化 关键
    PeerConnectionFactory.initializeAndroidGlobals(context, true, true, true)
    factory = PeerConnectionFactory()
  • 获得Media,简单理解就是需要传输的音视频流:

    //获取视频源
    val videoCapture = VideoCapturerAndroid.create(CameraEnumerationAndroid.getNameOfBackFacingDevice())
    val videoSource = factory.createVideoSource(videoCapture, MediaConstraints())
    //获取音频源
    val audioSource = factory.createAudioSource(MediaConstraints())
    //获取封装MediaTrack
    val videoTrack = factory.createVideoTrack("ARDAMSv0", videoSource)
    val audioTrack = factory.createAudioTrack("ARDAMSa0", audioSource)
    //封装媒体流
    localMs = factory.createLocalMediaStream("ARDAMS")
    localMs?.addTrack(videoTrack)
    localMs?.addTrack(audioTrack)
    //预览
    preview?.invoke(localMs!!)
  • 配置ICE,进行网络连接:

    //Ice NAT穿透
    val iceList = ArrayList<PeerConnection.IceServer>()
    iceList.add(PeerConnection.IceServer("stun:23.21.150.121"))
    iceList.add(PeerConnection.IceServer("stun:stun.l.google.com:19302"))
    //媒体限制
    val constraints = MediaConstraints()
    constraints.mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"))
    constraints.mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"))
    constraints.optional.add(MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true"))
    pc = factory.createPeerConnection(iceList, constraints, Observer())
    pc?.addStream(localMs)

    这里使用的是stun方式,ICE逻辑判断逻辑很复杂,主要分为两种方式:STUN、TURN。

    STUN是将本地地址转换成外部可访问的公网地址,说白了有点像内网穿透的意思。

    TURN则是需要自己搭建,由公共中介服务器分配地址。

    有兴趣可以看我接下来的另一篇介绍ICE的博文。

  • 创建Offer:

    pc?.createOffer(Observer(), MediaConstraints())

    WebRTC模型中Peer之间需要进行信令交换,而承载信令的载体就是Offer/Answer,这里因为是实现的直播推流端,因此创建的是Offer,如果是观看端则需要创建Answer。

  • 信令交换:

    private inner class Observer : SdpObserver, PeerConnection.Observer {
    //创建offer成功override fun onCreateSuccess(p0: SessionDescription?) {log("offer:${p0?.description}")pc?.setLocalDescription(Observer(), p0)val jsonObject = JSONObject()jsonObject.put("id", "presenter")jsonObject.put("sdpOffer", p0?.description)SocketUtils.sendMsg(jsonObject.toString())log("json:$jsonObject")}//创建offer失败override fun onCreateFailure(p0: String?) {log("error: create offer $p0")}//当网络可用即Ice穿透成功override fun onIceCandidate(p0: IceCandidate?) {val jsonObject = JSONObject()jsonObject.put("id", "onIceCandidate")val ice = JSONObject()ice.put("sdpMid", p0?.sdpMid)ice.put("sdpMLineIndex", p0?.sdpMLineIndex)ice.put("usernameFragment", p0?.sdp?.substringAfter("ufrag ")?.substring(0, 4))ice.put("candidate", p0?.sdp)jsonObject.put("candidate", ice)SocketUtils.sendMsg(jsonObject.toString())log("iceCandidate:$p0")log("json:$jsonObject")}
    }

    通过Socket获得:

      private fun setRemoteSdp(sdp: String) {val answer = SessionDescription(SessionDescription.Type.ANSWER, sdp)pc?.setRemoteDescription(Observer(), answer)}private fun setRemoteIce(ice: EventIceCandidate) {ice.candidate?.let {pc?.addIceCandidate(IceCandidate(it.sdpMid,it.sdpMLineIndex,it.candidate))}}
  • 显示画面

          gl_view.preserveEGLContextOnPause = truegl_view.keepScreenOn = trueVideoRendererGui.setView(gl_view) {RtcClient(this).preview = { localMs ->// local and remote renderval localRender = VideoRendererGui.createGui(LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED,LOCAL_WIDTH_CONNECTED, LOCAL_HEIGHT_CONNECTED,RendererCommon.ScalingType.SCALE_ASPECT_FILL,false)localMs.videoTracks[0].addRenderer(localRender)}}

主要流程

直播端

  • 初始化,Peer连接工厂类。
  • 获取Media,创建GL渲染器,进入显示就绪状态。
  • 配置ICE并监听,当Candidate收集完成发送给远程端。
  • 创建Offer,当Offer创建完成发送给远程端。
  • 接收远程端发送的ICE信息,并设置给PeerConnection对象。
  • 接收远程端返回的Answer,并设置给PeerConnection对象。
  • 建立连接,开始直播。

观看端

  • 初始化,Peer连接工厂类。
  • 获取Media,创建GL渲染器,进入显示就绪状态。
  • 配置ICE并监听,当Candidate收集完成发送给远程端。
  • 接收远程端发送的ICE信息,并设置给PeerConnection对象。
  • 接收远程端发送的Offer,并设置给PeerConnection对象。
  • 创建Answer,当Answer创建完成发送给远程端。
  • 建立连接,开始直播。

基于WebRTC搭建直播平台相关推荐

  1. webrtc 搭建直播平台

    设计思路 需求: 一个直播页面,可以输入直播名.一个观看页面输入客户名个要看的直播名建立直播视频传输 思路: 直播页面输入直播名建立websocket连接,创建PeerConnection对象组存放连 ...

  2. 如何从零开始搭建直播平台,从flash时代的rtmp到过渡期的flv和webrtc的未来以及简单聊聊webassmbly

    前言 在2020年12月flash正式落幕之后,流媒体领域是否有新的技术替代?有没有较为成熟的整体方案?市面上的直播/流媒体平台都在使用哪些方案?有没有通用又简单快速的搭建方案?不同的方案在行业内部也 ...

  3. 搭建直播平台,你需要先知道这些

    搭建直播平台,你需要先知道这些 一.直播知识小科普 一个典型的直播流程:录制->编码->网络传输(推流->服务器处理->CDN分发)->解码->播放 IPB:一种常 ...

  4. 如何搭建直播平台?低延时连麦+人工智能让互动升级

    摘要: 通过集成阿里云直播SDK,用户可以轻松实现移动端.PC端的直播流推送.直播服务器接收到直播流,对流进行处理(转封装.转码等),并通过CDN进行分发.支持10万+路流输出,1000万+观众同时在 ...

  5. 搭建直播平台什么样的服务器最合适?

    服务器也称伺服器,是提供计算服务的设备.由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力.服务器是我们在搭建直播平台唯一需要的硬件设备. 直播中比较常用的服务 ...

  6. 搭建直播平台过程中的全能“辅助”——流媒体服务器

    直播在经历了爆发式增长后,在互联网领域中呈现出稳步增长的状态.前期观望许久的创业开发者们认为"火候到了",纷纷开始将搭建直播平台项目提上日程.对于平台搭建来讲,流媒体服务器是必不可 ...

  7. 搭建直播平台过程中的全能“辅助”——流媒体服务器...

    直播在经历了爆发式增长后,在互联网领域中呈现出稳步增长的状态.前期观望许久的创业开发者们认为"火候到了",纷纷开始将搭建直播平台项目提上日程.对于平台搭建来讲,流媒体服务器是必不可 ...

  8. 怎么搭建直播平台,直播环境搭建该怎样做?

    怎么搭建直播平台,直播环境搭建该怎样做? 目录 环境准备 ●Centos系统安装:请查看我的另一篇博客Java后端之路(六)安装Linux系统 ●git安装(系统如果没有的话):www.cnblogs ...

  9. 搭建直播平台源码用到的云技术到底是什么

    现在在搭建直播平台源码时经常会听到云技术这个词,云技术到底是什么?很多第一次听到的人都会有这个困扰,简单说,云技术就是将局域网或广域网内的硬件.软件和网络等一系列资源统一整合起来,通过托管对数据的计算 ...

最新文章

  1. leetcode算法题--计算各个位数不同的数字个数
  2. mysql的status状态说明
  3. DVWA 黑客攻防实战(十五) 绕过内容安全策略 Content Security Policy (CSP) Bypass
  4. 字符串和json之间的互相转化
  5. 怎样查看rpm安装包的安装路径
  6. c++ string 堆还是栈_5 个刁钻的 String 面试题!你都遇到过哪些?
  7. 【ACM】nyoj_305_表达式求值_201308081018
  8. 磁盘剩余空间策略_MySQL磁盘消耗迅猛掌握这点就够了,包你事半功倍
  9. 最准的中文文本相似度计算工具
  10. 用计算机打李白的歌,抖音笨李白是什么歌 歌词中带有笨李白原版歌曲名字-游侠手游...
  11. MIKE水动力笔记3_岸线及水深数据之根据遥感影像绘制岸线的方法
  12. 使用Python和MySQL实现网上购物管理系统
  13. ElasticJob‐Lite:作业监听器
  14. 速记软考之木马和病毒
  15. 软件工程学习笔记——软件开发模型
  16. 穷举查找之旅行商问题、背包问题、分配问题
  17. Javascript使用turndown 将html 转为md
  18. 你真的了解“手机端的 C/S架构 向 B/S架构 迁移”吗
  19. 程序员坐行李箱迎寒风编码2小时,上热搜!你怎么看?
  20. 五千字聊一聊接口测试

热门文章

  1. PHP开发_PDO应用
  2. java 数组元素依次右移,将数组元素循环右移k个位置(Java实现)
  3. 汉(海)明码 | “十六宫格法” 破解汉(海)明码相关题目(附软考经典例题)
  4. 入职前端工程师你需要学会什么?前端实习生告诉你十大必备技能
  5. prometheus+consul 服务自动发现监控
  6. 物联卡采购注意要点有哪些
  7. 4K分辨率搭配光学变焦功能,极米H6成旗舰家用投影首选
  8. 计算机术语harddrive是什么意思,hard drive是什么意思
  9. [LeetCode]187. 重复的DNA序列(java实现)暴力 + 哈希
  10. android学习之屏幕解锁