Android技术分享| 实现视频连麦直播
视频连麦产品端核心步骤分析
- 游客申请连麦/取消申请
- 主播同意/拒绝申请
- 音视频发布取消
- 支持很多观众观看
- 支持多人连麦
- 低延时
- IM 弹幕
视频连麦技术端调研
emmm,大致可以分为视频采集、编码,传输,解码,渲染%¥#@¥%…………%……¥……%¥%……¥%%……%#¥%#%¥&%&……%……&%……¥?卒
所以经过调研,发现市场上已经有很多成熟的商业解决方案,并且成本很低就可以接入使用。
对比了很久,最后采用 anyRTC 公司的两个 SDK 来完成视频连麦中的音视频通许和信令传输。
信令交互
首先利用 RTM SDK,主播和游客端都分别加入同一个频道,这样就能实现频道内的成员心令交互。
实现申请连麦/取消申请连麦的话,只需要和主播端约定好信令格式即可,代码如下。
游客
//申请连麦
fun applyLine() {
RtmManager.instance.sendPeerMessage(hostId,
"{\"cmd\": \"apply\", \"avatar\": \"$userAvatar\", \"userName\": \"$userNickname\"}"
)
}
//取消申请连麦
fun cancelApply() {
RtmManager.instance.sendPeerMessage( hostId,"{\"cmd\": \"cancelApply\"}"
)
}
//收到信令回调通知
override fun onP2PMessageReceived(var1: RtmMessage?, var2: String?) {
val params = JSONObject(var1.text)
when (params.get("cmd")) {
"acceptLine" -> {
//主播同意
}
"rejectLine" -> {
//主播拒绝
}
}
}
主播
//拒绝游客连麦
fun rejectLine(uid: String) {
RtmManager.instance.sendPeerMessage(uid, "{\"cmd\": \"rejectLine\"}"
)
}
//同意主播连麦
fun acceptLine(uid: String) {
RtmManager.instance.sendPeerMessage(uid, "{\"cmd\": \"acceptLine\"}"
)
}
override fun onP2PMessageReceived(var1: RtmMessage?, var2: String?) {
val params = JSONObject(var1.text)
when (params.get("cmd")) {
"apply" -> {
//收到游客申请连麦
}
"cancelApply" -> {
//游客取消申请连麦
}
}
}
以上,就完成了最简单的信令交互,实际业务场景中,会有更多更复杂的,只需商定好,通过 RTM 发送交互就行。
音视频推流
游客只观看主播的时候,是不需要发布音视频的,所以在加入房间后,将自己的身份设置为游客(CLIENT_ROLE_AUDIENCE)即可。申请连麦并且主播同意后,再将身份设置为(CLIENT_ROLE_BROADCASTER)就会自动发布音视频。这样就能与直播互动了。
anyRTC 音视频 SDK 有2种直播模式,分别如下:
1.RTC
RTC(Real Time Communication)实时音视频通信,最大的特点就是延迟极低,基本都是基于 WebRTC 标准,使用私有协议进行推流的。
主播
进入视频页面,打开自己的视频并加入房间。
//初始化 SDK 引擎
RtcManager.instance.initRtc(ctx)
//打开视频模块
RtcManager.instance.enableVideo()
//打开本地摄像头设置视图显示
RtcManager.instance.setupLocalVideo(VideoCanvas(textureView))
//加入房间
RtcManager.instance.joinChannel(rtcToken, roomId, userId, isHost)
加入房间成功之后,如果有人申请连麦并上麦后,会收到 onUserJoin 回调,只需要在合适的回调中显示移除上麦人的视图即可。
//在这显示上麦的人的视频
override fun onUserJoined(uid: String?, elapsed: Int) {
// add remote user
}
//移除他人视频
override fun onUserOffline(uid: String?, reason: Int) {
//remove remote user
}
游客
主播同意上麦申请后,应将自己的身份设置为 CLIENT_ROLE_BROADCASTER
,并将自己的视频模块打开并添加到视图中。
//转换身份
RtcManager.instance.setClientRole(Constants.CLIENT_ROLE_BROADCASTER)
//添加自己的视频
val clientTexture = RtcEngine.CreateRendererView(this)
addVideoView(
binding.rlHostView,
clientTexture,
yourself = true,
setupLocalVideo = true
)
binding.apply.text = "下麦"
使用 RTC 模式实现非常的简单,只需要关注几个重要的回调即可。
2.RTMP+CDN
RTMP (Real Time Messaging Protocol)是基于 TCP 的流媒体传输协议,最大的特点是与 CDN 的强绑定,需要借助 CDN 的负载均衡系统将内容推送到接近用户的边缘节点,使用户就近取得所需内容,提高用户访问的响应速度和成功率,解决因分布、带宽、服务器性能带来的访问延迟问题。更多适用于站点加速、点播、短视频等场景。
使用该模式比 RTC 模式代码要写的多一点,因为主播短要设置上麦人的视频合流参数,观众需要添加一个 anyRTC 内置的播放器用来拉 rtmp 流。
rtmp会比RTC 延时要高一些,但是连麦不会,因为连麦后还是走的 RTC 模式,因此,连麦的人和主播之间的延时会很小。其他观众拉流的话,并不会察觉到主播和上麦者之间有什么延迟。
主播推流到 CDN
//加入频道成功
override fun joinChannelSuccess() {
//设置合流参数
publishPushLiveTranscoding()
//添加推流地址
RtcManager.instance.addPublishStreamUrl(cdnUrl, true)
}
private fun publishPushLiveTranscoding(
transcodingArr: List<LiveTranscoding.TranscodingUser>,
canvasInfo: CDNStreamLayoutInfo
) {
rtcEngine?.setLiveTranscoding(LiveTranscoding().apply {
width = canvasInfo.width
height = canvasInfo.height
}.apply { transcodingArr.forEach { addUser(it) } })
}
//游客上麦
override fun onUserJoin(uid: String) {
//更新合流布局
updatePushLiveTranscoding()
}
//游客下麦
override fun onUserOffline(uid: String) {
//更新合流布局
updatePushLiveTranscoding()
}
这里需要注意的是合流布局参数的设置,具体可以查看文末 github仓库代码。
游客拉流播放
//创建播放器并播放主播的流
RtcManager.instance.initMediaPlayer().apply {
open(cdnUrl, 0)
setView(textureView)
play()
}
游客上下麦还是和上麦的流程一致,变的只是界面上的效果。具体可以参考Demo
效果图展示
Demo 代码地址
Android技术分享| 实现视频连麦直播的更多相关文章
- fir.im Weekly - 8 个不能错过的 iOS / Android 技术分享
本期 fir.im Weekly 收集了 2 月下旬新鲜出炉的 iOS /Android 技术分享.源码等,iOS 中图片技术的解压缩.逆向实战.iOS SDK 实践,Android架构思考.Andr ...
- Android技术分享-文字转语音并朗读
Android技术分享-文字转语音并朗读 最近在做一个项目,其中有一个功能是需要将文本转换成语音并播放出来.下面我将我的做法分享一下. 非常令人开心的是,Android系统目前已经集成了TTS,提供了 ...
- Android技术分享收集
Android高工必备技能! 我的 Android 开发实战经验总结 微信Android客户端架构演进之路 微信Android版智能心跳方案 流量优化: WebP 探寻之路 HTTP 协议缓存机制详解 ...
- Android中直播视频技术探究之---视频直播服务端环境搭建(Nginx+RTMP)
一.前言 前面介绍了Android中视频直播中的一个重要类ByteBuffer,不了解的同学可以 点击查看 到这里开始,我们开始动手开发了,因为我们后续肯定是需要直播视频功能,然后把视频推流到服务端, ...
- 从无到有开发连麦直播技术<转>
转贴地址:http://blog.csdn.net/heisedelangzi/article/details/52400333 从无到有开发连麦直播技术点整理-AnyRTC 直播关键字 采集.前处理 ...
- 腾讯技术分享:微信小程序音视频技术背后的故事
1.引言 微信小程序自2017年1月9日正式对外公布以来,越来越受到关注和重视,小程序上的各种技术体验也越来越丰富.而音视频作为高速移动网络时代下增长最快的应用形式之一,在微信小程序中也当然不能错过. ...
- 腾讯技术分享:微信小程序音视频与WebRTC互通的技术思路和实践
1.概述 本文来自腾讯视频云终端技术总监rexchang(常青)技术分享,内容分别介绍了微信小程序视音视频和WebRTC的技术特征.差异等,并针对两者的技术差异分享和总结了微信小程序视音视频和WebR ...
- UWP 手绘视频创作工具技术分享系列 - Ink & Surface Dial
本篇作为技术分享系列的第四篇,详细讲一下手绘视频中 Surface Pen 和 Surface Dial 的使用场景. 先放一张微软官方商城的图,Surface 的使用中结合了 Surface Pen ...
- UWP 手绘视频创作工具技术分享系列 - 手绘视频与视频的结合
本篇作为技术分享系列的第三篇,详细讲一下手绘视频中结合视频的处理方式. 随着近几年短视频和直播行业的兴起,视频成为了人们表达情绪和交流的一种重要方式,人们对于视频的创作.编辑和分享有了更多的需求.而视 ...
随机推荐
- 感知机与支持向量机 (SVM)
感知机与SVM一样都是使用超平面对空间线性可分的向量进行分类,不同的是:感知机的目标是尽可能将所有样本分类正确,这种策略指导下得出的超平面可能有无数个,然而SVM不仅需要将样本分类正确,还需要最大化最 ...
- 可扩展的 Web 架构与分布式系统
作者:Kate Matsudaira 译者:尹星 本文介绍了分布式架构是如何解决系统扩展性问题的粗略方法,适合刚刚入门分布式系统的同学,我把整篇文章翻译如下,希望给你一些启发. 备注:[idea]标注 ...
- 重新整理 .net core 实践篇—————HttpClientFactory[三十二]
前言 简单整理一下HttpClientFactory . 正文 这个HttpFactory 主要有下面的功能: 管理内部HttpMessageHandler 的生命周期,灵活应对资源问题和DNS刷新问 ...
- Docker入门与进阶(上)
Docker入门与进阶(上) 作者 刘畅 时间 2020-10-17 目录 1 Docker核心概述与安装 1 1.1 为什么要用容器 1 1.2 docker是什么 1 1.3 docker设计目标 ...
- 46、django工程(view)
46.1.django view 视图函数说明: 1.http请求中产生两个核心对象: (1)http请求:HttpRequest对象. (2)http响应:HttpResponse对象. 2.vie ...
- 浅谈最长上升子序列(O(n*logn)算法)
今天GM讲了最长上升子序列的logn*n算法,但没讲思路... 我看了篇博客,发现-- 说的有道理!!! 首先,举例子: a[7]={1,2,4,3,6,7,5}(假设以1开头) 很明显,LIS=5: ...
- 如何快速实现一个虚拟 DOM 系统
虚拟 DOM 是目前主流前端框架的技术核心之一,本文阐述如何实现一个简单的虚拟 DOM 系统. 为什么需要虚拟 DOM? 虚拟 DOM 就是一棵由虚拟节点组成的树,这棵树展现了真实 DOM 的结构.这 ...
- ESP32使用SPIFFS文件系统笔记
基于ESP-IDF4.1 1 #include <stdio.h> 2 #include <string.h> 3 #include <sys/unistd.h> ...
- WPF之花式控件功能扩展
文章默认你已经入门WPF了 WPF日常开发,经常遇到默认的控件功能不满足需求,怎么办? No1. 自定义控件模板 平时开发中,经常遇到比较"俗"的需求,嫌弃控件默认的样子. ...
- sort,wc,uniq 排序与统计命令
sort命令 语法:sort [parameter] [file or stdin]参数: -f:忽略大小写的差异,例如A和a视为编码相同 -b:忽略最前面的空格符部分 -n:使用"纯数字& ...