基于WebRTC搭建直播平台
基于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搭建直播平台相关推荐
- webrtc 搭建直播平台
设计思路 需求: 一个直播页面,可以输入直播名.一个观看页面输入客户名个要看的直播名建立直播视频传输 思路: 直播页面输入直播名建立websocket连接,创建PeerConnection对象组存放连 ...
- 如何从零开始搭建直播平台,从flash时代的rtmp到过渡期的flv和webrtc的未来以及简单聊聊webassmbly
前言 在2020年12月flash正式落幕之后,流媒体领域是否有新的技术替代?有没有较为成熟的整体方案?市面上的直播/流媒体平台都在使用哪些方案?有没有通用又简单快速的搭建方案?不同的方案在行业内部也 ...
- 搭建直播平台,你需要先知道这些
搭建直播平台,你需要先知道这些 一.直播知识小科普 一个典型的直播流程:录制->编码->网络传输(推流->服务器处理->CDN分发)->解码->播放 IPB:一种常 ...
- 如何搭建直播平台?低延时连麦+人工智能让互动升级
摘要: 通过集成阿里云直播SDK,用户可以轻松实现移动端.PC端的直播流推送.直播服务器接收到直播流,对流进行处理(转封装.转码等),并通过CDN进行分发.支持10万+路流输出,1000万+观众同时在 ...
- 搭建直播平台什么样的服务器最合适?
服务器也称伺服器,是提供计算服务的设备.由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力.服务器是我们在搭建直播平台唯一需要的硬件设备. 直播中比较常用的服务 ...
- 搭建直播平台过程中的全能“辅助”——流媒体服务器
直播在经历了爆发式增长后,在互联网领域中呈现出稳步增长的状态.前期观望许久的创业开发者们认为"火候到了",纷纷开始将搭建直播平台项目提上日程.对于平台搭建来讲,流媒体服务器是必不可 ...
- 搭建直播平台过程中的全能“辅助”——流媒体服务器...
直播在经历了爆发式增长后,在互联网领域中呈现出稳步增长的状态.前期观望许久的创业开发者们认为"火候到了",纷纷开始将搭建直播平台项目提上日程.对于平台搭建来讲,流媒体服务器是必不可 ...
- 怎么搭建直播平台,直播环境搭建该怎样做?
怎么搭建直播平台,直播环境搭建该怎样做? 目录 环境准备 ●Centos系统安装:请查看我的另一篇博客Java后端之路(六)安装Linux系统 ●git安装(系统如果没有的话):www.cnblogs ...
- 搭建直播平台源码用到的云技术到底是什么
现在在搭建直播平台源码时经常会听到云技术这个词,云技术到底是什么?很多第一次听到的人都会有这个困扰,简单说,云技术就是将局域网或广域网内的硬件.软件和网络等一系列资源统一整合起来,通过托管对数据的计算 ...
最新文章
- leetcode算法题--计算各个位数不同的数字个数
- mysql的status状态说明
- DVWA 黑客攻防实战(十五) 绕过内容安全策略 Content Security Policy (CSP) Bypass
- 字符串和json之间的互相转化
- 怎样查看rpm安装包的安装路径
- c++ string 堆还是栈_5 个刁钻的 String 面试题!你都遇到过哪些?
- 【ACM】nyoj_305_表达式求值_201308081018
- 磁盘剩余空间策略_MySQL磁盘消耗迅猛掌握这点就够了,包你事半功倍
- 最准的中文文本相似度计算工具
- 用计算机打李白的歌,抖音笨李白是什么歌 歌词中带有笨李白原版歌曲名字-游侠手游...
- MIKE水动力笔记3_岸线及水深数据之根据遥感影像绘制岸线的方法
- 使用Python和MySQL实现网上购物管理系统
- ElasticJob‐Lite:作业监听器
- 速记软考之木马和病毒
- 软件工程学习笔记——软件开发模型
- 穷举查找之旅行商问题、背包问题、分配问题
- Javascript使用turndown 将html 转为md
- 你真的了解“手机端的 C/S架构 向 B/S架构 迁移”吗
- 程序员坐行李箱迎寒风编码2小时,上热搜!你怎么看?
- 五千字聊一聊接口测试
热门文章
- PHP开发_PDO应用
- java 数组元素依次右移,将数组元素循环右移k个位置(Java实现)
- 汉(海)明码 | “十六宫格法” 破解汉(海)明码相关题目(附软考经典例题)
- 入职前端工程师你需要学会什么?前端实习生告诉你十大必备技能
- prometheus+consul 服务自动发现监控
- 物联卡采购注意要点有哪些
- 4K分辨率搭配光学变焦功能,极米H6成旗舰家用投影首选
- 计算机术语harddrive是什么意思,hard drive是什么意思
- [LeetCode]187. 重复的DNA序列(java实现)暴力 + 哈希
- android学习之屏幕解锁