干货 | 携程移动直播探索
作者简介
鹏程,携程 Android 开发工程师,Android google jetpack和kotlin语言的拥护者。
一、背景
直播行业大概在10年前就开始兴起了,秀场直播和游戏直播是pc时代比较成功的应用场景。现阶段,移动互联网的大规模普及,流量价格越来越便宜,移动视频直播异常火爆,随着各行各业的不断融合,直播带货超高的营业额,明星艺人、销售、秀场网红的涌入,直播行业迎来了空前的繁荣发展。从pc直播到渐渐火爆的移动直播,直播技术也在不断地更新迭代,趋于成熟。
本文从直播流的选择、交互优化、快速迭代等方面介绍携程直播技术。
二、直播原理
视频直播流程如下图。简单来说,推流端通过视频采集功能,把采集到的视频画面经过一系列的业务特效处理后,进行视频编码推送。拉流端使用流播放器把视频画面播放出来。
采集:视频采集的主要采集源:摄像头、屏幕录制、视频文件推流
处理:视频采集后得到原始数据,为了增强一些现场效果,需要在编码前进行处理(logo、美颜、变声)
编码:编码性能、编码速率和编码压缩比直接影响整个流媒体传送的用户体验和传送成本
推流:推流是直播的第一步。推流协议的选择会直接影响到观看的用户体验,常见的流协议(RTMP、HLS)
分发:流媒体服务器负责直播流的发布和转播分发功能
播放:直播终端的展示
前四步我们通常情况下称为推流操作,第五步称为服务分发或者cdn分发,第六步称为拉流操作。简化图如下:
推流操作中比较重要的两步是编码和推流。
2.1 编码
1)编码是什么
视频编码是压缩和可能改变视频内容格式的过程。
2)编码能做什么
a. 减少占用空间;
b. 兼容性;
在减少占用空间方面:
(数据来源于网络)
在兼容性方面,有时内容已经被压缩到足够的大小,但仍然需要进行编码以实现兼容性。这通常被更准确地描述为代码转换。兼容可能涉及某些服务或程序,这些服务或程序需要某些编码规范。
国内常见的编解码器是H.265、H.264。
2.2 推流
常见的流协议为以下几种:
1)RTMP
RTMP(Real Time MessagingProtocol):实时消息传输协议,是Adobe公司为flash播放器和服务器之间实现音频、视频和数据传输开发的实时消息传输协议。在RTMP协议中,视频必须是H264编码,音频必须是AAC或者MP3编码,且多以Flv格式封包。
RTMP的优势在于:
RTMP 是专为流媒体开发的协议,对底层的优化比其它协议更加优秀,同时它 Adobe Flash 支持好,基本上所有的编码器(摄像头之类)都支持 RTMP 输出。
RTMP适合长时间播放。因为RTMP支持的很完善,所以能做到flash播放RTMP流长时间不断流。当时的测试时长是100万秒,即10天多可以连续播放。(数据来源于网络)
RTMP 的延迟相对较低,一般延时在 1-5s 之间,一般的视频会议,互动式直播,完全是够用的。
RTMP的劣势是:RTMP是基于TCP协议,不会丢包。所以当网络状态差时,服务器会将包缓存起来,导致累积的延迟;待网络状况好了,就一起发给客户端。
2)HLS
HLS(HTTPLive Straming): 是苹果公司实现的基于HTTP的流媒体传输协议。它将整个流分为多个小文件来下载,客户端只要不停的按顺序播放从服务器获取的文件,就实现了直播。
HLS的优势是:客户端支持简单,只需要支持HTTP请求即可。并且HTTP协议很方便通过防火墙或者代理服务器。CDN支持良好。由于是苹果公司提出的,所以在苹果的全系列产品都支持。
HLS的劣势:相比 RTMP 这类长连接协议,HLS的延时较高, 难以用到互动直播场景。
3)WebRTC
WebRTC(Web Real TimeCommunication):是一个支持浏览器进行实时语音、视频对话的开源协议。基于UDP,即使在网络信号一般的情况下也具备较好的稳定性。
WebRTC的优点:开发者使用简单的HTML标签和JavaScriptAPI就能够实现Web音/视频通信的功能。
WebRTC的缺点:WebRTC中很多的参数都是由GIPS公司的工程师们依靠经验所设定的值,这就会出现卡顿、延时、回声、丢包、多人视频不稳定等问题。WebRTC缺乏服务器方案的设计和部署。对Native开发支持不够。
4)HTTP-Flv
HTTP-Flv:是一种将直播流模拟成flv文件,通过http协议进行下载的模式实现流媒体传输的协议。
它结合了RTMP的低延时,以及可以复用现有HTTP分发资源的流式协议。优势在于可以在一定程度上避免防火墙的干扰,可以使用HTTPS做加密通道,很好的支持移动端。
缺点在于由于它的传输特性,会让流媒体资源缓存在本地客户端,在保密性方面不够好。因为网络流量较大,它也不适合做拉流协议。
协议 |
http-flv |
RTMP |
HLS |
WebRTC |
传输方式 |
HTTP长连接 |
Tcp |
http短连接 |
UDP |
视频封装格式 |
FLV |
FLV |
TS文件 |
Track分片 |
原理 |
同RTMP,使用HTTP协议 |
每个时刻的数据收到后立即转发 |
集合一段时间的数据,生产TS切片并更新m3u8索引 |
Udp 传输协议,保证低延时和及时性。 Client-client之间传输,要解决NAT 穿透问题。 |
延时 |
低 1-5s |
低 1-5s |
高 10-20秒 |
低1-2s |
数据分段 |
连续流 |
连续流 |
切片文件 |
P2P数据交换 |
Html5 |
支持 |
不支持 |
支持 |
支持 |
其他 |
需要Flash技术支持, |
网络质量要求高 |
要解决NAT,socket建立等问题 |
我们选择RTMP作为主要的流协议的原因有:
1)RTMP是编码器输入的工业标准协议,基本上所有的编码器(摄像头等)都支持RTMP输出。
2)RTMP适合长时间播放的优势,可以保证尽可能的减少用户重连的次数。
3)直播场景互动性交高,对时延要求高。RTMP通常情况下可以做到3秒延迟,满足大多数场景(hls大概10秒)。
4)WebRTC对浏览器支持较好,对native支持不够,需要做大量的开发工作。
5)由于开源软件和开源库的支持稳定完整(OBS软件,开源的librtmp库,服务端有nginx-rtmp插件),RTMP在国内流行度很高,技术相对成熟。
目前市面上有很多云直播厂商。可以综合考虑推流协议,时延要求、推拉流费用,SDK的size以及扩展直播场景等方面来选择适合自己的sdk。
三、直播前端框架
当我们需要建立一个直播的时候,我们需要做什么呢?
简单的来说分3步。
第一步:从sdk中拿出推流Manager,设置预览View,设置推流地址。
@Overrideprotected void onCreate(Bundle bundle) {super.onCreate(bundle);setContentView(R.layout.live_push);livePusher = new LivePusher();videoView = findViewById(R.id. live_video_preview);livePusher. startCameraPreview(videoView);String pushUrl = "rtmp://...";livePusher.startPusher(PushUrl);}
第二步:使用拉流Manager,设置播放预览view,设置拉流地址和流类型(RTMP、flv等)。
@Overrideprotected void onCreate(Bundle bundle) {super.onCreate(bundle);setContentView(R.layout.live_pull);livePlayer = new LivePlayer();playerView = findViewById(R.id.live_video_view);String pullURl = "rtmp://...";livePlayer.setPlayerView(playerView)livePlayer.startPlay(pullURl, PLAY_TYPE_LIVE_RTMP)}
第三步就可以愉快地观看直播了。
携程直播就是在这个基础之上,进行了复杂的业务开发。视频推流和拉流是需要调用Native直播sdk的方法,所以需要保留在Native中。页面上的互动区域需要更快速的迭代方式,所以选择了RN。
携程直播作出以下的分层结构:
视频直播前端框架图
1)Lib
这一层主要放置整个直播项目通用的类。
ClientProxy:网络请求的通用字段封装和返回的常规错误码处理、序列化处理、通用Log日志控制等。
PushManger 和 PullManger 使用了 Proxy 设计模式用于减少sdk和业务代码的耦合。使用单例模式保证多个直播的配置统一。
Event:跨平台事件传递类(EventBus),RN、Hybrid的事件都最终调用native的Event方法发送事件来保证多平台事件传递的可能。
RN:
Event.sendEvent("EventName",{ params: 0 });
Native:
CtripEventCenter.getInstance().sendMessage(EventName,jsonObject)
底层都是调用Native的EventBus。
IMManger:消息的管理类。控制直播间的弹幕消息,开始结束消息以及礼物等消息的分发。
2)Page
把推流和拉流页面称为Page。主要作用有两个,首先调用SDK做推拉流。其次,在页面中对RN和Native进行交互,例如从消息中获取流状态、礼物或者其他的消息。然后给RN发Event事件或者调用Native方法来完成相关消息的后续动作。
Page中注册消息监听。
interface CTLiveChatMessageListener {fun startLive()
}
Page.registerCTLiveChatMessageListener(listener)
在listener中使用Event分发事件。
3)View层
Page上挂载了一个透明的RNView作为直播中交互View。主要负责渲染业务交互view,比如头像名称、评论列表、礼物动画、商品卡片、分享等。
在 page 的 onCreate 的时候把 view 挂载上去。
manager.beginTransaction().add(R.id.live_crn_fragment, rnFragment,"livePage").commitAllowingStateLoss()
然后页面和逻辑放到RN中。
效果图上,摄像头的内容为原生Native,其他的可见为RNVIew。
四、遇到的问题和解决的办法
在Native-RN 混合开发过程中,我们遇到了一些棘手的问题:
1)在多次唤醒直播间,或者同时打开多个直播间时,会存在画面和声音对不上,或者出现多个声道的问题。为了解决这个问题我们把直播间做成单例,保证整个app的运行过程中只存在一个直播间。
2)覆盖在直播预览页面上面的交互RNView设置为透明背景不生效问题。我们在RN的render返回一个透明View,但是在页面上还是出现了白色的底色。这个时候需要检查一下fragment是否挂载在一个白色View上。
3)在Page初始化的时候发送Event事件,但是RN没有收到的问题。这个时候RN容器可能还没有创建完成,我们需要保证发送事件的时机在RN容器创建完成之后。
五、总结
视频直播在近几年是一个比较火爆的技术点。直播的场景每年都在迅速地更新中。我们需要使用一种更快速的迭代方式,所以需要在优化时把稳定的东西使用native封装成基础页面,在保证底层稳定的前提下,选择跨平台的技术栈进行快速的页面迭代开发。ReactNative或者Flutter等跨平台开发语言都是不错的选择。
【推荐阅读】
深入浅出Apple响应式框架Combine
高耦合场景下,Trip.com如何做支付设计与落地
携程旅行App iOS工程编译优化实践
一波N折的携程酒店Swift-Objc混编实践
携程Android 10适配踩坑指南
“携程技术”公众号
分享,交流,成长
干货 | 携程移动直播探索相关推荐
- 2020携程“BOSS直播”大数据发布:GMV累计超11亿
今日,2020携程"BOSS直播"大数据报告(以下简称<报告>)正式对外发布.<报告>结合大量最新披露的数据,从携程直播体系的整体情况.用户特征.核心(直播 ...
- 干货 | 携程酒店iOS动态View的探索
作者简介 姜睿东,2009年加入携程,从事无线研发,现在大住宿事业群负责酒店无线研发工作. 一直以来,Native App因为审核的原因,新版本不能很及时地上线.尤其是iOS,碰到点审核问题,有时候一 ...
- 干货 | 携程APP Native/RN内嵌Flutter UI混合开发实践和探索
作者简介 Deway,携程资深工程师,iOS客户端开发,热衷于大前端和动态化技术: Frank,携程高级工程师,关注移动端热门技术,安卓客户端开发. 前言 随着各种多端技术的蓬勃发展,如今的移动端和前 ...
- 携程加入直播行列:负债近千亿 疫情后用户面临退款难
来源|雷达财经 作者|李亦辉 尽管带货成绩斐然,依然未能挽救携程业绩.携程公告显示,2020财年第三财季携程营业收入为54.62亿人民币元,同比下跌47.86%. 时隔近20年,携程再度回归夫妻档. ...
- 干货 | 携程火车票基于因果推断的业务实践
作者简介 Seven,数据分析师,专注用户增长.数据科学等领域. 一.背景 携程作为旅游平台,跟用户需求息息相关,理解和识别各个策略/系统对转化/收益的因果关系尤为重要,在这个过程中需要将影响因变量的 ...
- 干货 | 携程度假无线前端架构演进之路
作者简介 Jade Gu,携程高级前端开发专家,负责度假前端框架设计和 Node.js 基础设施建设等工作. 这篇文章将简略地介绍我们当前的无线前端架构设计及其演进之路.主要内容包含以下几个部分,希望 ...
- 干货 | 携程机票Sketch插件开发实践
作者简介 尹正波,携程机票研发部前端工程师,专注设计和开发的交叉领域,用系统和工具改进设计体验和交付. Sketch 是伴随移动应用程序崛起而流行的 UI 设计工具.2014年 Sketch V3 增 ...
- 干货 | 携程微信小程序如何进行Size治理
作者简介 携程前端框架团队,为携程集团各业务线在PC.H5.小程序等各阶段提供优秀的Web解决方案.产品涉及各类前端/Node端应用框架.研发工作台.前端中台化.静态资源发布系统等.当前主要专注方向包 ...
- 干货 | 携程国际业务动态实时标签处理平台实践
作者简介 Weiyi,携程资深数据开发,关注大数据相关技术,对大数据实时计算.流批一体等方面有浓厚兴趣: Hzhou,携程资深数据开发,关注大数据相关技术,对系统架构和实时处理等方面有浓厚兴趣: Ro ...
最新文章
- nginx下部署vue项目
- java switch小程序,小程序自定义switch组件
- ABAP,Java和JavaScript的序列化,反序列化
- 我的第一次博客 张学良
- IOS应用管理学习,进阶,涉及字典转模型,工厂方法,面向对象思想,页面布局等
- 80年代出生人坦白十大尴尬事80一代全搜集
- 二叉树的创建、前序遍历、中序遍历、后序遍历
- java----单例模式
- Linux移植随笔:git的使用
- backbone, AngularJS, EmberJS 简单比较
- (DevExpress2011控件教程)ASPxGridView 范例3 :ASPxGridView 排序和分组、过滤行、统计功能等功能实现...
- pandasSeries模块
- Java基础梳理第二天03(继承、抽象类、多态)
- Elasticsearch:运用 Elasticsearch 查找类似文档:more_like_this
- 云上的日子电台php源码,云上的日子超炫酷音乐电台源码2.0更新,支持全网收费音乐外链获取...
- 【自动化测试selenium】
- uni-app 学习笔记(三)uni-app中的各种引用
- Opencv中的图像相加,相减,相除,相乘(python实现)
- 在Deepin 15.11系统中遇到微信版本过低不能登录的解决方法
- [DFS/递推/DP] 2327 [SCOI2005] 扫雷 ( 普及+/提高
热门文章
- 集成电路CAD课程实验报告:PMOS和NMOS管的版图设计与IV特性仿真
- 18.自定义键盘 toolbar的barTintColor UIBarButtonItem的使用 datePick使用
- gitlab 配置ssh 登陆 需要 输入密码
- 安装算量软件点画立管_给排水、喷淋、消火栓等专业
- 竞技游戏专用耳机:英雄联盟手游蓝牙耳机推荐
- 时序数据库如何支持秒级上亿数据的查询分组和聚合运算
- composer报错Project directory is not empty.的解决
- 能运行游戏的服务器,这才算全服第一!这款游戏里玩家能控制整个服务器,为所欲为!...
- Springboot整合JPA 多表关联操作 @Query
- Improved-DDPM