不操千曲而后晓声,观千剑而后识器。这篇文章主要讲述Android技术分享| 实现视频连麦直播相关的知识,希望能为你提供帮助。
视频连麦产品端核心步骤分析
- 游客申请连麦/取消申请
- 主播同意/拒绝申请
- 音视频发布取消
- 支持很多观众观看
- 支持多人连麦
- 低延时
- IM 弹幕
文章图片
所以经过调研,发现市场上已经有很多成熟的商业解决方案,并且成本很低就可以接入使用。
【Android技术分享| 实现视频连麦直播】对比了很久,最后采用 anyRTC 公司的两个 SDK 来完成视频连麦中的音视频通许和信令传输。
- RTC 实时视频通讯
- RTM 实时消息传输
文章图片
首先利用 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
主播进入视频页面,打开自己的视频并加入房间。
//初始化 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
使用该模式比 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 代码地址
推荐阅读
- 微信小程序模拟购物界面联动
- Unity3D静态对象优化系列二
- Cocos2d-x《赵云要格斗》--虚拟摇杆控制精灵上下左右运动
- 如何用程序员的方式,营造七夕氛围感()
- iOS开发面试只需知道这些,技术基本通关!(block篇)
- Cocos2d-x《雷电大战》-双层地图无限滚动
- 如何从JavaScript中的字符串中剥离HTML(仅提取文本内容)
- 如何仅使用JavaScript获取客户端IP地址
- 如何根据文件的文件扩展名设置ACE编辑器模式