游戏直播的应用场景是用户在使用游戏类 App 时,使用第三方直播类 App 进行游戏直播。在 Android 设备上,目前游戏直播的实现原理是通过不断截取设备屏幕内容和系统音频输出,并将其编码为视频流后再交给直播类 App 进行推拉流。Android 5.0 及之后的版本中,系统内置了一个 MediaProjection 类用于获取屏幕输出数据。请注意:如何截取屏幕,如何获取系统音频输出不在本文论述范围;
如何使用 MediaProjection 录屏亦不在本文论述范围,请开发者自行参阅 Android API 手册;
为了开发者快速接入 SDK 并实现游戏直播功能,SDK 内置了一个使用 MediaProjection 实现的外部采集工厂。
1 设置外部采集工厂
SDK 的游戏直播功能是通过外部采集能力实现的。在初始化 SDK 前,必须调用如下 API 设置外部采集工厂。/**
* 开启外部采集.
*
* @param factory 外部采集工厂实例
* @return true:调用成功;false:调用失败
*/
public static boolean setVideoCaptureFactory(ZegoVideoCaptureFactory factory);
或者/**
* 开启外部采集.
*
* @param factory 外部采集工厂实例
* @param channelIndex 推流通道index, 参考 {@link ZegoConstants.PublishChannelIndex}
* @return true:调用成功;false:调用失败
*/
public static boolean setVideoCaptureFactory(ZegoVideoCaptureFactory factory, int channelIndex);
示例代码如下:mScreenCaptureFactory = new ZegoScreenCaptureFactory();
ZegoLiveRoom.setVideoCaptureFactory(mScreenCaptureFactory);
如何创建外部采集工厂与外部采集设备请参考:高级功能指南-外部采集
2 初始化 SDK
设置外部采集工厂后,需要初始化 SDK 后才能开始推流,具体初始化 SDK 流程请参考:初级功能指南-初始化请注意:
如果是由其它直播类型切换到游戏直播,需要先停止推流,再反初始化 SDK。然后再按照正常开启外部采集步骤:先设置外部采集工厂,再重新初始化 SDK。
3 申请录屏权限
由于 SDK 中提供的默认录屏工厂 ZegoScreenCaptureFactory 是基于 MediaProjection 实现的,所以在推流前,需要使用如下方式申请录屏权限:GameLiveActivity.java
void requestMediaProjection(){
// 请求录屏权限, 等待用户授权
mMediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
startActivityForResult(mMediaProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == REQUEST_CODE && resultCode == RESULT_OK){
Log.i(TAG, "获取MediaProjection成功");
mMediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, data);
...
} else {
Log.i(TAG, "获取MediaProjection失败");
Toast.makeText(GameLiveActivity.this, "获取MediaProjection失败", Toast.LENGTH_SHORT).show();
}
}请注意:
当外部有调用 mMediaProjection 的 stop() 方法或者录屏异常退出后,如想再次开启录屏功能,需要使用上述代码重新申请录屏权限并获取 mMediaProjection,再将这个新的 mMediaProjection 使用 API setMediaProjection 设置到 mScreenCaptureFactory 中。
4 开始推流
在推流前需要先登录房间,仅在登录房间成功后,才能开始推流。登录房间的具体流程可参考:初级功能指南-推流 中 2.3 登录房间 一节。
LiveDemo5 中示例代码:GameLiveActivity.java
// 开启录屏功能,开始推流
private void startCapture(){
ZegoAvConfig zegoAvConfig = ZegoApiManager.getInstance().getZegoAvConfig();
// 开始录屏
if (mScreenCaptureFactory != null) {
mScreenCaptureFactory.setMediaProjection(mMediaProjection);
mScreenCaptureFactory.setCaptureResolution(zegoAvConfig.getVideoEncodeResolutionWidth(),
zegoAvConfig.getVideoEncodeResolutionHeight());
mZegoLiveRoom.setAudioDeviceMode(ZegoConstants.AudioDeviceMode.General);
}
// 开启流量自动控制
int properties = ZegoConstants.ZegoTrafficControlProperty.ZEGOAPI_TRAFFIC_FPS
| ZegoConstants.ZegoTrafficControlProperty.ZEGOAPI_TRAFFIC_RESOLUTION;
mZegoLiveRoom.enableTrafficControl(properties, true);
// 开始推流
mPublishTitle = "Android录屏_" + PreferenceUtil.getInstance().getUserID();
mPublishStreamID = ZegoRoomUtil.getPublishStreamID();
mZegoLiveRoom.startPublishing(mPublishStreamID, mPublishTitle, 0);
}
5 停止推流
游戏直播结束,需要停止录屏,并结束推流。LiveDemo5 中示例代码如下:GameLiveActivity.java
// 停止录屏,结束推流
private void stopCapture(){
Toast.makeText(GameLiveActivity.this, "停止推流", Toast.LENGTH_SHORT).show();
// 停止录屏
if (mScreenCaptureFactory != null) {
mScreenCaptureFactory.setMediaProjection(null);
mScreenCaptureFactory.setCaptureResolution(ZegoScreenCaptureFactory.DEFAULT_VIDEO_WIDTH,
ZegoScreenCaptureFactory.DEFAULT_VIDEO_HEIGHT);
mZegoLiveRoom.setAudioDeviceMode(ZegoConstants.AudioDeviceMode.Communication);
}
// 停止推流
mZegoLiveRoom.stopPublishing();
}