梳理了下项目中使用的腾讯直播SDK相关,为再接入一套声网RTC SDK做些准备工作。
dependencies {
implementation 'com.tencent.liteav:LiteAVSDK_Professional:latest.release'
}
初始化与摄像头推流相关
public class MApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
String licenceURL = ""; // 获取到的 licence url
String licenceKey = ""; // 获取到的 licence key
V2TXLivePremier.setLicence(this, licenceURL, licenceKey);
V2TXLivePremier.setObserver(new V2TXLivePremierObserver() {
@Override
public void onLicenceLoaded(int result, String reason) {
Log.i(TAG, "onLicenceLoaded: result:" + result + ", reason:" + reason);
}
});
}
而在开发中,我们选择在启动页SplashActivity中处理配置授权逻辑,以及相关初始化操作,这个设计到启动优化的相关思维。
val licenceURL = "获取到的 licence url" //
val licenceKey = "获取到的 licence key" //
TXLiveBase.getInstance().setLicence(application, licenceURL, licenceKey)
官方推荐如下:
创建一个 V2TXLivePusher 对象,该对象负责完成推流的主要工作。
// 指定对应的直播协议为 RTMP,该协议不支持连麦
V2TXLivePusher mLivePusher = new V2TXLivePusherImpl(this, V2TXLiveDef.V2TXLiveMode.TXLiveMode_RTMP);
// 指定对应的直播协议为 RTC,该协议支持连麦。如果在直播过程中有连麦需求,需要选择该协议
V2TXLivePusher mLivePusher = new V2TXLivePusherImpl(this, V2TXLiveDef.V2TXLiveMode.TXLiveMode_RTC);
通过 TXLivePushConfig 中的setPauseImg接口可以设置垫片用的背景图片、垫片的最大时长以及视频帧率。
通过 TXLivePushConfig 中的setPauseFlag接口可以设置是暂停视频采集、还是暂停声音采集,还是两者都暂停
TXLivePushConfig mLivePushConfig = new TXLivePushConfig();
TXLivePusher mLivePusher = new TXLivePusher(this);
// bitmap: 用于指定垫片图片,最大尺寸不能超过 1920*1920
// time:垫片最长持续时间,单位是秒,300即代表最长持续300秒
// fps:垫片帧率,最小值为 5fps,最大值为 20fps。
Bitmap bitmap = decodeResource(getResources(), R.drawable.pause_publish);
mLivePushConfig.setPauseImg(bitmap);
mLivePushConfig.setPauseImg(300, 5);
//表示仅暂停视频采集,不暂停音频采集
//mLivePushConfig.setPauseFlag(PAUSE_FLAG_PAUSE_VIDEO);
//表示同时暂停视频和音频采集
mLivePushConfig.setPauseFlag(PAUSE_FLAG_PAUSE_VIDEO|PAUSE_FLAG_PAUSE_AUDIO);
mLivePusher.setConfig(mLivePushConfig);
设置完成之后,就可以调用 TXLivePusher 中的pausePusher进入隐私模式,也可以调用resumePusher退出隐私模式,
但请注意保持正确的调用顺序:startPush=> ( pausePush => resumePush ) => stopPush,错误的调用顺序会导致 SDK 表现异常,
因此使用成员变量对执行顺序进行保护是很有必要的。
// 进入隐私模式
mLivePusher.pausePusher();
...
// 退出隐私模式
mLivePusher.resumePusher();
项目中:
object BaobanAppLifecycle : AppLifecycleManager() {
lateinit var mLivePausePusher: TXLivePusher
val mLivePushConfig
get() = TXLivePushConfig().also {
// bitmap: 用于指定垫片图片,最大尺寸不能超过 1920*1920
// time:垫片最长持续时间,单位是秒,300即代表最长持续300秒
// fps:垫片帧率,最小值为 5fps,最大值为 20fps。
val bitmap = BitmapFactory.decodeResource(
DangkouApplication.app.resources,
R.mipmap.ic_live_pause_img
)
it.setPauseImg(bitmap)
it.setPauseImg(30 * 60, 5)
it.setPauseFlag(TXLiveConstants.PAUSE_FLAG_PAUSE_AUDIO or TXLiveConstants.PAUSE_FLAG_PAUSE_VIDEO)
}
}
//SplashActivity
BaobanAppLifecycle.mLivePausePusher = TXLivePusher(application).also { it.config = BaobanAppLifecycle.mLivePushConfig }
想要开启摄像头的预览画面,您需要先给 SDK 提供一个用于显示视频画面的TXCloudVideoView对象
1.在 xml 文件中添加一个视频渲染控件:
<com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/pusher_tx_cloud_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
2.通过调用 V2TXLivePusher 中的startCamera接口开启当前手机摄像头的预览画面
//启动本地摄像头预览
TXCloudVideoView mPusherView = (TXCloudVideoView) findViewById(R.id.pusher_tx_cloud_view);
mLivePusher.startCameraPreview(mPusherView);
需要注意,这里需要检查下权限。需要申请相机、存储、通话、音频权限。开启之后再调用摄像头预览。
如果已经启动了摄像头预览,就可以调用 TXLivePusher 中的startPusher接口开始推流。
int ret = mLivePusher.startPusher("rtmpurl 推流地址".trim());
if (ret == -5) {
Log.i(TAG, "startRTMPPush: license 校验失败");
}
推流结束后,可以调用 TXLivePusher 中的stopPusher接口结束推流。请注意,如果已经启动了摄像头预览,请在结束推流时将其关闭,否则会导致 SDK 的表现异常。
mLivePusher.stopPusher();
mLivePusher.stopCameraPreview(true); //如果已经启动了摄像头预览,请在结束推流时将其关闭。
项目开发中,需要留意,在onDestroy中,执行这些方法。
private fun stopLive() {
mPresenter.removeImMsgListener()
mLivePusher.stopPusher()
testSpeedThreadPool.shutdown()
video_view.onDestroy()
video_view.stop(true)
mLivePusher.stopCameraPreview(true)
livePlayer.stopPlay(true)
可以设定观众端的画面清晰度:
标清:VIDEO_QUALITY_STANDARD_DEFINITION
高清:VIDEO_QUALITY_HIGH_DEFINITION
超清:VIDEO_QUALITY_SUPER_DEFINITION
mLivePusher.setVideoQuality(
TXLiveConstants.VIDEO_QUALITY_STANDARD_DEFINITION,
true,
false
)
调用 TXLivePush 中的setBeautyFilter接口可以设置美颜效果,SDK 中提供了三种磨皮算法(style)
TXLiveConstants.BEAUTY_STYLE_SMOOTH :光滑风格,算法更加注重皮肤的光滑程度,适合秀场直播类场景下使用。
TXLiveConstants.BEAUTY_STYLE_NATURE :自然风格,算法更加注重保留皮肤细节,适合对真实性要求更高的主播。
TXLiveConstants.BEAUTY_STYLE_HAZY :朦胧风格,算法会更加侧重画面去噪,使整体画面风格偏柔和。
//style 美颜算法: 0:光滑 1:自然 2:朦胧
//beautyLevel 磨皮等级: 取值为 0-9.取值为 0 时代表关闭美颜效果.默认值: 0,即关闭美颜效果.
//whiteningLevel 美白等级: 取值为 0-9.取值为 0 时代表关闭美白效果.默认值: 0,即关闭美白效果.
//ruddyLevel 红润等级: 取值为 0-9.取值为 0 时代表关闭美白效果.默认值: 0,即关闭美白效果.
//
public boolean setBeautyFilter(int style, int beautyLevel, int whiteningLevel, int ruddyLevel);
mLivePusher.setBeautyFilter(1, meiYanLevel, meiBaiLevel, meiBaiLevel)
TXLivePusher 提供了一组 API 用户控制摄像头的行为:
切换前后摄像头: switchCamera
打开或关闭闪光灯(仅在当前是后置摄像头时有效):turnOnFlashLight
调整摄像头的焦距(可以通过 TXLivePusher 的getMaxZoom()函数获取最大焦距,setZoom的取值范围即为 1 - 最大焦距。):setZoom
TXLivePushListener 里的 onPlayEvent 可以捕获 PUSH_WARNING_NET_BUSY 事件,它代表当前主播的网络已经非常糟糕,出现此事件即代表观众端会出现卡顿。
此时就可以像上图一样在 UI 上弹出一个“弱网提示”。
@Override
public void onPushEvent(int event, Bundle param) {
if (event == TXLiveConstants.PUSH_ERR_NET_DISCONNECT
|| event == TXLiveConstants.PUSH_ERR_INVALID_ADDRESS
|| event == TXLiveConstants.PUSH_ERR_OPEN_CAMERA_FAIL
|| event == TXLiveConstants.PUSH_ERR_OPEN_MIC_FAIL) {
// 遇到以上错误,则停止推流
//...
} else if (event == TXLiveConstants.PUSH_WARNING_NET_BUSY) {
//您当前的网络环境不佳,请尽快更换网络保证正常直播
showNetBusyTips();
}
}
可以这么处理:
livePlayer.setPlayListener(object : ITXLivePlayListener {
override fun onPlayEvent(p0: Int, p1: Bundle?) {
}
override fun onNetStatus(bundle: Bundle?) {
bundle?.also {
setNetSpeed(it.getInt(NET_STATUS_NET_SPEED) / 1000f)
}
}
})
mLivePusher.setPushListener(object : ITXLivePushListener {
override fun onNetStatus(bundle: Bundle?) {
bundle?.also {
setNetSpeed(it.getInt(NET_STATUS_NET_SPEED) / 1000f)
}
}
override fun onPushEvent(code: Int, bundle: Bundle) {
}
})
视频播放器
请参见 TXLivePlayer。TXLivePlayer
主要负责将直播流的音视频画面进行解码和本地渲染,包含如下技术特点:
针对腾讯云的拉流地址,可使用低延时拉流,实现直播连麦等相关场景。
针对腾讯云的拉流地址,可使用直播时移功能,能够实现直播观看与时移观看的无缝切换。
支持自定义的音视频数据处理,让您可以根据项目需要处理直播流中的音视频数据后,进行渲染以及播放。
直播推流类
请参见 TXLivePusher。TXLivePusher
主要负责将本地的音视频画面进行编码和 RTMP 推送,包含如下技术特点:
针对腾讯云的推流地址,会采用 QUIC 协议进行加速,配合改进后的 BBR2 带宽测算方案,可以最大限度的利用主播的上行带宽,降低直播卡顿率。
内嵌套的 Qos 流量控制技术具备上行网络自适应能力,可以根据主播端网络的具体情况实时调节音视频数据量。
内嵌多套美颜磨皮算法(自然&光滑)和多款色彩空间滤镜(支持自定义滤镜),可以根据需要自行选择。
商业版包含了基于优图 AI 识别技术的大眼、瘦脸、隆鼻以及动效挂架,只需要购买优图 License 就可以零成本集成。
支持自定义的音视频采集和渲染,让您可以根据项目需要选择自己的音视频数据源。