您尚未登录

登录

您尚未登录

登录

推荐您使用PC浏览器访问

确定
  • 开发者中心
  • >
  • 云游戏
  • >
  • SDK开发指南
  • >
  • 云游戏基础SDK
  • >
  • Android
  • >
  • v5.1.112

文档版本:20231023-122

变更说明:

SDK版本 发版日期 更新内容
5.1.109 2023/10/23 1、新增切换移动网络接口
2、新增切换移动网络回调接口
3、新增获取当前播流类型接口
5.1.106 2023/9/20 1、新增双通道网络接口
2、新增双通道网络回调接口
5.1.105 2023/8/29 1、修改SDK状态回调,新增STATUS_RECEIVE_KQI_DATA状态通知
5.1.102 2023/7/24 1、新增申请实例录屏接口
2、新增获取流地址IP回调接口
5.1.100 2023/7/7 1、新增重启实例内游戏接口
5.1.99 2023/6/23 1、新增游戏保活接口
5.1.98 2023/6/8 1、新增设置游戏画面黑白模式接口
5.1.97 2023/5/23 1、修改SDK状态回调,新增STATUS_RECEIVE_DISTANCE状态通知
5.1.93 2023/3/23 1、修改基础配置中的权限及混淆配置
5.1.90 2023/2/8 1、新增获取键盘类型接口
5.1.87 2022/12/8 1、修改云游戏中远端实例状态通知接口,新增云游戏中磁盘空间状态通知
5.1.86 2022/11/23 1、修改获取清晰度列表接口,新增getResolutionList方法及使用场景说明
2、修改获取云游戏延迟信息接口,新增getVideoInputFps(),getVideoSendFps(),getVideoSendBitrate(),getReceivedBitrate(),getFrameRateOutput(),getAudioBitrate(),getCodecName()方法
3、增加发送云端截图指令接口
4、修改云游戏中远端实例状态通知接口,新增截图游戏生成通知字段
5.1.84 2022/10/23 1、修改申请服务,新增SHOW_INPUT_OFFSET字段
2、修改申请服务,新增RESOLUTION_ID字段
3、修改申请服务,新增CLEAN_CACHE_CID字段
5.1.81 2022/9/16 1、修改SDK状态回调,新增STATUS_DOWNLOAD_ONLY字段
2、修改云游戏中远端实例状态通知接口,新增文件创建通知、文件生成通知
3、新增查询文件下载任务状态接口
4、新增查询可下载文件列表接口
5、新增文件下载接口
6、新增获取文件下载任务列表接口
7、新增取消文件下载接口
8、新增查询取消下载文件列表
9、新增更新文件下载列表接口
5.1.80 2022/9/5 1、修改申请服务,新增TRANSMISSION_DATA_TO_SAAS字段
5.1.79 2022/8/19 1、修改上传、下载图片接口,新增设置文件云端路径字段
2、修改申请服务,新增CUTOUT_HEIGHT_PERCENT字段
3、新增获取刘海屏高度占比接口
4、新增发送关闭Loading框消息通知接口
5.1.76 2022/7/22 1、修改申请服务,新增参数IME_TYPE字段
5.1.74 2022/6/20 1、修改云游戏中远端实例状态通知接口,完善分享事件JSON字段介绍
5.1.73 2022/6/8 1、修改SDK状态回调,新增打开传感器失败的回调状态STATUS_SENSOR_GET_FAILURE 说明
5.1.67 2022/5/7 1、新增输入法切换接口
2、修改发送消息接口给ws服务器发送消息接口获取远端实例图片列表接口 这三个函数为有返回boolean值函数,表示当前长链接是否连接成功
5.1.61 2022/3/23 1、修改IDC节点测速接口获取清晰度列表接口获取游戏存档状态接口查询是否存在游戏存档接口检测未释放游戏接口根据cid释放实例接口 增加带游戏BID参数方法
5.1.59 2022/3/11 1、修改SDK状态回调,STATUS_WAIT_CHOOSE和STATUS_OPERATION_INTERVAL_TIME状态返回数据修改
5.1.56 2022/2/23 1、新增发送返回键事件给实例接口
5.1.52 2021/1/7 1、新增隐藏SDK本地键盘接口
5.1.51 2022/1/4 1、修改云游戏中远端实例状态通知接口,新增两种状态通知:android_share和weixin_share
5.1.48 2021/12/15 1、修改申请服务,新增参数openCameraPermissionCheck字段
2、修改获取控制权接口,Control新增参数cameraOpenPermissionCheck字段
5.1.47 2021/12/10 1、修改初始化SDK增加init函数,回调的错误信息为Json
2、修改SDK状态回调回调的报错信息中新加字段
5.1.42 2021/11/9 1、新增通知SDK权限结果接口
5.1.33 2021/8/2 1、修改获取控制权接口
5.1.29 2021/7/14 1、新增给ws服务器发送消息接口
2、新增Intent拦截接口功能
3、新增发送GPS数据接口功能
5.1.25 2021/6/30 1、上传、下载图片接口中新增下载图片方法
2、取消上传、下载实例的图片接口中新增取消下载方法
3、修改云游戏中分享、云游戏中打开摄像头、云游戏中打开系统相册合并至云游戏中远端实例状态通知接口,修改方法及参数
4、新增获取远端实例图片列表接口
5.1.20 2021/5/25 1、修改SDK状态回调,新增状态回调stateChangeReason

[TOC]

1 产品简介

海马云游戏Android SDK是一款助力快速部署云游戏产品的软件开发工具包。 您可以通过调用海马云游戏Android SDK接口,实现云游戏的播放、停止、状态回调等各类控制操作和数据交互,在海马云游戏端到端全栈云服务能力基础上,为用户带来顺畅的云游戏体验。以下简称SDK。

2 工程配置

为方便 Android 开发者调试和接入海马云游戏多产品 API,这里向您介绍适用于Android开发的工程配置。

2.1 集成SDK

在Module的build.gradle文件中,添加依赖属性:

repositories {
    flatDir {
        dirs 'libs'
    }
}
dependencies {
    implementation 'com.alibaba:fastjson:1.2.0'
    implementation 'com.android.support:support-v4:26.1.0'
    implementation (name: 'saas-sdk-latest.release', ext: 'aar')
    implementation('io.socket:socket.io-client:1.0.0') {
        exclude group: 'org.json', module: 'json'
    }
}

注意

  • SDK目前只支持通过gradle集成方式。

  • saas-sdk-latest.release是海马的SDK,其他为海马SDK的依赖包,saas-sdk-latest.release根据实际提供的aar文件进行修改(.aar文件的部分)。

  • 如果无法正常集成,请在Project的build.gradle文件中配置repositories,添加 jcenter:

    allprojects {
        repositories {
            jcenter()
        }
    }

2.2 基础配置

在AndroidManifest.xml中添加权限:

<!-- 网络权限,必需权限 -->
<uses-permission android:name="android.permission.INTERNET" />

<!-- 获取WiFi状态,获取当前WiFi接入的状态以及WLAN热点的信息,必需权限 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

<!-- 获取网络状态,如当前的网络连接是否有效,必需权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<!-- 游戏过程中防止锁屏、保持屏幕常亮,必需权限 -->
<uses-permission android:name="android.permission.WAKE_LOCK" />

<!-- 使用SDK提供的⽂件下载功能,该权限必需;在Android 6.0及以上需要动态申请权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<!-- 使用SDK提供的⽂件上传功能,该权限必需;在Android 6.0及以上需要动态申请权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<!-- 使用SDK提供的摄像头相关功能,如进行人脸识别,该权限必需;在Android 6.0及以上需要动态申请权限 -->
<uses-permission android:name="android.permission.CAMERA" />

<!-- 使用SDK提供的麦克风相关功能,如录音,该权限必需;在Android 6.0及以上需要动态申请权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />

为避免混淆海马SDK,在Proguard混淆文件中增加以下配置:

-dontwarn org.codehaus.**
-keep class org.codehaus.** {*;}
-keep interface com.haima.hmcp.listeners.*{*;}
-keep class com.haima.hmcp.beans.*{*;}
-keep enum com.haima.hmcp.enums.*{*;}
-keep class com.haima.hmcp.**{*;}
-keep enum com.haima.hmcp.websocket.WebSocketCloseNotification{*;}
-keep interface com.haima.hmcp.websocket.WebSocket{*;}
-keep interface com.haima.hmcp.websocket.WebSocketConnectionObserver{*;}
-keep class com.haima.hmcp.websocket.WebSocketConnection{public <methods>;}
-keep class com.haima.hmcp.websocket.WebSocketOptions{public <methods>;}
-keep class com.haima.hmcp.websocket.WebSocketException{*;}
-keep interface com.hmcp.saas.sdk.listeners.*{*;}
-keep class com.hmcp.saas.sdk.beans.*{*;}
-keep class com.hmcp.saas.sdk.enums.*{*;}
-keep class com.hmcp.saas.sdk.SaasSDK{public <methods>;}
-keep class de.tavendo.autobahn.**{*;}
-keep class tv.haima.ijk.media.player.** { *; }
-keep interface tv.haima.ijk.media.player.listeners.*{*;}
-keep interface tv.haima.ijk.media.player.IMediaPlayer{*;}
-keep class com.netcheck.LDNetDiagnoService.LDNetDiagnoService{public <methods>;}
-keep interface com.netcheck.LDNetDiagnoService.LDNetDiagnoListener{public <methods>;}
-keep class com.netcheck.LDNetDiagnoService.LDNetTraceRoute { *; }
-dontwarn org.openudid.**
-keep class org.openudid.**{*;}
-keep class org.hmwebrtc.**{*;} 
-keep class org.webrtc.haima.**{*;} 
-keep class io.socket.**{*;} 
-keep class com.haima.hmcp.rtc.widgets.RtcTextureViewRenderer{*;}  

2.3 配置硬件加速

打开硬件加速可以提高渲染能力,提高用户体验。

<application ……
android:hardwareAccelerated="true">

2.4 添加组件

在布局文件中添加HmcpVideoView组件:

<com.haima.hmcp.widgets.HmcpVideoView
    android:id="@+id/gameView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"/>

HmcpVideoView组件所在Acitvity需要设置以下属性:

<activity
    android:name=".xxxActivity"
    android:configChanges="orientation|screenSize"
    android:launchMode="singleTask"
    android:screenOrientation="landscape" />

3 快速开始

这里向您介绍适用于Android开发的快速接入部分。

表3-1 重要接口说明

重要接口 接口含义 建议调用时机
init() 初始化SDK Application的onCreate()
setUserInfo() 设置用户登录信息 init()成功回调后
play(bundle) 与海马云Server建立通讯、申请服务,成功后则可以开启游戏 init()成功回调后

⭕️说明

  • SDK使用前请对工程进行配置,否则SDK不生效。

  • SDK的接口调用要在同一个线程下。

  • SDK回调信息请参见SDK状态回调

3.1 初始化SDK

按照工程配置,已在AndroidManifest.xml文件中配置渠道信息HMCP_ACCESS_KEY_ID和HMCP_CHANNEL_ID,接入方需调用init方法初始化SDK,否则需通过Bundle对ACCESS_KEY_ID与CHANNEL_ID进行赋值。

初始化方法建议在自定义Application类中进行,如果成功回调success()方法,则初始化成功。

请求接口报错时返回的错误信息默认是普通字符串格式,若需要返回json格式,需要isJson参数传入true。

注意

isJson影响的接口除了init之外还有:更新uid和游戏时长接口获取游戏存档状态接口查询是否存在游戏存档接口检测未释放游戏接口根据cid释放实例接口开始直播接口停止直播接口获取授权码接口

函数原型:

public class HmcpManager {
        public void init(Context context, OnInitCallBackListener callBack)
        public void init(Bundle bundle, Context context, OnInitCallBackListener callBack)
        public void init(Bundle bundle, Context context, OnInitCallBackListener callBack,boolean isJson)
}

表3-2 bundle参数说明

参数 类型 必填项 说明
bundle Bundle 使用携带bundle的参数初始化SDK ,渠道信息将使用bundle中携带信息
context Context 应用程序上下文对象
callBack OnInitCallBackListener 初始化方法接口回调监听器

表3-3 key说明

key value 类型 必填项 说明
HmcpManager.ACCESS_KEY_ID String 接入方的唯一ID,用来区分不同的接入方,该值由海马云分配
HmcpManager.CHANNEL_ID String 渠道号,由接入方配置。如果应用本身不区分渠道,可以设置为一个随机的字符串;参数由接入方自己定义,请注意不要跟appChannel混淆

示例代码:

Bundle bundle = new Bundle();
// 设置ACCESS_KEY_ID
bundle.putString(HmcpManager.ACCESS_KEY_ID, mBid); 
// 设置CHANNEL_ID
bundle.putString(HmcpManager.CHANNEL_ID, mChannelID);        

manager.init(bundle, this, new OnInitCallBackListener() {
    @Override
    public void success() {
        // 初始化SDK成功,可以云游戏
    }
    @Override
    public void fail(String s) {
        // 初始化SDK失败,不能云游戏
        // {"errorCode":"","errorCodeWithoutCid":"","errorMessage":""}
    }
},true);

3.2 Activity中初始化组件

以下是 Activity 中的示例代码:

public class HmcpPlayerActivity extends AppCompatActivity implements HmcpPlayerListener {
    private HmcpVideoView hmcpVideoView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // 获取 HmcpVideoView 组件
        hmcpVideoView = (HmcpVideoView) this.findViewById(R.id.gameView);
    }
    // Activity需要implements HmcpPlayerListener接口
    @Override
    public void onError(ErrorType errorType, String s) {
        // 出错信息回调
    }
    @Override
    public void onSuccess() {
        // SDK启动成功并且开始播流的回调
    }
    @Override
    public void onMessage(Message message) {
        // 收到退出登录消息回调
    }
    @Override
    public void onPlayStatus(int status, long value, String data) {
        // 帧率fps,带宽Bps上报。
    }
    @Override
    public void onExitQueue() {
        // 游戏内部弹窗退出消失回调
        this.finish();
    }
    @Override
    protected void onStart() {
        hmcpVideoView.onStart();
        super.onStart();
    }
    @Override
    protected void onRestart() {
        hmcpVideoView.onRestart(int time);
        super.onRestart();
    }
    @Override
    protected void onResume() {
        hmcpVideoView.onResume();
        super.onResume();
    }
    @Override
    protected void onPause() {
       hmcpVideoView.onPause();
        super.onPause();
    }
    @Override
    protected void onStop() {
       hmcpVideoView.onStop();
        super.onStop();
    }
    @Override
    protected void onDestroy() {
        if (hmcpVideoView != null) {
            hmcpVideoView.onDestroy();
        }
        super.onDestroy();
    }
    @Override
    public void onPlayerError(String errorCode, String errorMsg) {
        // SDK上报错误信息回调接口
    }
    @Override
    public void HmcpPlayerStatusCallback(String callback) {
        // SDK使用状态回调接口
    }
    @Override
    public void onSceneChanged(String sceneMessage) {
        // SDK游戏过程中各状态发生变化时通知应用消息接口
    }
    @Override
    public void onNetworkChanged(NetWorkState netWorkState) {
        // 网络变化后通知应用的接口
    }
    @Override
    public void onPermissionNotGranted(String permission) {
        // SDK没有敏感权限时回调(比如游戏途中需要语音连麦)
        // 在申请到连麦权限时需要调用hmcpVideoView.startRecord重新拉起录音
    }
    @Override
    public void onCloudDeviceStatus(String status) {
        // 云游戏中分享、打开摄像头、打开系统相册、游戏内截图
    }

    @Override
    public void onInterceptIntent(String intentData) {
        // intent拦截回调
    }
}

其中:

  • Activity的onResume()、onPause()、onDestroy()必须重写,并在重写的方法中调用HmcpVideoView的相应方法,可以参考上面的示例代码。

  • Activity需要实现(implement)HmcpPlayerListener接口。

  • onPlayerError(String errorCode,String errorMsg)是SDK上报播流错误信息回调接口,errorMsg是错误信息,errorCode是错误码。

  • HmcpPlayerStatusCallback(String callback)是SDK运行状态回调接口,参数callback为回调信息。详情请参见SDK状态回调

  • onSceneChanged(String sceneMessage)是SDK游戏过程中各状态发生变化时通知应用的接口,参数sceneMessage是包括sceneId和extraInfo{}两个字段的Json串。详情请参见场景切换回调

  • onNetworkChanged(NetWorkState state)是SDK在监听到网络变化后通知应用的接口,参数NetWorkState为枚举类型,现在包括ISWIFI、NOTWIFI、NO_NETWORK三种网络状态。

  • onInputDevice(int device, int operationType)是SDK在监听到输入设备变化时通知应用的接口。

    表3-4 device类型

    类型 类型描述
    INPUT_DEVICE_NONE 未检测到输入设备
    INPUT_DEVICE_REMOTE_CONTROL 遥控器输入
    INPUT_DEVICE_KEY_MOUSE 键盘鼠标输入
    INPUT_DEVICE_GAMEPAD 实体手柄输入
    INPUT_DEVICE_VIRTUAL_GAMEPAD 虚拟手柄输入

    表3-5 operationType类型

    类型 类型描述
    INPUT_DEVICE_OPERATION_TYPE_VIRTUAL_BUTTON 虚拟按键
    INPUT_DEVICE_OPERATION_TYPE_BUTTON 实体按键
    INPUT_DEVICE_OPERATION_TYPE_VIRTUAL_TOUCH 虚拟触摸

    onPermissionNotGranted(String permission)是SDK在没有相关敏感权限时的回调接口,需要APP申请对应权限。

  • onCloudDeviceStatus(String status)是云游戏中远端实例状态发生改变的回调接口,包括云游戏中分享、打开摄像头、打开系统相册、游戏内截图,详情请参见云游戏中远端实例状态通知接口

  • onInterceptIntent(String intentData)是云游戏内实现免登等需求时进行Intent拦截的回调接口。详情请参见Intent拦截接口

3.3 设置用户登录信息

用户登录信息包括userId和userToken。

  • userId作为游戏客户端用户的唯一识别码,原则上为APP端的用户登录账号,在开始游戏前需设置用户登录信息,或随机生成长度在64以内的字符串,每台客户端上的账号需保证唯一性。
  • userToken用来校验userId的有效性,如果userId为随机生成,userToken也可以随机生成。
  • HmcpVideoView的setUserInfo()方法用来设置用户的登录信息。

函数原型:

public class HmcpVideoView {
        public void setUserInfo(UserInfo userInfo)
}

表3-6 用户登录信息参数说明

参数 类型 必填项 说明
userInfo UserInfo 用户登录信息(包含userID、usertoken等信息)

示例代码:

mUserInfo = new UserInfo();
mUserInfo.userId = USER_ID;
mUserInfo.userToken = USER_TOKEN;
mUserInfo.userType = 0;
hmcpVideoView.setUserInfo(mUserInfo);

注意

如果两台客户端上的userId相同,将会导致游戏异常现象。userType代表用户类型,可以不传,默认其值为0。0代表示表普通用户,5表示超级账号,超级账号需要海马云后台配合生效。

3.4 申请服务

调用HmcpVideoView的play(bundle)函数,SDK会与海马云的server通讯,申请服务成功后即可开始游戏。

函数原型:

public class HmcpVideoView {
        public void play(Bundle bundle)
}

表3-7 申请服务参数说明

参数 类型 必填项 说明
bundle Bundle 需调用对应put***()方法,将下表所有参数赋值并打包到bundle中

表3-8 bundle key说明

key value类型 必填项 说明
HmcpVideoView.ORIENTATION ScreenOrientation 标识游戏是竖屏还是横屏显示。
竖屏: ScreenOrientation.PORTRAIT
横屏: ScreenOrientation.LANDSCAPE
HmcpVideoView.PLAY_TIME long 用户可以玩游戏的时长,单位为ms
HmcpVideoView.PRIORITY int 用户申请游戏服务的优先级,默认为0。数值越大优先级越高
HmcpVideoView.APP_NAME String 游戏包名,传入对应的要启动的游戏包名
HmcpVideoView.APP_CHANNEL String 如果存在多款游戏同包名的情况,可以通过appChannel区分。此参数由海马云配置。需要注意不要与channelId(接入方自己定义,与海马云无关)混淆
HmcpVideoView.C_TOKEN String 用来校验参数的有效性,cToken的计算方法请参考cToken说明文档
HmcpVideoView.EXTRA_ID String 预留参数,默认为空字符串
HmcpVideoView.PAY_STR String 支付相关参数,默认为空字符串
HmcpVideoView.ARCHIVED boolean 游戏是否存档
HmcpVideoView.PAY_PROTO_DATA String APP业务系统关心的参数,需要base64编码
HmcpVideoView.FPS_PERIOD int 采集fps周期及上报周期,单位为s
HmcpVideoView.BAND_WIDTH_PERIOD int 采集带宽的周期及上报周期,单位为s
HmcpVideoView.BAND_WIDTH_PEAK int 采集带宽周期内的最大的几个值
HmcpVideoView.DECODE_TIME_PERIOD int 采集解码时间的周期及上报周期,单位为秒s
HmcpVideoView.INTERNET_SPEED int 设置该参数可以固定的码率开始游戏,单位为KB/s
HmcpVideoView.RESOLUTION_ID int 设置该参数可以指定清晰度档位序号播流
HmcpVideoView.IS_SHOW_TIME boolean 是否显示剩余游戏时间
HmcpVideoView.CLIENT_ISP String 运营商名称
HmcpVideoView.CLIENT_PROVINCE String 当前定位省份
HmcpVideoView.CLIENT_CITY String 当前定位城市
HmcpVideoView.C_ID String 第一次游玩不需要传cid,若要重连未释放游戏,则需要查询未释放游戏信息(检测未释放游戏接口中的channelInfoList)中对应cid、包名、渠道,使用该参数申请重连
HmcpVideoView.NO_INPUT_LIMIT_TIME int 无操作超时时长,单位为s
HmcpVideoView.CID_CACHE_INTERVAL long cid超时重连缓存时长,单位为s,不传默认为2h,传0为永不超时
HmcpVideoView.ALLOW_COMPATIBLE_IPV6 boolean 是否支持IPV6功能,同时需海马云在后台配置
HmcpVideoView.VERTICAL_BACKGROUND int 播放器背景图,主要针对竖屏游戏黑色边框的优化
HmcpVideoView.VIEW_RESOLUTION_WIDTH int 自定义游戏推流清晰度宽度,宽度、高度可调换位置,不影响显示效果
HmcpVideoView.VIEW_RESOLUTION_HEIGHT int 自定义游戏推流清晰度高度,宽度、高度可调换位置,不影响显示效果
HmcpVideoView.STREAM_TYPE int 选择流类型。
0:表示RTMP
1:表示WEBRTC
不填写此参数时,默认为RTMP流类型
HmcpVideoView.DECODE_TYPE int rtmp解码类型。
0:表示软解码
1:表示硬解码
不填写此参数时,默认为硬解码
HmcpVideoView.ARCHIVE_FROM_USER_ID String 被读取的存档用户的userId
HmcpVideoView.ARCHIVE_FROM_BID String 被读取的存档用户的bid
HmcpVideoView.OPEN_CAMERA_PERMISSION_CHECK boolean 每次开启摄像头时,向APP申请权限的开关。
true:表示开启
false:表示关闭
不传默认为关闭。
权限申请回调请参见关键接口回调中onPermissionNotGranted接口,权限结果通知请参见通知SDK权限结果接口
HmcpVideoView.IME_TYPE int 输入法类型
0:表示云端键盘
1:表示本地键盘
HmcpVideoView.CUTOUT_HEIGHT_PERCENT float[] 设备的刘海缺口所占屏幕高度占比参见获取刘海屏高度占比接口
HmcpVideoView.TRANSMISSION_DATA_TO_SAAS SerializableMap<String, T extends Serializable> 向服务端透传数据
Map数据结构,value需要实现Serializable,具体的key和value请和服务端对接
HmcpVideoView.CLEAN_CACHE_CID int 清除缓存cid
1:清除缓存cid
0:不清除缓存cid
HmcpVideoView.SHOW_INPUT_OFFSET int 本地输入法控制云端输入框高度的偏移量
单位:像素

示例代码:

boolean isPortraitOrientation = false;             
// 是否竖屏
ScreenOrientation orientation = isPortraitOrientation ? ScreenOrientation.PORTRAIT : ScreenOrientation.LANDSCAPE;

int playTime = 6000 * 1000;
int priority = 100;

String packageNameGame = "com.yodo1tier1.skizgfTV.cmcc";
String appChannel = "";
String cToken = CryptoUtils.generateCToken(packageNameGame, userId, userToken, accessKeyID, channelID, accessKey);
String extraId = "";
String payStr = "";
boolean archive = true;
String protoData = "protoData"; 
int fpsPeriod = 1;
int bandWidthPeriod = 5; 
int bandWidthPeak = 3; 
int decodeTimePeriod = 1;
int speed = 1024;
boolean isShowTime = true; 
String clientISP = "联通";
String clientProvince = "河北";
String clientCity = "廊坊";
// 根据查询未释放游戏对应信息赋值
String cid = "";
// 无操作超时时间单位为秒
int noInputLimitTime = 60;
// 是否支持IPV6功能
boolean isEnableIpv6 = false; 
// 推流画面宽度
int viewResolutionWidth = 1080;    
// 推流画面高度
int viewResolutionHeight = 1920; 
// cid缓存时长
long cidCacheInterval = 3600L;  
// WEBRTC
int rtcStream = 1;  
// 解码类型
int decodeType = HmcpVideoView.DECODE_HARDWARE;    
// 传入参数
Bundle bundle = new Bundle();
bundle.putSerializable(HmcpVideoView.ORIENTATION, orientation);
bundle.putLong(HmcpVideoView.PLAY_TIME, playTime.toLong());
bundle.putInt(HmcpVideoView.PRIORITY, priority);
bundle.putString(HmcpVideoView.APP_NAME, packageName);
bundle.putString(HmcpVideoView.APP_CHANNEL, appChannel);
bundle.putString(HmcpVideoView.C_TOKEN, cToken);
bundle.putString(HmcpVideoView.EXTRA_ID, extraId);
bundle.putString(HmcpVideoView.PAY_STR, payStr);
bundle.putBoolean(HmcpVideoView.ARCHIVED, archieve);
bundle.putString(HmcpVideoView.PAY_PROTO_DATA, protoData);
bundle.putInt(HmcpVideoView.FPS_PERIOD, fpsPeriod);
bundle.putInt(HmcpVideoView.BAND_WIDTH_PERIOD, bandWidthPeriod);
bundle.putInt(HmcpVideoView.BAND_WIDTH_PEAK, bandWidthPeak);
bundle.putInt(HmcpVideoView.DECODE_TIME_PERIOD, decodeTimePeriod);
bundle.putInt(HmcpVideoView.INTERNET_SPEED, speed);
bundle.putBoolean(HmcpVideoView.IS_SHOW_TIME,isShowTime);
bundle.putBoolean(HmcpVideoView.CLIENT_ISP, clientISP);
bundle.putBoolean(HmcpVideoView.CLIENT_PROVINCE, clientProvince);
bundle.putBoolean(HmcpVideoView. CLIENT_CITY, clientCity);
bundle.putBoolean(HmcpVideoView.C_ID,cid); 
bundle.putInt(HmcpVideoView.NO_INPUT_LIMIT_TIME, noInputLimitTime);
bundle.putInt(HmcpVideoView.ALLOW_COMPATIBLE_IPV6, isEnableIpv6);
bundle.putInt(HmcpVideoView.VIEW_RESOLUTION_WIDTH, viewResolutionWidth);
bundle.putInt(HmcpVideoView.VIEW_RESOLUTION_HEIGHT, viewResolutionHeight);
bundle.putLong(HmcpVideoView.CID_CACHE_INTERVAL, cidCacheInterval);
bundle.putInt(HmcpVideoView.STREAM_TYPE, rtcStream);
bundle.putInt(HmcpVideoView.DECODE_TYPE, decodeType);

hmcpVideoView.play(bundle);

3.5 开始游戏

服务请求完成后,通过HmcpVideoView的play()接口开始游戏。启动游戏时调用play()接口。

函数原型:

public class HmcpVideoView {
    public void play();
}

示例代码:

@Override
public void HmcpPlayerStatusCallback(String callback) {
    try {
        JSONObject jsonObject = new JSONObject(callback);
        int statusCode = jsonObject.getInt(StatusCallbackUtil.STATUS);
        switch (statusCode) {
            case Constants.STATUS_PLAY_INTERNAL:
                hmcpVideoView.play();
                break;
            default:
                break;
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

4 API 接口

4.1 初始化失败返回内容接口

初始化失败返回 JSON 字符串:

{
    "message":"", 
    "volleyMessage": "",
    "startTime": "",
    "errorTime": "",
}

表4-1 初始化失败返回内容字段说明

字段 说明
message 错误描述
volleyMessage 网络请求失败时,错误信息
startTime 网络超时会携带该字段,表示请求开始时间
errorTime 网络超时会携带该字段,表示错误下发时间

4.2 设置配置信息接口

配置信息为免登录功能所需信息,SDK在获取云游戏服务时需要传送“配置信息”给服务器。如不使用配置信息,可传非空字符串。

函数原型:

public class HmcpVideoView {
        public void setConfigInfo (String config)
}

4.3 暂停游戏接口

游戏启动后,通过HmcpVideoView的pauseGame() 接口暂停游戏。

函数原型:

public class HmcpVideoView {
        public void pauseGame();
}

示例代码:

hmcpVideoView.pauseGame();

4.4 继续游戏接口

暂停游戏后,通过HmcpVideoView的restartGame()接口继续游戏。

函数原型:

public class HmcpVideoView {
    public void restartGame(int time);
}

表4-2 继续游戏参数说明

参数 类型 必填项 说明
time int 用户可以玩游戏的时长,单位为ms

示例代码:

// 游玩10分钟
hmcpVideoView.restartGame(1000 * 60 * 10 );    

4.5 断网重新连接游戏接口

通过HmcpVideoView的reconnection()接口进行重新连接游戏,应用场景为:

  • 游戏启动后,断网重新连接游戏。
  • 游戏启动后,WIFI切换到4G。

函数原型:

public class HmcpVideoView {
        public void reconnection();
}

示例代码:

hmcpVideoView.reconnection();

4.6 重新申请游戏接口

服务请求完成后,通过HmcpVideoView的startPlay()接口重新申请游戏。应用场景为:

  • 长时间无操作后,重新申请游戏。
  • 其他情况下需重新申请游戏场景。

函数原型:

public class HmcpVideoView {
        public void startPlay();
}

示例代码:

hmcpVideoView.startPlay(); 

4.7 插队申请游戏接口

服务请求完成后,通过HmcpVideoView的startPlay(boolean isAhead)接口重新以插队方式申请游戏。可在排队失败等报错场景下,以等待申请实例队列的第一位进行插队,等待有空闲实例进行分配游玩。

函数原型:

public class HmcpVideoView {
        public void startPlay(boolean isAhead);
}

表4-3 插队申请游戏参数说明

参数 类型 必填项 说明
isAhead boolean 是否插队进行申请游戏

示例代码:

// 注意:调用 play(bundle) 成功后,才可调用该方法
hmcpVideoView.startPlay(true);    

4.8 退出游戏接口

结束播放,退出游戏。退出需要在Activity方法重载onPause()、onDestroy()接口。

函数原型:

public class HmcpVideoView {
        public void onPause();
        public void onDestroy();
}

示例代码:

@Override
protected void onPause() {
  super.onPause();
  hmcpVideoView.onPause();
}
@Override
protected void onDestroy() {
  if (hmcpVideoView!= null) {
    hmcpVideoView. onDestroy();
  }
  super.onDestroy();
}

4.9 切换清晰度接口

此接口用于切换清晰度,ResolutionInfo类的定义请参见清晰度信息ResolutionInfo类的定义,切换清晰度的调用时机请参见切换清晰度调用时机

函数原型:

public class HmcpVideoView {
        public void onSwitchResolution (int level, ResolutionInfo resolution, int rate)
}

表4-4 切换清晰度参数说明

参数 类型 必填项 说明
level int 预留字段,传0
resolution ResolutionInfo 要切换的清晰度信息
rate int 预留字段,传0

示例代码:

// 获取清晰度列表
List<ResolutionInfo> resolutionList = hmcpVideoView.getResolutionList;
// 切换清晰度
hmcpVideoView.onSwitchResolution(level, resolution, rate);

注意

切换清晰度接口仅可使用此方法。

4.10 添加控件接口

游戏启动后,通过HmcpVideoView的addView()接口添加控件,如背景图片、设置图标等。

函数原型:

public class HmcpVideoView {
        public void addView(View child);
}

表4-5 添加控件参数说明

参数 类型 必填项 说明
child View 要添加控件的View

示例代码:

// view 可以自定义
hmcpVideoView.addView(view);    

4.11 获取配置信息接口

获取图片清晰度、测速等相关配置信息。

函数原型:

public class HmcpVideoView {
        public IntroImageInfo mIntroImageInfo;
        public List<ResolutionInfo> mResolutionList;
}

示例代码:

// 背景图片配置信息
introImageInfos = hmcpVideoView.mIntroImageInfo;          
// 清晰度配置信息
resolutionList = hmcpVideoView.mResolutionList;    
// 测速配置最小值
min = Integer.parseInt(Constants.MINIMUM_BITRATE);    

4.12 进入队列接口

获取需要排队信息后调用entryQueue()接口进入队列。

函数原型:

public class HmcpVideoView {
        public void entryQueue()
}

示例代码:

hmcpVideoView.entryQueue();

4.13 退出队列接口

获取需要排队信息后调用exitQueue()接口退出队列。

函数原型:

public class HmcpVideoView {
        public void exitQueue ()
}

示例代码:

hmcpVideoView.exitQueue();

4.14 IDC节点测速接口

游戏启动前,调用HmcpManager类的testSpeed()接口进行网络带宽测试。

通过duration参数控制测试的最长时间,单位为s。测试完成后通过注册的callback接口返回测试结果,单位为 KB/s。

函数原型:

public class HmcpManager {
    public void testSpeed(boolean isIpv6, final int duration, final String clientISP,
final String clientProvince, final String clientCity, final OnSpeedTestCallBackListener listener)

    public void testSpeed(boolean isIpv6, final int duration, final String clientISP,
final String clientProvince, final String clientCity, String gameBID,final OnSpeedTestCallBackListener listener)    
}

表4-6 测速参数说明

参数 类型 必填项 说明
isIpv6 boolean 是否是Ipv6
duration int 检测速度所用时间,单位为s
clientISP String 运营商名称
clientProvince String 当前定位省份
clientCity String 当前定位城市
gameBID String 游戏bid
listener OnSpeedTestCallBackListener 节点测速接口回调监听器

表4-7 OnSpeedTestCallBackListener说明

方法名 参数 类型 说明
onComplete success boolean 测速结果。
true:表示测速通过
false:表示测试未通过
speed int 测速值,单位为KB/s
speedThreshold int 测速最低阈值,单位为KB/s

示例代码:

HmcpManager manager = HmcpManager.getInstance();
manager.testSpeed(5, "联通", "河北", "廊坊", new OnSpeedTestCallBackListener() {
  @Override
  public void success(boolean success, int speed, int speedTheshold) {
      //to do somthing
  }
});

4.15 点测速接口

游戏启动后,通过HmcpVideoView的点测速接口getVideoLatency()获取实时视频网络延迟,单位为ms。

函数原型:

public class HmcpVideoView {
        public int getVideoLatency()
}

示例代码:

int latency = hmcpVideoView.getVideoLatency();

4.16 发送消息接口

游戏启动后,通过HmcpVideoView的sendMessage()接口可以向access服务器发送消息。
函数返回值表示:当前长链接是否连接成功。

函数原型:

public class HmcpVideoView {
    //返回当前长链接是否连接成功
    public boolean sendMessage(String payload, MessageType type, OnSendMessageListener listener)
}

表4-8 发送消息参数说明

参数 类型 必填项 说明
payload String 需要发送的消息
type MessageType 消息类型,只支持MessageType.PAY_TYPE
listener OnSendMessageListener 发送消息接口回调监听器

示例代码:

public void testSendMessage(View v) {
    if (hmcpVideoView != null) {
        //isConnect true:长链接成功  false:长链接失败
        boolean isConnect = hmcpVideoView.sendMessage("test send msg", MessageType.PAY_TYPE, new OnSendMessageListener() {
            @Override
            public void result(boolean success, String mid) {
            }
        });
    }
}

4.17 消息回调接口

实现HmcpPlayerListener接口后,在该接口的onMessage()函数中可以收到access服务器的消息回调。

函数原型:

public interface HmcpPlayerListener {
  void onMessage(Message message)
}

表4-9 消息回调返回值说明

返回值 类型 说明
message Message Message的定义以及参数说明请参见消息回调

示例代码:

public class HmcpPlayerActivity extends AppCompatActivity implements HmcpPlayerListener {
  @Override
  public void onMessage(Message message) {
      // 收到退出登录消息回调
  }
}

4.18 获取实时视频信息接口

实现HmcpPlayerListener接口后,在该接口的onPlayStatus()函数中可以收到实时数据的上报。

函数原型:

public interface HmcpPlayerListener {
  void onPlayStatus(int status, long value, String data);
}

表4-10 获取实时视频信息返回结果说明

返回结果 类型 说明
status int 状态值,可为0、1、2,value根据status值不同而含义不同
value long status = 0时,value是采样周期内接受到的视频帧的总大小,单位为Byte
status = 1时,value是采样周期内,渲染帧的总数
status = 2时,value是采样周期内,平均解码耗时,单位为ms
data String 附加信息,status = 0时,data 为采样周期内最大的N帧大小,单位为Byte

示例代码:

public class HmcpPlayerActivity extends AppCompatActivity implements HmcpPlayerListener {
    @Override
    public void onPlayStatus(int status, long value, String data) {
    }
}

4.19 更新uid和游戏时长接口

更新uid和游戏时长的接口。

函数原型:

public class HmcpVideoView {
    public void updateGameUID(Bundle bundle,final OnUpdataGameUIDListener listener)
}

表4-11 更新uid和游戏时长参数说明

参数 类型 必填项 说明
bundle Bundle 调用 put***() ,将下列所有参数赋值并打包到bundle中
listener OnUpdataGameUIDListener 结果回调监听器

表4-12 bundle key说明

key value类型 必填项 说明
HmcpVideoView.PLAY_TIME long 游戏时长,单位为ms(注意确认时间单位是否与代码一致)
HmcpVideoView.USER_ID String 新的用户ID ,uid
HmcpVideoView.TIPS_MSG String 更新成功的tip显示
HmcpVideoView.PAY_PROTO_DATA String 更新的proto data
HmcpVideoView.C_TOKEN String 更新的cToken ,用来校验参数的有效性

注意

更新uid成功后需要重新设置用户信息,详情请参见设置用户登录信息

示例代码:

Bundle bundle = new Bundle();
bundle.putLong(HmcpVideoView.PLAY_TIME, playingTime);
bundle.putString(HmcpVideoView.USER_ID, userID);
bundle.putString(HmcpVideoView.TIPS_MSG, tip);
bundle.putString(HmcpVideoView.PAY_PROTO_DATA, proto_data);
bundle.putString(HmcpVideoView.C_TOKEN, cToken);
OnUpdataGameUIDListener listener = new OnUpdataGameUIDListener () {
  @Override
  public void success(boolean result) {
      // success中返回查询结果,false(更新失败),true(更新成功)
  }
  @Override
  public void fail(String msg) {
      // fail中返回更新失败信息
      // HmcpManager.init(...,true)时
      // msg={"errorCode":"","errorCodeWithoutCid":"","errorMessage":""}
  }
});
hmcpVideoView. updateGameUID(bundle, listener);

4.20 获取Input地址接口

游戏收到第一帧后,通过HmcpVideoView的getInputUrl()接口获取input地址。

函数原型:

public class HmcpVideoView {
    public String getInputUrl();
}

示例代码:

String inputUrl = hmcpVideoView. getInputUrl();

4.21 获取SDK版本号接口

创建HmcpManager后,通过getSDKVersion()获取版本号。

函数原型:

public class HmcpManager{
    public String getSDKVersion()
}

示例代码:

String sdkVersion = HmcpManager.getInstance().getSDKVersion();

4.22 获取清晰度列表接口

获取清晰度列表的接口,分为两种场景。

  • 场景一:使用getResolutionInfos方法获取清晰度列表,该方法会进行网络请求,建议传入对应的StreamType,默认为StreamType.RTMP。

    函数原型:

    public class HmcpManager{
        public void getResolutionInfos(String packageName, String mAppChannel, 
                                     final OnGetResolutionsCallBackListener listener)
    
        public void getResolutionInfos(String packageName, String mAppChannel,  String gameBID,final OnGetResolutionsCallBackListener listener)
        public void getResolutionInfos(String packageName, String mAppChannel,  String gameBID,StreamType streamType,final OnGetResolutionsCallBackListener listener)
    }

    表4-13 获取清晰度列表参数说明

    参数 类型 必填项 说明
    packageName String 游戏包名
    mAppChannel String 游戏配置的AppChannel
    gameBID String 游戏bid
    streamType StreamType 流类型,无streamType参数的方法默认为StreamType.RTMP
    StreamType.RTMP:RTMP播流
    StreamType.WEBRTC:RTC播流
    listener String 查询结果回调监听器

    示例代码:

    OnGetResolutionsCallBackListener listener = new OnGetResolutionsCallBackListener () {
      @Override
      public void success(List mResolutionList) {
          // success查询成功会返回,查询结果为List。注:List可能为空
      }
      @Override
      public void fail(String msg) {
          // fail如查询失败会返回String类型的错误信息。
      }
    });
    HmcpManager.getInstance().getResolutionInfos (packageName, mAppChannel, listener);
  • 场景二:播流成功后,须使用getResolutionList方法获取对应播流类型的清晰度。改方法不进行网络请求,切换清晰度时获取列表,建议使用此方法。

    函数原型:

    public class HmcpVideoView {
        public List<ResolutionInfo> getResolutionList()
    }

    示例代码:

    List<ResolutionInfo> resolutionList = hmcpVideoView.getResolutionList();

4.23 获取视频流基本参数接口

通过HmcpVideoView中的getQRCodeData()接口获取参数。

函数原型:

public class HmcpVideoView {
    public String getQRCodeData()
}

示例代码:

String qrCodeData = hmcpVideoView.getQRCodeData();
// 返回数据格式:
{
  "screenShotUrl":"ws://wss.haimawan.com:9480/websocket?url=10.20.32.79:7682&st=4a61796462746b37314e424235734b45724754416a6c752b7034396445646145",
  "screenResolution":"1920x1080",
  "inputUrl":"ws://115.159.241.62:10267/4a61796462746b37314e424235734b45724754416a6c752b7034396445646145",
  "orientation":0,
  "encryption":""
}            

表4-14 视频流字段说明

字段 类型 说明
screenShotUrl String 截屏流地址
screenResolution String 视频清晰度
inputUrl String input连接地址
orientation int 横竖屏参数
encryption String 加密的cid

4.24 获取云游戏延迟信息接口

通过该接口会返回当前云游戏的延迟信息,该算法的准确性基于APP和实例的时钟校准。

函数原型:

public class HmcpVideoView {
    public VideoDelayInfo getClockDiffVideoLatencyInfo()
}

示例代码:

hmcpVideoView.getClockDiffVideoLatencyInfo();

表4-15 云游戏延迟信息方法说明

方法 方法说明
getNetDelay() 获取帧网络耗时(最近1S内随机采样1帧)
getDecodeDelay() 获取帧解码耗时(最近1S内随机采样1帧)
getRenderDelay() 获取帧渲染耗时只包含解码后送入渲染队列的时间,不包含系统渲染部分(最近1S内随机采样1帧)
getFrameSize() 获取帧大小(最近1S内随机采样1帧)
getVideoFps() 获取客户端接收视频帧数
getBitRate() 获取视频码率
getReciveFrameCount() 收到的总帧数
getReceiveFrameSize() 收到帧的总大小
getPacketsLostRate() 丢包率,该接口只支持webrtc,不支持rtmp,返回为空字符串
getJitterBuffer() JitterBuffer,该接口只支持webrtc,不支持rtmp,返回为-1
getServerEncodeDelay() 服务端编码延迟,该接口只支持webrtc,不支持rtmp,返回为-1
getVideoInputFps() 服务端渲染帧率,该接口只支持webrtc,不支持rtmp,返回为-1,该数据为异步数据,游戏刚启动时为-1
getVideoSendFps() 服务端发送帧率,该接口只支持webrtc,不支持rtmp,返回为-1,该数据为异步数据,游戏刚启动时为-1
getVideoSendBitrate() 服务端发送码率,单位为:kbps,该接口只支持webrtc,不支持rtmp,返回为-1,该数据为异步数据,游戏刚启动时为-1
getReceivedBitrate() 客户端接收码率,单位为:kbps,该接口只支持webrtc,不支持rtmp,返回为-1
getFrameRateOutput() 客户端渲染帧数,该接口只支持webrtc,不支持rtmp,返回为-1
getAudioBitrate() 音频码率,单位为:kbps,该接口只支持webrtc,不支持rtmp,返回为-1
getCodecName(() 编码协议,该接口只支持webrtc,不支持rtmp,返回为为空字符串

注意

如果是RTMP流类型,该接口依赖于服务器打开时钟校准配置和ROM支持,当时钟校准成功时才会有数据返回,之前会返回null。在切换清晰度,前后台切换时,需要重新进行时钟校准,校准成功前会存在异常数据,需要在重新获取第一帧之后调用。

4.25 结束播放接口

游戏启动后,通过HmcpVideoView的release()接口结束播放。可在长时间无操作后调用,也可在其他error时调用。

函数原型:

public class HmcpVideoView {
    public void release()
}

示例代码:

hmcpVideoView.release();

4.26 静音功能开关接口

设置当前的播放为静音状态或关闭静音状态。

函数原型:

public class HmcpVideoView {
    // @param isMute true:全局静音 false:取消全局静音 
      public void setAudioMute(boolean isMute)
}

表4-16 静音功能开关参数说明

参数 类型 必填项 说明
isMute boolean true:表示全局静音
false:表示取消全局静音

示例代码:

hmcpVideoView. setAudioMute(false);

4.27 隐藏SDK本地键盘接口

在需要隐藏SDK本地键盘时,可以通过调用此方法隐藏SDK中打开的本地键盘。

函数原型:

public class HmcpVideoView{
  public void hideKeyboard(){}
}

示例代码:

public void hideInput(View view){
        //隐藏SDK本地键盘
        hmcpVideoView.hideKeyboard()
}

4.28 获取键盘类型接口

调用此方法可获取键盘类型,键盘类型分为本地键盘、云端键盘。

函数原型:

public class HmcpVideoView {
    public void getCloudIMEType(GetCloudIMECallback callback);
}

表4-17 参数说明

参数 类型 说明
callback GetCloudIMECallback 键盘类型结果回调

函数原型:

public interface GetCloudIMECallback {
     /**
     *
     * @param result 0失败,1成功
     * @param imeType 实例键盘类型 0云端键盘,1本地键盘
     */
    void getCloudImeResult(int result, int imeType);
}

示例代码:

hmcpVideoView.getCloudIMEType(new GetCloudIMECallback() {
    @Override
    public void getCloudImeResult(int result, int imeType) {
        String msg = "";
        if (result == 0) {
          msg = "查询失败";
        } else if (result == 1) {
          msg = "查询成功:" + imeType;
        }
    }
})

4.29 获取当前播流类型接口

获取当前播流类型。

注意

收到第一帧后调用。

函数原型:

public class HmcpManager{
    public StreamType getStreamType();
}

表4-18 返回值说明

返回结果 类型 说明
StreamType StreamType RTMP:RTMP
RTC:WEBRTC

示例代码:

StreamType streamType=HmcpManager.getInstance().getStreamType();

5 进阶API

5.1 获取视频流地址接口

游戏启动后,通过HmcpVideoView的getStreamUrl()接口接口获取视频流地址。

函数原型:

public class HmcpVideoView {
    public String getStreamUrl()
}

示例代码:

String streamUrl = hmcpVideoView.getStreamUrl();

5.2 获取cid接口

游戏启动后,通过HmcpManager的getCloudId接口获取cid。

函数原型:

public class HmcpManager{
    public String getCloudId()
}

示例代码:

String cloudId = HmcpManager.getInstance().getCloudId();

5.3 获取游戏存档状态接口

获取存档状态的接口,判断游戏所处状态(正在存档、存档完成、存档失败)。

函数原型:

public class HmcpManager{
    public void getGameArchiveStatus(String packageName, UserInfo userInfo,
                                     final OnSaveGameCallBackListener listener)

    public void getGameArchiveStatus(String packageName, UserInfo userInfo, String gameBID,final OnSaveGameCallBackListener listener)
}

表5-1 获取游戏存档状态参数说明

参数 类型 必填项 说明
packageName String 游戏包名
userInfo UserInfo 用户登录信息,请参见设置用户登录信息
gameBID String 游戏bid
listener OnSaveGameCallBackListener 查询存档结果回调监听器

示例代码:

OnSaveGameCallBackListener listener = new OnSaveGameCallBackListener() {
  @Override
  public void success(boolean result) {
      // success中返回查询结果,false(正在存档),true(存档完成)。
  }
  @Override
  public void fail(String msg) {
      // fail(存档失败),msg为失败信息。
      // HmcpManager.init(...,true)时,msg={"errorCode":"","errorCodeWithoutCid":"","errorMessage":""}
  }
});
HmcpManager.getInstance().getGameArchiveStatus(packageName, userInfo, listener);

5.4 查询是否存在游戏存档接口

查询当前用户是否存在存档的接口。

函数原型:

public class HmcpManager{
    public void gameArchived(String packageName, UserInfo userInfo,
                           final OnSaveGameCallBackListener listener)

    public void gameArchived(String packageName, UserInfo userInfo, String gameBID,
                             final OnSaveGameCallBackListener listener)
}

表5-2 查询是否存在游戏存档参数说明

参数 类型 必填项 说明
packageName String 游戏包名
userInfo UserInfo 用户登录信息,请参见设置用户登录信息
gameBID String 游戏bid
listener OnSaveGameCallBackListener 查询结果回调监听器

示例代码:

OnSaveGameCallBackListener listener = new OnSaveGameCallBackListener() {
  @Override
  public void success(boolean result) {
      // success中返回查询结果,false(没有游戏存档),true(有游戏存档)。
  }
  @Override
  public void fail(String msg) {
      // fail中返回查询失败信息
      // HmcpManager.init(...,true)时
      // msg={"errorCode":"","errorCodeWithoutCid":"","errorMessage":""}
  }
});
HmcpManager.getInstance().gameArchived(packageName, userInfo, listener);

5.5 检测未释放游戏接口

通过用户信息UserInfo查询,是否有未释放实例(仍在运行的游戏)。

函数原型:

public class HmcpManager{
    /**
       * @param userInfo 用户登录信息
       * @param listener 回调函数
       */
    public void checkPlayingGame(UserInfo userInfo, final OnGameIsAliveListener listener)

    public void checkPlayingGame(UserInfo userInfo, String gameBID, final OnGameIsAliveListener listener)
}

表5-3 检测未释放游戏参数说明

参数 类型 必填项 说明
userInfo UserInfo 用户登录信息,请参见设置用户登录信息
gameBID String 游戏bid
listener OnSaveGameCallBackListener 查询结果回调监听器

示例代码:

OnGameIsAliveListener listener = new OnGameIsAliveListener () {
  @Override
  public void success(List<CheckCloudServiceResult.ChannelInfo> channelInfoList) {
      // success 中返回查询结果,channelInfoList,返回的未释放游戏信息,含 pkgName、cid、appChannel
      // 如果有未释放游戏,则取集合第1个元素,如果没有则元素为0;
    if (channelInfoList != null && channelInfoList.size() > 0) {
      final CheckCloudServiceResult.ChannelInfo channelInfo = channelInfoList.get(0);
    }
  }
  @Override
  public void fail(String msg) {
      // fail中返回查询失败信息
      // HmcpManager.init(...,true)时,msg={"errorCode":"","errorCodeWithoutCid":"","errorMessage":""}
  }
});
HmcpManager.getInstance().checkPlayingGame (userInfo, listener);

5.6 根据cid释放实例接口

检测到未释放的cid后,通过调用接口,根据cid释放实例。

函数原型:

public class HmcpManager{
    public void setReleaseCid(String packageName, String cid, String cToken, String appChannel, UserInfo2 userInfo2, final OnSaveGameCallBackListener listener);

    public void setReleaseCid(String packageName, String cloudId, String cToken, String appChannel, UserInfo2 userInfo2,String gameBID, final OnSaveGameCallBackListener listener)
}

表5-4 参数说明

参数 类型 必填项 说明
packageName String 游戏包名,传入要释放的对应游戏包名
cid String 要释放的cid
cToken String 用来校验参数的有效性,cToken的计算方法请参考cToken说明文档
appChannel String 如果存在多款游戏同包名的情况,可以通过appChannel区分。如果不存在则可以忽略。
userInfo2 UserInfo2 用户登录信息,包含字段userId、token
gameBID String 游戏bid
listener OnSaveGameCallBackListener 存档结果回调监听器

表5-5 回调结果

回调结果 类型 说明
code int 请求结果标识。
0:表示请求成功
1:表示请求失败
msg String 当code = 0时返回的信息
errorCode String 当code = 1时返回的错误码
errorMsg String 当code = 1时返回的错误信息

5.7 获取网络请求数据接口

可以使用HmcpManager中的getNetText(HmcpVideoView hmcpVideoView)接口获取网络请求结果数据。

函数原型:

public class HmcpManager{
    public String getNetText (HmcpVideoView  hmcpVideoView)
}

表5-6 获取网络请求数据参数说明

参数 类型 必填项 说明
hmcpVideoView HmcpVideoView SDK播放组件,如果没有创建可以传null

示例代码:

String netText = HmcpManager.getInstance().getNetText(hmcpVideoView)

返回值为字符串格式,可能为null要做为空判断。

返回数据格式见下方:

[{
    "action": "104",
    "index": 0,
    // 结果详细描述
    "msg": "",
    "packageName": "",
    "responseTime": 1565684454987,
    // 请求结果
    "result": "success",
    "startTime": 1565684452774,
    // 请求耗时
    "time": 2213,
    "transId": "7082cbf20b8456c4a02a6e520a7f7982",
    // 网络请求的url
    "url": "https://saasauth.cmgame.com/s/rest/api" 
}, {
    "action": "108",
    "index": 1,
    "msg": "",
    "packageName": "",
    "responseTime": 1565684455511,
    "result": "success",
    "startTime": 1565684455015,
    "time": 496,
    "transId": "7082cbf20b8456c4a02a6e520a7f7982",
    "url": "https://saasauth.cmgame.com/s/rest/api"
}]

表5-7 返回值说明

返回值 类型 说明
url String 网络请求的url
time long 请求耗时
result String 请求结果
uid String 当前用户的uid
cid String 当前云游戏的cid
action String 请求的类型。
长连接:access、input
连接:input
视频流:videoUrl
音频流:audioUrl
action:actionId
transId String 当前申请的唯一id
packageName String 请求的游戏包名
startTime long 开始请求的时间
responseTime String 请求结束的时间
DNS String DNS解析后的IP地址

5.8 云游戏结束信息上报接口

在APP判定云游戏异常结束但SDK未报错误码时,可调用该接口上报云游戏信息,用于SDK排查问题做优化。正常结束也可以调用该接口,该接口对业务逻辑无影响,参数取不到或未定义时可以传空。

函数原型:

public class HmcpVideoView {
    public void reportFinishInfo(int finishCode, String cid, String pkgName, String appChannel, String appVersion, String imei, String deviceId, String gameId)
}

表5-8 云游戏结束信息上报参数说明

参数 类型 必填项 说明
finishCode String 结束状态。
0:表示正常结束
1:表示超时结束
2:表示异常结束,有SDK错误码
3:表示异常结束,无SDK错误码
cid long 当前云游戏cid
pkgName String 当前云游戏包名
appChannel String 当前云游戏渠道号
appVersion String APP版本
deviceId String 用户设备号
gameId String 当前云游戏id号

示例代码:

hmcpVideoView.reportFinishInfo(finishCode, cid, pkgName, appChannel, appVersion, imei, deviceId, gameId);

5.9 获取云游戏状态码接口

云游戏异常结束时,通过该接口返回云游戏当前的状态码,可以分析统计游戏失败原因。

函数原型:

public class HmcpVideoView {
    public String getCloudPlayStatusCode()
}

表5-9 RTMP状态码

RTMP状态码 类型 说明
100999001 String 无流地址,cid未获取成功(初始状态)
100999002 String 无流地址,cid获取成功,Socket连接失败
100999003 String 无流地址,cid获取成功,Socket连接成功,乒乓状态异常
100999004 String 无流地址,cid获取成功,Socket连接成功,乒乓状态正常
100999005 String 无流地址,video成功
100999006 String 有流地址,video失败,audio成功
100999007 String 有流地址,video失败,audio失败,input成功
100999008 String 有流地址,video失败,audio失败,input失败
100999009 String 获取流地址超时
100999010 String 刷新stoken超过次数上限
100999100 String user info 为空

表5-10 WEBRTC状态码

参数 类型 说明
100666001 String 请求流地址未返回成功
100666002 String 请求流地址成功Access长连接失败
100666003 String 请求流地址成功Access长连接成功,乒乓状态异常
100666004 String 请求流地址成功Access长连接成功,乒乓状态正常
100666005 String 有流地址,signal连接失败
100666006 String 有流地址,未收到offer
100666007 String 有流地址,未发送answer
100666008 String 有流地址,未发送candidate
100666009 String 有流地址,未收到candidate
100666010 String 有流地址,webrtc连接超时
100666011 String 有流地址,webrtc连接成功,input成功
100666012 String 有流地址,webrtc连接成功,input成功,未收到第一帧
100666013 String 有流地址,webrtc连接成功,input失败
100666014 String 有流地址,webrtc连接成功,input失败,未收到第一帧
100666015 String 有流地址,webrtc连接失败,input成功
100666016 String 有流地址,webrtc连接失败,input失败

示例代码:

String cloudPlayStatusCode = hmcpVideoView.getCloudPlayStatusCode();

5.10 开始直播接口

函数原型:

public class HmcpVideoView {
    public void startLiving(String livingId, String livingUrl, OnLivingListener listener);
}

表5-11 开始直播参数说明

参数 类型 必填项 说明
livingId String 直播id
livingUrl String 直播地址
listener OnLivingListener 调用结果回调

示例代码:

hmcpVideoView.startLiving(livingId, livingUrl, new OnLivingListener() {
  @Override
  public void start(boolean success, String msg) {
    if (success) {
        // 开始直播成功
    }else{
        // HmcpManager.init(...,true)时,msg={"errorCode":"","errorCodeWithoutCid":"","errorMessage":""}}
    }
  }
  @Override
  public void stop(boolean success, String msg) {
    if (success) {
        // 停止直播成功
    }else{
        // HmcpManager.init(...,true)时,msg={"errorCode":"","errorCodeWithoutCid":"","errorMessage":""}}
    }
  }
});

5.11 停止直播接口

函数原型:

public class HmcpVideoView {
    public void stopLiving(String livingId, OnLivingListener listener);
}

表5-12 停止直播参数说明

参数 类型 必填项 说明
listener OnLivingListener 调用结果回调
livingId String 直播id

示例代码:

hmcpVideoView.stopLiving(livingId, new OnLivingListener() {
  @Override
  public void start(boolean success, String msg) {
    if (success) {
        // 开始直播成功
    }else {
        // HmcpManager.init(...,true)时
        // msg={"errorCode":"","errorCodeWithoutCid":"","errorMessage":""}}
    }
  }
  @Override
  public void stop(boolean success, String msg) {
    if (success) {
        // 停止直播成功
    }else {
        // HmcpManager.init(...,true)时,msg={"errorCode":"","errorCodeWithoutCid":"","errorMessage":""}}
    }
  }
});

5.12 获取授权码接口

函数原型:

public class HmcpVideoView {
    public void getPinCode(OnContronListener listener);
}

表5-13 获取授权码参数说明

参数 类型 必填项 说明
listener OnContronListener 调用结果回调

示例代码:

hmcpVideoView.getPinCode(new OnContronListener() {
  @Override
  public void pinCodeResult(boolean success, String cid, String pinCode, String msg) {
    if (success) {
        // 获取授权码成功
    } else {
        // 获取授权码失败
        // HmcpManager.init(...,true)时,msg={"errorCode":"","errorCodeWithoutCid":"","errorMessage":""}}
    } 
  }
  @Override
  public void contronResult(boolean success, String msg) {
    if (success) {
        // 获取控制权成功
    } else {
        // 获取控制权失败
        // HmcpManager.init(...,true)时,msg={"errorCode":"","errorCodeWithoutCid":"","errorMessage":""}}
    } 
  }
  @Override
  public void contronLost() {
      // 失去控制权
  }
});

5.13 获取控制权接口

函数原型:

public class HmcpVideoView {
    public void contronPlay(int streamType, Control controlPara, OnContronListener listener);
}

表5-14 获取控制权参数说明

参数 类型 必填项 说明
streamType int 选择流类型。
0 :表示RTMP
1 :表示WEBRTC
controlPara Control 获取控制权参数对象
listener OnContronListener 调用结果回调

表5-15 Control数据结构说明

参数 类型 必填项 说明
cid String cid
pinCode String 授权码
accessKeyID String 被转移客户端的bid(接入方的唯一ID,用来区分不同的接入方,该值由海马云分配。)
isIPV6 boolean 是否兼容IPV6环境
clientISP String 运营商名称
clientProvince String 当前定位省份
clientCity String 当前定位城市
ScreenOrientation.PORTRAIT ScreenOrientation 屏幕方向
竖屏:ScreenOrientation.PORTRAIT
横屏:ScreenOrientation.LANDSCAPE
cameraOpenPermissionCheck boolean 每次开启摄像头时,向APP申请权限的开关,不传默认为关闭。
true:表示开启
false:表示关闭
权限申请回调请参见关键接口回调中onPermissionNotGranted接口,
权限结果通知请参见通知SDK权限结果接口

示例代码:

Control control = new Control();
control.cid = contronCid;
control.pinCode = contronPinCode;
control.accessKeyID = accessKeyID;
control.isIPV6 = isEnableIpv6;
control.clientISP = clientISP;
control.clientProvince = clientProvince;
control.clientCity = clientCity;
control.orientation = ScreenOrientation.PORTRAIT;

hmcpVideoView.contronPlay(streamType, control, new OnContronListener() { 

    @Override 
    public void pinCodeResult(boolean success, String cid, String pinCode, String msg) { 
        if (success) {
            // 获取授权码成功 
        } else {
            // 获取授权码失败 
        } 
    }

    @Override 
    public void contronResult(boolean success, String msg) { 
        if (success) {
            // 获取控制权成功 
        } else {
            // 获取控制权失败 
        } 
    }

    @Override 
    public void contronLost() {
        // 失去控制权
    } 
});

5.14 是否支持直播接口

函数原型:

public class HmcpVideoView {
    public ELivingCapabilityStatus getLivingCapabilityStatus();
}

表5-16 是否支持直播返回结果说明

返回结果 类型 说明
ELivingCapabilityStatus ENUM 是否支持直播状态

示例代码:

public enum ELivingCapabilityStatus {
    // 未知
    UNKNOWN,
    // 支持
    SUPPORTED,
    // 不支持
    UNSUPPORTED
}

示例代码:

ELivingCapabilityStatus livingCapabilityStatus = hmcpVideoView.getLivingCapabilityStatus();

5.15 开始录音接口

一些支持语音连麦的云游戏中,用户触发云游戏中的语音连麦功能,当SDK没有录音权限时,SDK回调APP申请权限(详情请参见关键接口回调中的onPermissionNotGranted回调接口),当用户允许录音权限后,APP要主动调用开始录音接口启动云游戏连麦功能。

函数原型:

public class HmcpVideoView {
    public void startRecord();
}

示例代码:

@Override
public void onPermissionNotGranted(String permission) {
    if (permission.equals(Manifest.permission.RECORD_AUDIO)) {
        // APP帮助sdk申请连麦权限
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,             @NonNull int[] grantResults) {
    // 需要在获取录音权限后拉起录音
    hmcpVideoView.startRecord();
}

5.16 设置可存档最小游戏时间并退出游戏接口

使用此接口可设置可存档最小游戏时间并退出游戏。

函数原型:

public class HmcpVideoView{ 
    public void stopAndDismiss(Activity activity, int archiveMinSeconds); 
}

表5-17 设置可存档最小游戏时间并退出游戏参数说明

参数 类型 必填项 说明
activity Activity APP播流页Activity对象,设置此参数,SDK会调用Activity的finish方法,关闭播流页
archiveMinSeconds int 可存档游戏的最小游戏时间,单位为s,小于0时当0处理

示例代码:

// 退出游戏,游戏时间大于 60 秒以上才可以存档,关闭activity
hmcpVideoView.stopAndDismiss(activity, 60);    
// 退出游戏,游戏时间大于 60 秒以上可以存档
hmcpVideoView.stopAndDismiss(null, 60);        

5.17 云游戏中远端实例状态通知接口

用户在云游戏中分享、打开摄像头、打开系统相册、游戏内截图、云端截图等动作,SDK回调通知APP。此功能默认关闭,如需开启请联系项目对接人员。

函数原型:

public class HmcpVideoView{ 
    public void onCloudDeviceStatus(String message); 
}

表5-18 json格式说明

状态 Json 例如
云游戏中分享 {
“type”:”share_link”,
“link”:”分享链接”,
“package_name”:”游戏包名”
}
{
“bid”:”2c00b1e5528”,
“cid”:”50837988”,
“mid”:”ROM1654746290204”
,”type”:”weixin_share”
“data”:
{
“componentName”:”com.tencent.mm/.plugin.base.stub.WXEntryActivity”,
“extraInfo”:{},
“fileList”:[“/data/local/tmp/61bfc64234d4b4dc694d5bb0cbc362e3.jpg”],
“scene”:”friend”
,”shareType”:”SHARE_IMAGE_ONLY”
},
}
云游戏中打开摄像头 {
“type”:”open_camera”,
“package_name”:”游戏包名”
}
{
“type”:”open_camera”,
“package_name”:”com.netease.sky”
}
云游戏中打开系统相册 {
“type”:”open_gallery”,
“package_name”:”游戏包名”
}
{
“type”:”open_gallery”,
“package_name”:”com.netease.sky”
}
云游戏中游戏内截图 {
“type”:”screen_cap”,
“image_name”:”图片名称”
}
{
“type”:”screen_cap”,
“image_name”:”SKY_20210630_120023_416056826138713377.jpg”
}
云游戏中文件创建通知 {
“type”:”download_file”,
“event”:”create_file”,
“data”:{
“name”:”文件名”,
“path”:”云端文件路径”
}
}
{
“type”: “download_file”,
“event”: “create_file”,
“data”: {
“name”: “SKY_20220422_105627_4718240132002729782.mp4”,
“path”: “/sdcard/Movies/Sky”
}
}
云游戏中文件生成通知 {
“type”: “download_file”,
“event”: “download_file”,
“data”: {
“name”: “文件名”,
“path”: “云端文件路径”,
“duration”: 视频文件时长,
“size”: 文件大小
“type”: “文件类型”
}
}
{
“type”: “download_file”,
“event”: “download_file”,
“data”: {
“name”: “SKY_20220422_105627_4718240132002729782.mp4”,
“path”: “/sdcard/Movies/Sky”,
“duration”: 119.023,
“size”: 30785397,
“type”: “video/mp4”
}
}
截图游戏生成通知 {
“type”: “cap_screen”,
“data”: “base64图片编码数据”
}
{
“type”:”cap_screen”,
“data”:”/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAA”,
}
云游戏中磁盘空间状态通知 {
“type”: “storage”,
“data”:{
“action”:”当前Action”,
“usablePercentage”:”当前可用空间占用百分比”
}
}
{
“type”: “storage”,
“data”:{
“action”:”com.hm.action.DEVICE.STORAGE.LOW”,
“usablePercentage”:”14”
}
}

表5-19 分享事件 json字段说明

key value 说明
cid String 本次云玩cid
bid String 本次云玩bid
mid String 本次云玩cid
action String 分享事件的action
componentName String Intent 指定的组件
pkgName String intent指定包名 如系统分享指定包名进行分享
content String 分享的文本内容
fileList List [/xxx/xxx/a.png,xxx/xxx/b.png],当分享图片的时候,由fileList 返回,包含了每张图片的绝对路径信息,支持多张图片信息
scene String 微信分享的类型,好友分享/朋友圈分享,不是微信分享则为空”friend”为好友分享,”moment”为朋友圈分享, android分享无需传值
type String “android_share”,安卓系统分享事件;”weixin_share”, 微信分享事 “weibo_share”,微博分享;“qq_share”,QQ分享;
shareType String SHARE_IMAGE_WITH_TEXT(图文)、SHARE_IMAGE_ONLY(纯图片)、SHARE_TEXT(纯文本)、SHARE_VIDEO(视频)、share_link(链接)
title String 分享的标题
extraInfo String webUrl(链接分享),mimeType(系统分享),videoUrl(视频分享),share_qq_ext_str 扩展字段

5.18 上传、下载图片接口

可以上传一张图片到实例的系统相册中,也可从实例指定目录中下载一张图片到本地。

此功能默认关闭,如需开启请联系项目对接人员。

上传文件限制如下:

  • 图片格式:jpg、png。

  • 图片大小:最小1KB,最大5MB。

函数原型:

public class HmcpVideoView{ 
    public void upload(CloudFile file);
    public void download(CloudFile file);
}

表5-20 HmcpVideoView方法说明

方法 参数 类型 说明
upload file CloudFile 要上传的图片文件
download file CloudFile 要下载的图片文件

表5-21 CloudFile类型中的方法说明

方法 返回值 参数 参数类型 说明
setName void name String 设置上传、下载文件名,如pic-1.jpg、pic-2.png
getName String 返回文件名
setPath void path String 上传:设置文件路径/sdcard/DCIM/Camera/
下载:设置文件路径,/sdcard下任意路径,如/sdcard/Pictures/cloudgame/如果不设置,默认设置到/sdcard/Download目录注:如果设置到系统私有路径、或因权限问题导致创建失败,回调onError方法
setCloudPath void cloudPath String 下载的文件在rom端的路径
getPath String 上传返回文件路径下载该方法返回null

上传、下载结果回调:

 public class CloudOperationListener {
     // 回调APP,通知一个CloudFile文件上传/下载成功
     public void onSuccess(CloudOperation operation, CloudFile file);
     // 回调APP,通知上传/下载任务结束
     public void onFinsish(CloudOperation operation);
     // 回调APP,通知上传/下载任务停止,message是任务停止原因。message格式:{"message":"xxxxx"}
     public void onStop(CloudOperation operation, String message);
     // 回调APP,通知上传/下载任务错误,message是任务错误原因。message格式:{"message":"xxxxx"}
     public void onError(CloudOperation operation, String message);
     // APP调用取消上传/下载接口,SDK回调APP任务取消
     public void onCancel(CloudOperation operation);

}

表5-22 方法说明

方法 参数 类型 描述
onSuccess operation CloudOperation 回调APP,通知一个CloudFile文件上传/下载成功
file CloudFile
onFinish cloudOperation CloudOperation 回调APP,通知上传/下载任务结束
onStop cloudOperation CloudOperation 回调APP,通知上传/下载任务停止,message是任务停止原因。message格式:{"message":"xxxxx"}
message String
onError cloudOperation CloudOperation 回调APP,通知上传/下载任务错误,message是任务错误原因。message格式:{"message":"xxxxx"}
message String
onCancel cloudOperation CloudOperation APP调用取消上传/下载接口,SDK会回调APP任务取消

表5-23 CloudOperation类

枚举成员 描述
UPLOAD 表示上传
DOWNLOAD 表示下载

5.19 取消上传、下载实例的图片接口

取消运行中的任务,APP调用取消上传、下载接口,SDK会回调APP任务取消方法(上传、下载图片接口中onCancel方法)

函数原型:

public class HmcpVideoView {
    public void cancelUpload();
    public void cancelDownload();
}

表5-24 取消上传、下载实例的图片方法说明

方法 描述
cancelUpload 取消当前上传任务
cancelDownload 取消当前下载任务

5.20 获取远端实例图片列表接口

获取远端实例指定目录图片列表,目录由远端实例指定。此功能默认关闭,如需开启请联系项目对接人员。
函数返回值表示:当前长链接是否连接成功。

函数原型:

public class HmcpVideoView {
    //返回当前长链接是否连接成功
    public boolean requestCloudImageList(int limit, int offset, OnCloudImageListListener listener);
}

表5-25 获取远端实例图片列表参数说明

参数 类型 必填项 说明
limit int 索要图片数量
offset int offset表示分页,如从第21张获取,offset设置为20
listener OnCloudImageListListener 返回结果回调,onSuccess返回结果示例:{“type”:”image_list”,”code”:0,”fileNames”:[“SKY_20210624_162116_4917338882358232164.jpg”,”SKY_20210624_161637_8736674650163521885.jpg”]}

示例代码:

public void testRequestImage(View v) {
    if (hmcpVideoView != null) {
        // 获取最新10张截图
        //isConnect true:长链接成功 false:长链接失败
        boolean isConnect = hmcpVideoView. requestCloudImageList (10, 0, new OnCloudImageListListener () {
            @Override
            public void onSuccess(String payload) {
                WsUploadDownloadBean bean = JSONObject.parseObject(payload, WsUploadDownloadBean.class);
                if (bean.fileNames != null) {
                    mListAdapter.addAll(bean.fileNames);
                    mListAdapter.notifyDataSetChanged();
                }
            }

            @Override
            public void onError(String error) {
                Log.e(TAG, "requestCloudImageList onError:" + error);
            }
        });
    }
}

5.21 游戏启动参数携带执行脚本接口

在启动游戏组件时可以携带参数:componentType、extraData、action和componentName,其中action和componentName通过bundle传递,extraData通过方法setExtraData传递。详见申请服务

表5-26 参数说明

参数 类型 必填项 说明
componentType int 组件类型
Activity:
HmcpVideoView.COMPONENT_TYPE_ACTIVITY
Service:
HmcpVideoView.COMPONENT_TYPE_SERVICE
Broadcast:HmcpVideoView.COMPONENT_TYPE_BROADCAST
action String 组件对应的action
componentName String 指定的组件名,格式(packageName/componentName),
如(快手开心消消乐):com.happyelements.AndroidAnimal.kuaishou
/com.happyelements.hellolua.MainActivity
extraData IntentExtraData 额外参数

示例代码:

Bundle bundle = new Bundle();
bundle.putInt(HmcpVideoView.COMPONENT_TYPE, HmcpVideoView.COMPONENT_TYPE_ACTIVITY);
bundle.putString(HmcpVideoView.COMPONENT_ACTION, “android.intent.action.MAIN”);
bundle.putString(HmcpVideoView.COMPONENT_NAME, “com.happyelements.AndroidAnimal.kuaishou/com.happyelements.hellolua.MainActivity”);
hmcpVideoView.play(bundle);

表5-27 IntentExtraData结构定义

参数 类型 说明
booleanExtra HashMap<String,Boolean> 向Intent中添加Boolean
integerExtra HashMap<String,Integer> 向Intent中添加Integer
integerArrayExtra HashMap<String, Integer[]> 向Intent中添加Integer数组
integerListExtra HashMap<String,List<Integer>> 向Intent中添加Integer List
stringExtra HashMap<String, String> 向Intent中添加String
stringArrayExtra HashMap<String, String[]> 向Intent中添加String数组
stringListExtra HashMap<String, List<String>> 向Intent中添加String List
floatExtra HashMap<String, Float> 向Intent中添加Float
floatArrayExtra HashMap<String, Float[]> 向Intent中添加Float数组
floatListExtra HashMap<String, List<Float>> 向Intent中添加Float List
longExtra HashMap<String, Long> 向Intent中添加Long
longArrayExtra HashMap<String, Long[]> 向Intent中添加Long数组
longListExtra HashMap<String, List<Long>> 向Intent中添加Long List
componentNameExtra HashMap<String, String> 向Intent中添加componentName
uriExtra HashMap<String, String> 向Intent中添加uri
applink String 远程组队分享链接

函数原型:

public class HmcpVideoView{
    public void setExtraData(IntentExtraData extraData);
}

示例代码:

IntentExtraData extraData = new IntentExtraData();
HashMap<String, String> map = new HashMap<>();
map.put("StringKey1", “StringValue1”);
extraData.setStringExtra(map);
hmcpVideoView.setExtraData(extraData);

5.22 给ws服务器发送消息接口

启动游戏后,通过HmcpVideoView的sendWsMessage()接口可以向ws服务器发送消息,rom端消息SDK接收此消息
函数返回值表示:当前长链接是否连接成功。

函数原型:

public class HmcpVideoView{
    //返回当前长链接是否连接成功
    boolean sendWsMessage(String payload, WsMessageType type, OnSendWsMessageListener listener);
}

表5-28 给ws服务器发送消息的参数说明

参数 类型 必填项 说明
payload String 要发送的数据,以json格式发送
type WsMessageType 消息类型,可选WsMessageType.GPS_TYPE、WsMessageType.INTENT_TYPE、WsMessageType.UPDATE_VIEW_TYPE
listener OnSendWsMessageListener 发送消息接口回调监听器

发送Intent消息示例代码如下,发送的具体数据由接入方传入:

org.json.JSONObject object = new org.json.JSONObject();
try {
     object.put("key", "value");
     object.put("key", "value");
     object.put("key", "value");
     object.put("key", "value");
} catch (JSONException e) {
     e.printStackTrace();
}
//true:长链接成功  false:长链接失败
boolean isConnect = hmcpVideoView.sendWsMessage(object.toString(), WsMessageType.INTENT_TYPE, this);

可以通过第三个参数传入的listener来获取发送消息的状态。函数原型:

public interface OnSendWsMessageListener {
    void sendWsMessageSuccess();
    void sendWsMessageFail(String msg);
}

表5-29 发送Intent消息参数说明

参数 类型 必填项 说明
msg String 发送失败原因,格式:{“message”:”xxxxx”}

5.23 Intent拦截接口

SDK收到Intent拦截消息之后会通过onInterceptIntent方法通知给APP,APP处理之后再通过sendWsMessage发送处理之后的数据给云游戏,详情请参见给ws服务器发送消息接口

函数原型:

public interface HmcpPlayerListener{
    void onInterceptIntent(String intentData);
}

表5-30 Intent拦截参数介绍

参数 类型 必填项 说明
intentData String 返回的拦截的数据,以json格式发送,如:{“key”:”value”,”key”:”value”,”key”:”value”,”key”:”value”}拦截的数据由接入方提供

5.24 发送GPS数据接口

SDK可以通过sendWsMessage(给ws服务器发送消息接口)发送GPS数据给游戏。

发送GPS消息示例代码如下:

GPSData gpsData = new GPSData();
gpsData.longitude = Float.parseFloat(etGPSLongitude.getText().toString());
gpsData.latitude = Float.parseFloat(etGPSLatitude.getText().toString());
gpsData.altitude = Float.parseFloat(etGPSAltitude.getText().toString());
gpsData.course = Float.parseFloat(etGPSCourse.getText().toString());
gpsData.speed = Float.parseFloat(etGPSSpeed.getText().toString());
hmcpVideoView.sendWsMessage(gpsData.toJsonString(), WsMessageType.GPS_TYPE, this);

5.25 发送云端截图指令接口

SDK可以通过sendWsMessage(给ws服务器发送消息接口)发送截图指令给云端。

发送截图指令示例代码如下:

CapScreenData capScreenData = new CapScreenData();
capScreenData.scalePercent = Float.parseFloat(transferContext.getText().toString());
hmcpVideoView.sendWsMessage(JsonUtil.toJsonString(capScreenData), WsMessageType.CAP_SCREEN_TYPE, this);

截图生成通知处理示例代码如下:

@Override
public void onCloudDeviceStatus(final String status) {
    Log.e(TAG, "==onCloudDeviceStatus==" + status);
    JSONObject object = JSONObject.parseObject(status);
    if (object == null) {
        return;
    }
    if (Constants.WS_MESSAGE_TYPE_CAP_SCREEN.equals(object.getString(Constants.WS_MSG_KEY_TYPE))) {
       String dataStr = object.getString(Constants.WS_MSG_KEY_DATA);
       //base64解码
       byte[] pictureData = Base64.decode(dataStr, Base64.DEFAULT);
       //生成bitmpa就是游戏截图
       Bitmap bitmap = BitmapFactory.decodeByteArray(pictureData, 0, pictureData.length);
    }
}

5.26 发送关闭Loading框消息通知接口

SDK可以通过sendWsMessage(给ws服务器发送消息接口)发送关闭Loading框通知给游戏。

发送关闭Loading框消息示例代码如下:

org.json.JSONObject object = new org.json.JSONObject();
try {
    object.put(Constants.WS_MSG_KEY_ACTION, Constants.WS_MSG_CLOSE_LOADING);
} catch (JSONException e) {
    LogUtils.e(TAG, e.getMessage());
}
hmcpVideoView.sendWsMessage(object.toString(), WsMessageType.UPDATE_VIEW_TYPE, this);

5.27 一键返回游戏界面接口

通过HmcpVideoView中的backToGame()接口执行返回按键操作。请根据已有逻辑, 在合适的地方增加backToGame()方法调用, 对云端设备发送指令, 相当于手机中唤起游戏到前台。

适用场景:针对有些第三方登录多级,无法返回的情况。

函数原型:

public class HmcpVideoView {
    public void backToGame()
}

示例代码:

hmcpVideoView.backToGame();

5.28 通知SDK权限结果接口

一些云游戏中功能,会触发一些权限的申请,譬如语音连麦需要录音权限、人脸识别功能需要摄像头权限。当SDK没有权限时,SDK回调通知APP申请权限(详情请参见关键接口回调中onPermissionNotGranted回调接口),用户允许或者拒绝权限后,APP要调用接口通知SDK权限结果。

如果APP没有摄像头权限,SDK会通知APP向用户申请摄像头权限,并一直等待授权结果,APP需要实现用户申请权限的界面和交互,并在用户同意或者不同意授权的时候将结果通知给SDK,以便摄像头的后续处理。

注意

当前只支持摄像头权限处理,SDK通过onPermissionNotGranted接口通知APP权限申请,SDK没有收到APP告知权限结果之前,不会再次通知APP相同权限申请。

函数原型:

public class HmcpVideoView {
    public void handlePermissionResult(String permission, boolean isGranted);
}

示例代码:

@Override
public void onPermissionNotGranted(String permission) {
    if (permission.equals(Manifest.permission.CAMERA)) {
        // APP帮助SDK申请摄像头权限
        ActivityCompat.requestPermissions(
            BasePlayerActivity.this, 
            new String[]{Manifest.permission.CAMERA}, 
            917
        );
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case 917:    
            // 摄像头权限结果通知SDK
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                hmcpVideoView.handlePermissionResult(Manifest.permission.CAMERA, true);
            } else {
                hmcpVideoView.handlePermissionResult(Manifest.permission.CAMERA, false);
            }

    }
}

5.29 获取用户最后一次操作时间戳接口

游戏启动后,通过该接口获取用户最后一次操作实例的时间戳。

函数原型:

public class HmcpVideoView {
    public long getLastUserOperationTimestamp()
}

示例代码:

// 默认返回0,代表用户没有操作过实例,否则返回相应时间戳
hmcpVideoView.getLastUserOperationTimestamp();    

5.30 重置无操作超时计时器接口

游戏启动后,重置无操作超时计时器时调用此函数。

函数原型:

public class HmcpVideoView {
    public int resetInputTimer()
    public int resetInputTimer(boolean needUpdateTimestamp)
}

表5-31 重置无操作超时计时器参数说明

参数 类型 必填项 说明
needUpdateTimestamp boolean true:表示重置计时器并且更新用户最后一次操作时间戳
false:表示重置计时器不更新用户最后一次操作时间戳

表5-32 返回结果说明

返回结果 类型 说明
result int 0 : 表示和实例连接异常
1 : 表示重置无操作超时计数器成功

示例代码:

hmcpVideoView.resetInputTimer();
hmcpVideoView.resetInputTimer(false);

5.31 获取当前播放器截屏接口

游戏启动后,获取当前截屏和检测功能时调用此函数。

函数原型:

public class HmcpVideoView {
    public Bitmap getShortcut()
}

表5-33 当前播放器截屏返回结果说明

返回结果 类型 说明
Bitmap Bitmap 当前播放器截屏的 bitmap 对象

示例代码:

Bitmap bitmap = hmcpVideoView.getShortcut();

5.32 检测当前截屏是否黑屏接口

检测当前截屏的bitmap对象是否黑屏功能时调用此函数。

函数原型:

public class HmcpVideoView {
    public int checkBitmap (Bitmap bitmap)
}

表5-34 检测当前截屏是否黑屏参数说明

参数 类型 必填项 说明
bitmap Bitmap 需要检测的bitmap对象

表5-35 返回结果说明

返回结果 类型 说明
1/2/3/4 int 1:表示检测结果为纯色 排除黑色和全透明色,因为播放器没开始工作,不通设备获取截屏有的是纯黑色有的是纯透明色
2:表示检测结果为纯透明色
3:表示检测结果为正常
4:表示检测结果为纯黑色

示例代码:

int result = hmcpVideoView.checkBitmap(bitmap);

5.33 发送返回键事件给实例接口

在需要发送返回键事件给实例时,可以通过调用此方法发送返回键事件。

函数原型:

public class HmcpVideoView{
    // KeyType 是枚举类,这里参数固定为 KeyType.KEY_BACK
    public void sendKeyEvent(KeyType keyType){}
}

示例代码:

public void sendBackKeyEventClick(View view){
    // 发送返回键事件,KeyType 是枚举类,这里参数固定为 KeyType.KEY_BACK
    hmcpVideoView.sendKeyEvent(KeyType.KEY_BACK);
}

5.34 发送剪切板数据接口

SDK可以通过sendWsMessage(给ws服务器发送消息接口)发送剪切板数据给游戏。

注意

itemData长度不超过1024个字符。

发送剪切板消息示例代码如下:

List<ClipBoardItemData> data = new ArrayList<>();
ClipBoardItemData clipBoardItemData = new ClipBoardItemData();
clipBoardItemData.itemType = ClipBoardItemData.TYPE_TEXT_PLAIN;
clipBoardItemData.itemData = etClipboard.getText().toString(); //要发送的数据
data.add(clipBoardItemData);

ClipBoardData clipBoardData = new ClipBoardData();
clipBoardData.data = data;
clipBoardData.dataType = ClipBoardData.CLIPBOARD_DATA_TYPE_PLAIN;
clipBoardData.code = ClipBoardData.CLIPBOARD_DATA_CODE;

hmcpVideoView.sendWsMessage(JsonUtil.toJsonString(clipBoardData), WsMessageType.CLIPBOARD_TYPE, this);

5.35 本地键盘拉起收起通知接口

本地键盘开启后,本地键盘会通过接口onCloudPlayerKeyboardStatusChanged回调APP键盘拉起和收起状态。

注意

此功能需要配置开启,默认关闭,如需开启请联系项目对接人员。

函数原型:

public interface HmcpPlayerListener{
    void onCloudPlayerKeyboardStatusChanged(CloudPlayerKeyboardStatus status);
}

表5-36 参数介绍

参数 类型 说明
status CloudPlayerKeyboardStatus枚举 CLOUD_PLAYER_KEYBOARD_STATUS_NONE:默认
CLOUD_PLAYER_KEYBOARD_STATUS_SHOW:显示
CLOUD_PLAYER_KEYBOARD_STATUS_HIDE:隐藏

5.36 将数据写入到云端文本框接口

函数原型:

public class HmcpVideoView {
    public boolean inputText(String payload);
}

表5-37 参数说明

参数 类型 说明
payload String 发送的内容(最大长度256个字符)

示例代码:

hmcpVideoView.inputText("this is test data");

5.37 输入法切换接口

云游戏提供实例软键盘、手机端系统默认键盘切换功能。

函数原型:

public class HmcpVideoView {
    public void switchIME(SwitchIMECallback callback);
}

表5-38 参数说明

参数 类型 说明
callback SwitchIMECallback 输入法切换结果回调

函数原型:

public interface SwitchIMECallback {
    void onSwitchIMEResult(int result,String info);
}

示例代码:

hmcpVideoView.switchIME(new SwitchIMECallback() {
    @Override
    public void onSwitchIMEResult(int result, String info) {
        switch(result) {
            case 0:
                //切换失败
                break;
            case 1:
                //切换成功
                break;
            default:
                //等待切换结果
                break;
        }
    }
})

5.38 获取刘海屏高度占比接口

云游戏向Android P以上版本提供获取刘海屏高度占比接口,APP通过该接口获取到返回值,将返回值放入startPlay的入参内使游戏支持异形屏。
创建HmcpManager后,通过getCutOutsHeightPercent()获取刘海高度占比。

函数原型:

public class HmcpManager {
      @RequiresApi(api = Build.VERSION_CODES.P)
    public float[] getCutOutsHeightPercent(Activity context) {}
}

表5-39 方法说明

方法名 参数 类型 说明
getCutOutsHeightPercent context Activity Activity上下文

表5-40 返回值说明

返回值 类型 说明
cutOutsHeightPer float[] 屏幕2个刘海所占的高度占比,默认值0.0f,数组大小为2

5.39 查询文件下载任务状态接口

调用HmcpVideoView.getCloudFileStatus()接口查询下载任务状态。

函数原型:

public class HmcpVideoView {
    public int getCloudFileStatus(CloudOperation operation, CloudFileProtocol protocol)
}

表5-41 返回值说明

返回值类型 说明
int 任务状态。
-1:查询类型不支持
0:空闲状态
1:运行状态

表5-42 参数说明

参数 类型 说明
operation CloudOperation 文件操作类型,上传、下载,参见表5-58 CloudOperation说明
注:目前只支持CloudOperation.DOWNLOAD
protocol CloudFileProtocol 文件传输协议,WebSocket、HTTP,参见表5-43 CloudFileProtocol说明

表5-43 CloudFileProtocol说明

类型 说明
SOCKET WebSocket协议
HTTP HTTP协议

示例代码:

public class PlayerActivity extends Activity implements HmcpPlayerListener {

    private HmcpVideoView mHmcpVideoView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mHmcpVideoView = (HmcpVideoView) findViewById(R.id.hmcp_view);
    }

    /**
     * 任务是否运行中
     * @param operation 云文件操作方式,上传、下载
     * @param protocol 云文件操作协议,socket、http
     * @return -1为不支持的查询类型,0为空闲状态,1为运行状态
     */
    private boolean isRunning(CloudOperation operation, CloudFileProtocol protocol) {
        return mHmcpVideoView.getCloudFileStatus(operation, protocol);
    }
}

5.40 查询可下载文件列表接口

调用HmcpVideoView.queryCloudFile()接口查询云端文件列表。

函数原型:

public class HmcpPlayerListener {
    public void queryCloudFile(QueryCallback callback)
}

表5-44 参数说明

参数 类型 说明
callback QueryCallback APP查询实例文件列表结果回调

表5-45 QueryCallback

方法 返回值 参数 参数类型 说明
onQuery void files List<CloudFile> 文件列表集合,CloudFile参见表5-47 CloudFile说明
onCancelFail void errorCode int 查询可下载文件列表失败的错误码
errorMessage String 查询可下载文件列表失败的错误信息

示例代码:

public class PlayerActivity extends Activity implements HmcpPlayerListener, QueryCallback {

    private HmcpVideoView mHmcpVideoView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mHmcpVideoView = (HmcpVideoView) findViewById(R.id.hmcp_view);
    }

    /**
     * 查询云端文件列表
     */
    private void queryCloudFile() {
        mHmcpVidewView.queryCloudFile(PlayerActivity.this);
    }

    /**
     * QueryCallback接口实现
     * 
     * 查询可下载文件列表结果
     * @param files 文件列表
     */
    @Override
    public void onQuery(List<CloudFile> files) {
        if (files != null && !files.isEmpty()) {
            DownloadMode mode = DownloadMode.NORMAL;
            downloadFiles(files, mode, PlayerActivity.this);
        } else {
            //无文件
        }
    }

    /**
     * QueryCallback接口实现
     * 
     * 查询可下载文件列表失败
     * @param errorCode 错误码
     * @param errorCode 错误信息
     */
    @Override
    public void onQueryFail(int errorCode, String message) {
        //文件列表查询失败
    }
}

5.41 文件下载接口

APP获取到可下载的文件列表后,调用SDK的HmcpVideoView.download()接口,将需要下载的文件下载至手机中。可重复下载同一文件,生成不同的文件名。

函数原型:

public class HmcpVideoView {
    public void download(List<CloudFile> fileList, DownloadMode mode, DownloadCallback callback)

表5-46 参数说明

参数 类型 说明
fileList List<CloudFile> 下载文件列表,CloudFile参见表5-47 CloudFile说明
mode DownloadMode 下载方式,参见表5-48 DownloadMode说明
callback DownloadCallback APP下载文件进度、结果的回调,参见表5-49 DownloadCallback说明

表5-47 CloudFile说明

方法 返回值 参数 参数类型 说明
setName void name String 设置文件名称
getName String - - 获取文件名称
setPath void path String 设置文件保存路径。
不设置路径,sdk默认保存在/sdcard/Downloads下
getPath String - - 获取文件保存路径
setCloudPath void cloudPath String 设置文件实例路径
getCloudPath String - - 返回文件实例路径
setSize void size long 设置文件大小,单位为Byte
getSize long - - 返回文件大小,单位为Byte
setVideoDuration void videoDuration double 设置视频文件时长,单位为s
getVideoDuration double - - 返回视频文件时长,单位为s
setDownloadTime void downloadTime long 设置下载保活时长,单位为s。每个下载文件可以单独设置保活时长。
最小时长60s,最大时长3600s
getDownloadTime long - - 获取下载保活时长,单位为s
getDownloadedName String - - 文件下载完成的文件名

表5-48 DownloadMode说明

类型 说明
NORMAL 下载文件时可以正常播流,用户可正常操作游戏
DOWNLOAD_ONLY 下载文件时会断流,用户无法操作游戏,下载完成后重新播流。
下载文件过程中,若有前后台切换动作,比如前台切后台、后台切回前台,SDK会通过HmcpPlayerListener.HmcpPlayerStatusCallback回调APP status = 45,表示当前处于断流下载文件中,不会播流

表5-49 DownloadCallback说明

方法 返回值 参数 参数类型 说明
onDownload void file CloudFile 文件下载完成,CloudFile参见表5-47 CloudFile说明
onDownloadProgress void file CloudFile 正在下载的文件,参见表5-47 CloudFile说明
fileSize long 文件大小,单位为Byte
downloadSize long 已下载大小,单位为Byte
onDownloadFail void file CloudFile 下载失败的文件,参见表5-47 CloudFile说明
errorCode int 文件下载失败的错误码
errorMessage String 文件下载失败的错误信息
onDownloadFail void errorCode int 下载任务失败的错误码
errorMessage String 下载任务失败的错误信息
onDownloadFinish void - - 下载任务完成
onDownloading void - - 任务运行中

示例代码:

public class PlayerActivity extends Activity implements HmcpPlayerListener, DownloadCallback {

    private HmcpVideoView mHmcpVideoView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mHmcpVideoView = (HmcpVideoView) findViewById(R.id.hmcp_view);
    }

    /**
     * 文件下载
     * @param files 文件列表
     * @param mode 下载模式,DownloadMode.NORMAL不断流下载,DownloadMode.DownloadMode
     * 断流下载
     */
    private void downloadFiles(List<CloudFile> files, DownloadMode mode) {
        CloudOperation op = CloudOperation.DOWNLOAD;
        CloudFileProtocol protocol = CloudFileProtocol.HTTP;
        mHmcpVidewView.download(files, mode, PlayerActivity.this);
    }

    /**
     * DownloadCallback接口实现
     *
     * 文件下载完成
     * @param file 下载完成的文件
     */
    @Override
    public void onDownload(CloudFile file) {
        //file下载完成
    }

    /*
     * DownloadCallback接口实现
     *
     * 文件下载进度
     * @param file 下载中的文件
     * @param fileSize 下载文件的大小
     * @param downloadSize 已下载的大小
     */
    @Override
    public void onDownloadProgress(CloudFile file, long fileSize, long downloadSize) {
        //file的下载进度
    }

    /*
     * DownloadCallback接口实现
     *
     * 文件下载失败
     * @param file 下载的文件
     * @param errorCode 错误码
     * @param message 错误信息
     */
    @Override
    public void onDownloadFail(CloudFile file, int errorCode, String message) {
        //file下载失败
    }

    /*
     * DownloadCallback接口实现
     *
     * 下载任务失败
     * @param errorCode 错误码
     * @param message 错误信息
     */
    @Override
    public void onDownloadFail(int errorCode, String message) {
        //下载任务失败
    }

    /*
     * DownloadCallback接口实现
     *
     * 下载任务完成
     */
    @Override
    public void onDownloadFinish() {
        //下载任务完成
    }

    /*
     * DownloadCallback接口实现
     *
     * 下载任务运行中
     */
    @Override
    public void onDownloading() {
        //下载任务运行中
    }

}

5.42 获取文件下载任务列表接口

调用HmcpVideoView.getWorkingFile()接口可以获取下载任务列表,列表包含下载中文件和待下载文件。

函数原型:

public class HmcpVideoView {
    public void getWorkingFile(CloudOperation operation, CloudFileType fileType, WorkingFileCallback callback)
}

表5-50 参数说明

参数 类型 说明
operation CloudOperation 文件操作类型,上传、下载,参见表5-58 CloudOperation说明
注:目前只支持下载(CloudOperation.DOWNLOAD)
fileType CloudFileType 文件类型,参见表5-51 CloudFileType
callback WorkingFileCallback 结果回调

表5-51 CloudFileType

类型 说明
IMAGE 图片
VIDEO 视频

表5-52 WorkingFileCallback

方法 返回值 参数 参数类型 说明
onWorking void files List<CloudFile> 下载任务文件列表集合,CloudFile参见表5-47 CloudFile说明
onWorkingFail void errorCode int 获取下载任务文件列表失败的错误码
errorMessage String 获取下载任务文件列表失败的错误信息

示例代码:

public class PlayerActivity extends Activity implements HmcpPlayerListener, WorkingFileCallback {

    private HmcpVideoView mHmcpVideoView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mHmcpVideoView = (HmcpVideoView) findViewById(R.id.hmcp_view);
    }

    /**
     * 获取下载任务列表
     * @param operation 云文件操作方式,上传、下载
     */
    private void getWorkingFiles(CloudOperation operation) {
        mHmcpVidewView.getWorkingFile(operation, PlayerActivity.this);
    }

    /**
     * WorkingFileCallback接口实现
     *
     * 查询下载任务中的文件列表结果,包含下载中文件和待下载文件
     * @param files 下载中的文件列表
     */
    @Override
    public void onWorking(List<CloudFile> files) {
        //处理下载中列表
    }

    /**
     * WorkingFileCallback接口实现
     *
     * 查询下载任务中的文件列表失败
     * @param errorCode 错误码
     * @param message 错误信息
     */
    @Override
    public void onWorkingFail(int errorCode, String message) {
        //处理失败
    }
}

5.43 取消文件下载接口

调用HmcpVideoView.cancelDownload()接口取消下载列表中的指定文件或者取消本次下载。

函数原型:

public class HmcpVideoView{
    public void cancelDownload(CloudFile file, CancelCallback callback)
}

表5-53 参数说明

参数 类型 说明
file CloudFile 取消下载的文件,null表示取消本次下载
callback CancelCallback 取消下载结果回调

表5-54 CancelCallback

方法 返回值 参数 参数类型 说明
onCanceled void files List<CloudFile> 取消下载的文件集合,CloudFile参见表5-47 CloudFile说明
onCancelFail void file CloudFile 取消失败的下载文件,参见表5-47 CloudFile说明
errorCode int 下载文件取消失败的错误码
errorMessage String 下载文件取消失败的错误信息

示例代码:

public class PlayerActivity extends Activity implements HmcpPlayerListener, CancelCallback {

    private HmcpVideoView mHmcpVideoView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mHmcpVideoView = (HmcpVideoView) findViewById(R.id.hmcp_view);
    }

    /**
     * 取消文件下载
     * @param file 取消的文件
     */
    private void cancelCloudFile(CloudFile file) {
        mHmcpVidewView.cancelDownload(file, this);
    }

    /**
     * 取消全部文件下载
     */
    private void cancelAllCloudFile() {
        mHmcpVidewView.cancelDownload(null, this);
    }

    /**
     * CancelCallback接口实现
     *
     * 下载文件取消结果
     * @param files 取消的文件列表
     */
    @Override
    public void onCanceled(List<CloudFile> files) {
        //处理取消的文件列表
    }

    /**
     * CancelCallback接口实现
     *
     * 下载文件取消失败
     * @param file 取消的文件
     * @param errorCode 错误码
     * @param message 错误信息
     */
    @Override
    public void onCancelFail(CloudFile file, int errorCode, String message) {
        //处理取消失败
    }
}

5.44 查询取消下载文件列表

取消正在下载的文件后,可以调用HmcpVideoView.searchCloudFile()接口查询文件信息,调用HmcpVideoView.download()接口可恢复下载。

函数原型:

public class HmcpPlayerListener {
    public void searchCloudFile(SearchCallback callback)
}

表5-55 参数说明

参数 类型 说明
callback SearchCallback 查询结果回调接口

表5-56 SearchCallback

方法 返回值 参数 参数类型 说明
onSearched void files List<CloudFile> 文件列表集合,CloudFile参见表5-47 CloudFile说明
onSearchFail void errorCode int 查询失败的错误码
errorMessage String 查询失败的错误信息

示例代码:

public class PlayerActivity extends Activity implements HmcpPlayerListener, SearchCallback {

    private HmcpVideoView mHmcpVideoView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mHmcpVideoView = (HmcpVideoView) findViewById(R.id.hmcp_view);
    }

    @Override
    public void onSceneChanged(String sceneMessage) {
        if (sceneMessage.contains("firstFrameArrival")) {
            mHmcpVidewView.searchCloudFile(PlayerActivity.this)
        }
    }

    /**
     * SearchCallback接口实现
     * 
     * 查询下载中文件被取消的文件列表
     * @param files 文件列表
     */  
    @Override
    public void onSearched(List<CloudFile> files) {
        if (files != null && !files.isEmpty()) {
            DownloadMode mode = DownloadMode.NORMAL;
            downloadFiles(files, mode, PlayerActivity.this);
        } else {
            //无文件
        }
    }

    /**
     * SearchCallback接口实现
     * 
     * 查询下载中文件被取消的文件列表失败
     * @param errorCode 错误码
     * @param errorCode 错误信息
     */
    @Override
    public void onSearchFail(int errorCode, String message) {
        //查询失败
    }
}

5.45 更新文件下载列表接口

调用HmcpVideoView.updateWorkingFile()接口可更新下载列表,当前下载列表中未开始下载的任务将全部取消,处于下载中的文件不会受影响,新的下载任务将添加至下载列表中。

函数原型:

public class HmcpVideoView{
    public void updateWorkingFile(CloudOperation operation, List<CloudFile> files, UpdateCallback callback)
}

表5-57 参数说明

参数 类型 说明
operation CloudOperation 文件操作类型,上传、下载,参见表5-58 CloudOperation说明
注:目前只支持下载(CloudOperation.DOWNLOAD)
files List<CloudFile> 更新的列表,CloudFile参见表5-47 CloudFile说明
callback UpdateCallback 更新文件下载列表结果回调

表5-58 CloudOperation说明

类型 说明
UPLOAD 文件上传
DOWNLOAD 文件下载

表5-59 UpdateCallback

方法 返回值 参数 参数类型 说明
onUpdated void files List<CloudFile> 更新文件列表集合,CloudFile参见表5-47 CloudFile说明
onUpdateFail void errorCode int 更新文件列表失败的错误码
errorMessage String 更新文件列表失败的错误信息

示例代码:

public class PlayerActivity extends Activity implements HmcpPlayerListener, UpdateCallback {

    private HmcpVideoView mHmcpVideoView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mHmcpVideoView = (HmcpVideoView) findViewById(R.id.hmcp_view);
    }

    /**
     * 获取下载任务列表
     * @param operation 云文件操作方式,上传、下载
     */
    private void getWorkingFiles(CloudOperation operation) {
        CloudOperation op = CloudOperation.DOWNLOAD;
        mHmcpVidewView.getWorkingFile(op, operation, PlayerActivity.this);
    }

    /**
     * UpdateCallback接口实现
     *
     * 文件列表更新结果
     * @param files 更新成功后的文件列表
     */
    @Override
    public void onUpdated(List<CloudFile> files) {
        //处理更新的列表
    }

    /**
     * UpdateCallback接口实现
     *
     * 文件列表更新失败
     * @param errorCode 错误码
     * @param message 错误信息
     */
    @Override
    public void onUpdateFail(int errorCode, String message) {
        //处理更新失败
    }
}

5.46 设置游戏画面黑白模式接口

云玩过程中可以调用HmcpVideoView.setColorMode接口,将游戏画面改变黑白色。

函数原型:

public class HmcpVideoView {
    public void setColorMode(ColorMode mode, ColorModeListener listener)
}

表5-60 参数说明

参数 类型 说明
mode ColorMode 颜色模式设置,参见[表5-61 ColorMode说明](#表5-61 ColorMode说明)
listener ColorModeListener 设置结果回调,参见[表5-62 ColorModeListener说明](#表5-62 ColorModeListener说明)

表5-61 ColorMode说明

方法 返回值 参数 参数类型 说明
setMode void mode int 设置颜色模式,支持两个模式
1、正常模式:ColorMode.NORMAL,画面为彩色
2、黑白模式:ColorMode.PANDA,画面为黑白
getMode int - - 获取颜色模式

表5-62 ColorModeListener说明

方法 返回值 参数 参数类型 说明
onColorModeResult void success boolean 设置结果,true成功,false失败
message String 设置失败信息

示例代码:

public class PlayerActivity extends Activity implements HmcpPlayerListener, ColorModeListener {

    private HmcpVideoView mHmcpVideoView;
    private Switch pandaModeSwitch;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mHmcpVideoView = (HmcpVideoView) findViewById(R.id.hmcp_view);
        pandaModeSwitch = (Switch) v.findViewById(R.id.panda_mode_switch);
        pandaModeSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
            ColorMode colorMode;
            if (isChecked) {//开启黑白模式
                colorMode = new ColorMode(ColorMode.PANDA);
            } else {//关闭黑白模式
                colorMode = new ColorMode(ColorMode.NORMAL);
            }
            mHmcpVideoView.setColorMode(colorMode, (success, message) -> {
                String msg = success ? "成功" : "失败";
                Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
            });
        });
    }

}

5.47 游戏保活接口

云玩过程中可以调用HmcpVideoView.requestKeepAlive申请游戏实例保活。

函数原型:

public class HmcpVideoView {
  //申请游戏保活
    public void requestKeepAlive(long timeBySeconds, OnRequestAliveListener listener);
  //取消游戏保活
  public void requestStopKeepAlive(OnRequestAliveListener listener);
}

表5-63 参数说明

参数 类型 说明
timeBySeconds long 保活时间,单位:s,有效区间[60,86400]
listener OnRequestAliveListener 设置结果回调,参见[表5-64 OnRequestAliveListener](#表5-64 OnRequestAliveListener)

表5-64 OnRequestAliveListener说明

方法 返回值 参数 参数类型 说明
onRequestAliveResult void success boolean 申请保活结果,true成功,false失败
message String 设置失败信息
onStopAliveResult void success boolean 取消保活结果,true成功,false失败
message String 设置失败信息
onKeepAliveTimeUp void - - 保活时间耗尽通知回调

示例代码:

public void requestKeepAlive(View view) {
        int time  = Integer.parseInt(keepAliveTime.getText().toString().trim());
        hmcpVideoView.requestKeepAlive(time, new OnRequestAliveListener() {
            @Override
            public void onRequestAliveResult(boolean success, String msg) {
                LogUtils.d(TAG, "onRequestAliveResult:" + success + "--" + msg);
            }
            @Override
            public void onStopAliveResult(boolean success, String msg) {
                LogUtils.d(TAG, "onStopAliveResult:" + success + "--" + msg);
            }
            @Override
            public void onKeepAliveTimeUp() {
                LogUtils.d(TAG, "KeepAliveTimeUp");
            }
        });
    }

public void requestStopKeepAlive(View view) {
        hmcpVideoView.requestStopKeepAlive( new OnRequestAliveListener() {
            @Override
            public void onRequestAliveResult(boolean success, String msg) {
                LogUtils.d(TAG, "onRequestAliveResult:" + success + "--" + msg);
            }
            @Override
            public void onStopAliveResult(boolean success, String msg) {
                LogUtils.d(TAG, "onStopAliveResult:" + success + "--" + msg);
            }
            @Override
            public void onKeepAliveTimeUp() {
                LogUtils.d(TAG, "KeepAliveTimeUp");
            }
        });
    }

5.48 重启实例内游戏接口

云玩过程中可以调用HmcpVideoView.relaunchGame申请重启实例内游戏。

函数原型:

public class HmcpVideoView {
  //申请重启实例内游戏
  public void relaunchGame(OnRelaunchGameListener listener);
}

表5-65 参数说明

参数 类型 说明
listener OnRelaunchGameListener 设置结果回调,参见[表5-66 OnRelaunchGameListener](#表5-66 OnRelaunchGameListener)

表5-66 OnRelaunchGameListener说明

方法 返回值 参数 参数类型 说明
success void success boolean 申请重启实例内游戏结果,true成功,false失败
fail void message String 申请重启实例内游戏失败,message为具体失败原因

示例代码:

public void relauncGame(View view) {
        hmcpVideoView.relaunchGame(new OnRelaunchGameListener() {
            @Override
            public void success(boolean success) {
                LogUtils.d(TAG, "onRelaunchGameResult:" + success);
            }
            @Override
            public void fail(String message) {
                LogUtils.d(TAG, "onRelaunchGameResult:failed! Message:" + "--" + message);
            }
        });
    }

5.49 申请实例录屏接口

函数原型:

public class HmcpVideoView {
  //申请实例录屏
  public void startRecordStream(StartRecordStreamListener listener);
  //结束实例录屏
  public void stopRecordStream(StopRecordStreamListener listener);
}

表5-67 参数说明

参数 类型 说明
listener StartRecordStreamListener 申请录屏结果回调
listener StopRecordStreamListener 结束录屏结果回调

表5-68 StartRecordStreamListener说明

方法 返回值 参数 参数类型 说明
startRecord void success boolean 申请录屏结果,true成功,false失败
message String 申请失败信息

表5-69 StopRecordStreamListener说明

方法 返回值 参数 参数类型 说明
stopRecord void success boolean 结束录屏结果,true成功,false失败
message String 结束失败信息
info RecordStreamInfo 录屏文件信息

表5-70 RecordStreamInfo数据结构说明

参数 类型 必填项 说明
filePath String 录屏文件在实例内的完整路径

示例代码:

public void startRecordStream(View view) {
        hmcpVideoView.startRecordStream(new StartRecordStreamListener() {
            @Override
            public void startRecord(boolean success, String msg) {   
            }
        });
}

public void stopRecordStream(View view) {
        hmcpVideoView.stopRecordStream(new StopRecordStreamListener() {
            @Override
            public void stopRecord(boolean success, String msg, RecordStreamInfo info) {
             LogUtils.d(TAG, "stopRecordStream:" + success + "--" + msg + "---" + info);
            }
        });
}    

5.50 获取流地址IP回调接口

函数原型:

public class HmcpVideoView {
  //获取流地址IP回调
  public void setHmStreamerIPCallback(HmStreamerIPCallback callback);
}

表5-71 参数说明

参数 类型 说明
callback HmStreamerIPCallback 获取流地址IP结果回调

表5-72 HmStreamerIPCallback说明

方法 返回值 参数 参数类型 说明
onConnectionIPChanged void ipList org.json.JSONObject 获取流地址IP回调结果,JSON数据结构如下:
{ ipList:[
{
ip:"222.208.103.17:9122",
ipFormat:0, // IP格式:0-IPV4;1-IPV6
ipPriority:1 // IP优先级:0-当前主IP;1-备用IP
} ,
{
ip:"[2001:db8:3c4d:15::1a2f:1a2b]:5678",
ipFormat:1, // IP格式:0-IPV4;1-IPV6
ipPriority:1 // IP优先级:0-当前主IP;1-备用IP
}
]
}

5.51 双通道网络接口

函数原型:

public class HmcpVideoView {
  //连接加速通道
  public void connectAccProxy(String proxyHost, int proxyPort, String userInfo, String passwd);
  //断开加速通道
  public void disconnectAccProxy();
}

表5-73 参数说明

参数 类型 说明
proxyHost String acc代理服务ip,默认值(127.0.0.1)
proxyPort int acc代理端口
userInfo String 认证用户(非必填参数)
passwd String 认证密码(非必填参数)

示例代码:

/**
 * 开启网络加速
 **/
AccClient.getInstance(getApplicationContext()).setStausCallback(new AccStatusCallbcak() {
       /**
        * 加速启动成功,proxyPort就是加速成功的本地端口号
        **/
       @Override
       public void onAccSucess(int proxyPort, String ip, int port) {
            hmcpVideoView.connectAccProxy("127.0.0.1", proxyPort, "", "");
       }
       @Override
       public void onAccExit(int code, String reson) {
            AccClient.getInstance(getApplicationContext()).stopMeasure();
            AccClient.getInstance(getApplicationContext()).stopAcc();
       }
}

AccClient.getInstance(getApplicationContext()).startAcc();



/**
 * 关闭网络加速
 **/
public void stopAcc(View view) {
     AccClient.getInstance(getApplicationContext()).stopAcc();
     hmcpVideoView.disconnectAccProxy();
 }

5.52 双通道网络回调接口

实现HmcpPlayerListener接口后,在该接口的onAccProxyConnectStateChange()函数中可以收到通道连接状态。

函数原型:

public interface HmcpPlayerListener {
  void onAccProxyConnectStateChange(int connectState)
}

表5-74 connectState参数介绍

参数 类型 必填项 说明
connectState int 0:表示连接通道成功
-1:表示断开通道
>0:表示连接报错的错误码

5.53 切换移动网络接口

函数原型:

public class HmcpVideoView {
  //切换移动网络通道
  void switchMobileNetworkTransport(boolean turnOn)
}

表5-75 turnOn参数介绍

参数 类型 必填项 说明
turnOn boolean true:表示打开移动网络通道
false:表示关闭移动网络通道

5.54 切换移动网络回调接口

实现HmcpPlayerListener接口后,在该接口的onSwitchConnectionCallback()函数中可以收到切换移动网络状态。

函数原型:

public interface HmcpPlayerListener {
  void onSwitchConnectionCallback(int statusCode, int networkType)
}

表5-76 statusCode参数介绍

参数 类型 必填项 说明
statusCode int 0:表示切换移动网络通道成功
1:表示当前检测已经是移动网络
-1:表示当前未检测到移动网络
10:表示当前使用的网络类型

表5-77 networkType参数介绍

参数 类型 必填项 说明
networkType int 0:Unknown未知类型
3:Wifi网络类型
5:Cellular蜂窝网络类型

6 场景说明

6.1 排队管理

排队管理的触发条件:接入方所购买云服务实例和并发数达到上限。

处理机制:

  1. onSceneChanged接收到需要排队提示。

  2. HmcpPlayerStatusCallback接收到status = STATUS_WAIT_CHOOSE状态回调:多优先级用户排队参数增加说明

    onSceneChanged ==> {"sceneId":"needWait"}
    // 收到排队消息
    "status":7
    "data":{"message":"您当前排在第1位,当前队列总共排队1人,是否继续?","time":"300","index":"1",
     "waitTotalNum":"2",
     "queues":[{"index":1,"priorities":[0,1],"rank":0,"time":"300","timeStr":"5分钟"},
               {"index":0,"priorities":[2],"rank":1,"time":"0","timeStr":"00:00"}]}
  3. 调用开启排队videoView.entryQueue(),然后会接收到status = STATUS_OPERATION_INTERVAL_TIME状态回调信息。

    // 排队状态更新,返回该所有队列的排队信息
    status:13 
    "data":{"message":"排队中,您当前排在第q位, 当前队列总共排队2人,预计还需要5分钟",,"time":"300",
     "index":"1","waitTotalNum":"2"
     "queues":[{"index":1,"priorities":[0,1],"rank":0,"time":"3","timeStr":"3秒"},
               {"index":0,"priorities":[2],"rank":1,"time":"0","timeStr":"00:00"}]}
  4. 在海马云游戏管理平台进行配置禁止排队,则返回排队信息如下:

    status:10 
    Data:{"message":"当前游戏太过火爆,请您稍后再试",
          "queues":[{"index":1,"priorities":[0,1],"rank":0,"time":"300","timeStr":"5分钟"},
                    {"index":0,"prioritie":[2],"rank":1,"time":"0","timeStr":"00:00"}]}
  5. 调用取消排队ideoView.exitQueue()并直接退出游戏。

6.2 横竖屏切换

SaaS SDK提供动态切换横竖屏游戏画面功能。客户端通过SDK提供的接口,传入指定游戏横竖屏标识参数。

申请服务的时候传入orientation字段,可以控制游戏画面横竖屏显示。

设置横屏:

bundle.putSerializable(HmcpVideoView.ORIENTATION, ScreenOrientationLANDSCAPE);

设置竖屏:

bundle.putSerializable(HmcpVideoView.ORIENTATION, ScreenOrientation.PORTRAIT);

6.3 清晰度切换

  1. 在海马云游戏管理平台进行配置游戏的清晰度参数(高清、超清、流畅)。

  2. 调用开始游戏后,如果成功会有sceneId = “play”的场景回调。

    onSceneChanged ===> {"extraInfo":{"cur_rate":"200"},"sceneId":"play"}
  3. SDK调用HmcpManager.getInstance().getResolutionDatas()获取当前游戏的清晰度列表;

    "resolution":[          {"bitRate":"9600000","defaultChoice":"0","frameRate":60,"id":"4","name":"1080P","resolution":"1920x1080"},
      {"bitRate":"4000000","defaultChoice":"0","frameRate":60,"id":"2","name":"标清","resolution":"960x540"},
      {"bitRate":"3200000","defaultChoice":"1","frameRate":60,"id":"3","name":"高清","resolution":"1280x720"},
      {"bitRate":"2400000","defaultChoice":"0","frameRate":60,"id":"1","name":"流畅","resolution":"848x480"}
    ]
  4. 监听回调函数onSceneChanged并收到sceneId=”crtp”消息:

    onSceneChanged ===> {"extraInfo": {"delay_less_minimum":"0","minimum":0},"sceneId":"crtp"}

    表6-1 清晰度切换返回值说明

    返回值 类型 说明
    delay_less_minimum String 当前码率是否是最低码率。
    0:表示否
    1:表示是
    minimum int 当前码率是否低于下限。
    0:表示否
    1:表示是
  5. 开始切换码率:

    // 发起切换码率
    recordSceneEvent ===> crst{"des":"1024","method":0,"source":"50000"}
    // 切换码率时回调
    onSceneChanged ===> 
    {"extraInfo":{"des":"1024","method":0,"source":"50000"},"sceneId":"crst"}

    表6-2 参数说明

    参数 类型 必填项 说明
    method int 切换码率模式。
    0:表示手动切换码率
    1:表示自动切换码率
    des String 目标码率 ID
    • 如果手动调用onSwitchResolution()切换码率。
    • onSceneChanged接收到切换码率的消息回调scenedId = “crst”。
  6. onSceneChanged收到scenedId = “cred”切换码率后结果:

    recordSceneEvent ===> cred {"cur_rate":"500","result":1}

    表6-3 返回结果说明

    返回结果 类型 说明
    cur_rate String 当前码率是否是最低码率。
    0:表示否
    1:表示是
    result int 0:表示失败
    1:表示成功

7 数据结构定义

7.1 场景切换回调

游戏过程中的各个状态切换都会通过onSceneChanged(String sceneMessage)接口通知应用,sceneMessage字符串是有Json串转换的,格式如下:

{ 
  // 切换到的场景ID
  "sceneId": "" ,
  // 场景切换的扩展信息,参考sceneId说明
  "extraInfo" {} , 
}

表7-1 游戏过程中各状态的sceneId说明

sceneId extraInfo{} 备注
init 初始化中,extraInfo为空
wait 排队中,extraInfo为空
play 开始游戏,extraInfo为空
stop 游戏结束,extraInfo参考参数示例
mait 云玩维护,extraInfo参考参数示例
crtp 显示自动降低码率tips,extraInfo 参考参数示例
crst 开始切换码率(当前码率,目标码率,自动手动模式),extraInfo参考参数示例
cred 切换码率完成(成功,失败,当前码率),extraInfo参考参数示例
firstFrameArrival 拿到游戏视频第一帧
exchangeControlSuccess 控制权互换成功 调用控制权互换接口,触发场景之一
exchangeControlRestoreSuccess 控制权互换还原成功 调用控制权互换接口,触发场景之一
exchangeControlFail 控制权互换失败,该状态下会维持原状态继续播流 调用控制权互换接口,触发场景之一
exchangeControlRestoreFail 控制权互换还原失败,该状态下会维持原状态继续播流 调用控制权互换接口,触发场景之一
exchangeControlOtherError 控制权互换数据异常,该状态下会维持原状态继续播流 调用控制权互换接口,触发场景之一

以下是游戏过程中各状态对应的扩展信息extraInfo{}描述:

  • stop : 游戏结束。

    "extraInfo": {
        "interval": 10 // 当次游戏时长,单位 秒
        "reason": "" // 游戏结束原因
        // "time_limit"    :当次游戏事件到
        // "no_operation"  :超时无操作
        // "instance_err"  :实例出错
        // "forced"        :强制下线
        // "token_expire"  :Token失效
        // "log_off"       :游戏内注销
        // "network_off"   :网络不可用
        // "request_err"   :网络请求出错
    }
  • mait : 云游戏维护。

    "extraInfo": {
        "progress": "" // 云游戏维护进度
        // "soon" :即将,
        // "start":进入,
        // "done" :恢复
    }
  • crtp : 显示自动降低码率 tips。

    "extraInfo": {
        "minimum": "" // 当前码率是否最低码率
        // "0":否 
        // "1":是
    }
  • crst: 开始切换码率(当前码率、目标码率、自动手动模式)。

    "extraInfo" : {
        "source" : "当前码率" ,
        "des"    : "目标码率" ,
        "method" : "" // 自动手动模式 "0":手动 "1":自动
    }
  • cred : 切换码率完成 (成功,失败,当前码率)。

    "extraInfo" : {
        // "0":失败 "1":成功
        "result"   : 0,
        // 当前码率 
        "cur_rate" : 1
    }
  • exchangeControlSuccess:控制权互换成功,extraInfo为空。

  • exchangeControlRestoreSuccess:控制权互换还原成功,extraInfo为空。

  • exchangeControlFail:控制权互换失败,extraInfo为空。

  • exchangeControlRestoreFail:控制权互换还原失败,extraInfo为空。

  • exchangeControlOtherError:控制权互换数据异常,extraInfo为空。

7.2 消息回调

public void onMessage(Message message){}

Message类的定义如下:

public class Message implements Serializable {
    public static final int ACK_CLIENT_SEND = 0;
    public static final int TYPE_PAY_MESSAGE = 1;
    public static final int TYPE_SYSTEM_MESSAGE = 2;
    public static final int TYPE_AD_MESSAGE = 3;
    public static final int TYPE_INTERACTIVE_MESSAGE = 4;
    // 目标接收者cid,全部推送"ALL"
    public String to; 
    // 消息ID
    public String mid; 
    // 消息内容
    public String payload; 
    // 发送者,系统消息="System"
    public String from;  
    // 消息类型,默认是传 1
    public int type;     
    // 客户端发送默认为0;服务端收到回复为1
    public int ack;     
    // 可选参数,目标uid
    public String UID;    
    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}

表7-2 消息回调参数说明

参数 类型 必填项 说明
uid String 可选参数,目标uid
from String 消息发送方标识
to String 消息接收方标识
mid String 消息id
type Integer 消息类型,固定值为 1
ack Integer 固定值为0
payload String 消息内容

7.3 SDK状态回调

SDK的各个状态切换和sever下发通知都会通过HmcpPlayerStatusCallback(String callback)接口通知应用,callback字符串是有 JSON 串转换的,格式如下:

{
    // 切换到的场景ID
    "status": "" , 
    // 扩展信息
    "data" {} ,         
}

表7-3 状态说明

状态值 说明 扩展数据 使用建议
STATUS_PLAY_INTERNAL = 1 开始请求游戏 必须处理回调,调用play()方法
STATUS_START_PLAY = 2 开始播流 非必须处理回调
STATUS_STOP_PLAY = 3 停止播放 非必须处理回调
STATUS_TIPS_CHANGE_4G_TO_WIFI = 4 4g切换到wifi 非必须处理回调
STATUS_TIPS_CHANGE_WIFI_TO_4G = 5 Wifi切换到4g 配置的弹框话术 必须处理回调,调用reconnection()方法
STATUS_NETWORK_UNAVAILABLE = 6 网络断开 配置的弹框话术 非必须处理回调
STATUS_WAIT_CHOOSE = 7 需要排队 返回数据参照多优先级用户排队参数增加说明 必须处理回调,弹窗提示用户是否确认排队;排队调用entryQueue()方法,不排队调用exitQueue()方法
STATUS_START_RECONNECTION = 8 开始重新连接 非必须处理回调
STATUS_CONNECTION_ERROR = 9 重连失败 配置的弹框话术 必须处理回调,云游戏结束
STATUS_OPERATION_REFUSE_QUEUE = 10 排队人数过多 返回数据参照多优先级用户排队参数增加说明 必须处理回调,云游戏结束
STATUS_TOAST_NO_INPUT = 11 无操作时间超过配置 {“errorCode”:””,”errorCodeWithoutCid”:””,
“errorMessage”:””,”status”:””}
必须处理回调,云游戏结束
STATUS_OPERATION_INTERVAL_TIME = 13 进入队列消息 返回数据参照多优先级用户排队参数增加说明 非必须处理回调,提示用户排队进度
STATUS_OPERATION_STREAM_URL = 14 获取流地址成功 {“currentNetType”:””,
“currentApkType”:””}
非必须处理回调
STATUS_OPERATION_GAME_OVER = 15 游戏时间到 {“errorMessage”:””,
“finishByServer”:””,
“finishTip”:””}
必须处理回调,云游戏结束
STATUS_OPERATION_WAITING = 16 排队完成消息 配置的弹框话术 非必须处理回调
STATUS_OPERATION_READY_PAUSE_SAAS_SERVER=17 服务准备维护 {“errorMessage”:””} 非必须处理回调
STATUS_OPERATION_PAUSE_SAAS_SERVER = 18 服务器开始维护 {“errorMessage”:””} 必须处理回调,云游戏结束
STATUS_OPERATION_PAUSED_SAAS_SERVER = 19 服务维护中 配置的弹框话术 必须处理回调,云游戏结束
STATUS_SWITCH_RESOLUTION = 20 切换清晰度 {“defaultChoiceId”:””,
“switchResolution”:””}
非必须处理回调,可以获取当前推流参数
STATUS_SWITCH_RESOLUTION_ERROR = 21 切换清晰度失败 非必须处理回调
STATUS_MEDIAPLAYER_ERROR = 22 播放器创建失败 已经废弃
STATUS_TIME_OUT = 23 获取流地址超时 {“errorCode”:””,”errorCodeWithoutCid”:””,
“errorMessage”:””,”status”:””,”rootCause”}
必须处理回调,云游戏结束
STATUS_OPERATION_FORCED_OFFLINE = 24 Tocken过期服务终止 {“errorCode”:””,”errorCodeWithoutCid”:””,
“errorMessage”:””,”status”:””}
必须处理回调,云游戏结束
TATUS_AUTO_SWITCH_RESOLUTION = 25 自动切换清晰度 {“mCurrentSpeed”:””
“mMinResolutionLevel”:””}
非必须处理回调
STATUS_SPEED_LOWER_BITRATE = 26 测速结果低于服务下限 配置的弹框话术 必须处理回调,云游戏结束
STATUS_OPERATION_OPEN_MORE_SAME_GAME = 27 游戏多开 {“errorCode”:””,”errorCodeWithoutCid”:””,
“errorMessage”:””,”status”:””}
必须处理回调,云游戏结束
STATUS_OPERATION_HMCP_ERROR = 29 服务连接错误 {“errorCode”:””,”errorCodeWithoutCid”:””,
“errorMessage”:””,”status”:””}
必须处理回调,云游戏结束
STATUS_OPERATION_GAME_TIME_COUNT_DOWN = 30 游戏时长提示 {“ahead”: “”,
“countDown”: “”,
“formatter”: “”}
非必须处理回调,可以提⽰⽤户剩余游戏时长
STATUS_OPERATION_GAME_TIME_UPDATE = 31 游戏内更新时长 {“tip”: “”} 非必须处理回调
STATUS_OPERATION_GAME_TIME_HIGHLIGHT = 32 游戏可玩时长提示 {“playingTime”: “”} 非必须处理回调,可以提示用户本次游戏总时长
STATUS_RECEIVE_META_INFOS = 33 获取到sever配置信息 非必须处理回调
STATUS_PAUSE_PLAY = 35 暂停播放 非必须处理回调
STATUS_OPERATION_NO_INPUT_TIME_REMIND = 36 长时间无操作提示 {“noInputRemainingTime”: “”
“message”: “”}
非必须处理回调
STATUS_GET_CONTRON_ERROR = 40 获取控制权失败 {“errorMessage”: “”} 必须处理回调,云游戏结束
STATUS_OPERATION_STATE_CHANGE_REASON = 42 接入方连接服务端结束游戏 {“stateChangeReason”: “”} 必须处理回调,云游戏结束
STATUS_IDCINFO = 44 获取IDC信息 {“AddressInfo”:{
“idcId”: “”,
“idcName”:”” }}
非必须处理回调
STATUS_DOWNLOAD_ONLY = 45 大文件断流下载中 非必须处理回调
STATUS_RECEIVE_DISTANCE = 47 获取到用户与所有路由到的机房之间最短距离 {“minDistance”:12345} 非必须处理回调,距离单位:米
STATUS_RECEIVE_KQI_DATA = 48 获取KQI数据 {“status”:48,”data”:”[{"code":0,"consumeTimeMillions":0,"type":"STORE_ARCHIVE"},{"code":0,"consumeTimeMillions":683,"type":"START_GAMES"},{"code":0,"consumeTimeMillions":145,"type":"INSTALL_WITH_NFS"}]”} 非必须处理回调
STATUS_SHOW_SETTING_VIEW = 101 (TV)菜单呼出 非必须处理回调
FIRST_FRAME_ARRIVAL = 102 第一帧动画到达 必须处理回调,开始云游戏
STATUS_SENSOR_GET_FAILURE = 301 传感器不可用 {“status”:301,”data”:”{“sensorType”:123243}”} 非必须处理回调

表7-4 返回结果说明

返回结果 类型 说明
errorCode String 发生出错误的错误码
errorMessage String 发生错误的错误说明
errorCodeWithoutCid String 发生出错误的错误码(不包含”-cid”)
rootCause String 对应请求描述
status String 错误信息状态
currentNetType String 网络类型
currentApkType String 游戏池化状态
finishByServer String 游戏时长到,是否结束游戏(服务端配置)
finishTip String 游戏时长到状态说明
defaultChoiceId String 切换分辨率ID
switchResolution String 是否为自动切换
mCurrentSpeed String 当前网络速度
mMinResolutionLevel String 配置的最低播流速度
ahead String 游戏时长提示的剩余时长
countDown String 是否为倒计时,countDown == 1 为倒计时
formatter String 游戏时长提示说明
tip String 更新游戏时长说明
playingTime String 可玩游戏时长
stateChangeReason String 接入方通过openApi退出游戏时自定义原因

7.4 关键接口回调

接入方必须设置此接口来监听云游戏过程中的状态变化,HmcpPlayerListener监听类定义如下:

public interface HmcpPlayerListener {
    /**
     * 启动游戏失败
     *
     * @param errorType 错误的类型名:NETWORK_ERROR,OTHER
     * @param errorInfo 错误的消息
     */
    void onError(ErrorType type, String errorInfo);
    /**
     * 启动游戏成功
     */
    void onSuccess();
    /**
     * 游戏退出
     * 需要在该回调内调用finish()时,退出Activity
     */
    void onExitQueue();
    /**
     * SDK内消息通知,包括支付消息等
     *
     * @param message 消息内容
     */
    void onMessage(Message message);
      /**
     * SDK游戏过程中各状态发生变化时的回调
     * 
     * @param sceneMessage是JSON结构体,包含 sceneId 和 extraInfo{}。具体详细请参考“参数说明”中的“场景切换”章节。
     */
    void onSceneChanged(String sceneMessage);
      /**
     * 监听到网络变化后的通知
     * 
     * @param state 是enum类型,包含 ISWIFI, NOTWIFI, NO_NETWORK
     */
    void onNetworkChanged(NetWorkState state);
      /**
     * @param status:状态值,可为 0、1、2    
     * @param value:
     *                status=0,value是采样周期内接受到的视频帧的总大小,单位:Byte; 
     *                status=1,value是采样周期内,渲染帧的总数;
     *                status=2,value是采样周期内,平均解码耗时,单位是ms;
     *
     * @param data:附加信息,status=0,data为采样周期内最大的N帧大小,单位为Byte;status=其他,data无数据;
     */
    void onPlayStatus(int status, long value, String data);
      /**
     * 使用状态回调接口
     * 
     * @param callback 状态信息
     */
    void HmcpPlayerStatusCallback(String callback);
      /**
     * 上报错误信息回调接口
     * 
     * @param errorCode 错误码 
     * @param errorMsg  错误信息
     */
    void onPlayerError(String errorCode, String errorMsg);
      /**
     * 上报错误信息回调接口
     * 
     * @param errorCode 错误码
     * @param errorMsg  错误信息
     */
    void onInputMessage(String message);
      /**
     * 监听到输入设备变化的通知
     * 
     * @param device 设备类型
     * @param operationType 键盘类型
     */
    void onInputDevice(int device, int operationType);
    /**
     * 没有相关敏感权限时回调
     * 
     * @param permission 权限名称(如:Manifest.permission.RECORD_AUDIO)
     */
    void onPermissionNotGranted(String permission);
    /**
     * 云游戏中远端实例状态发生改变
     * 云游戏中分享、打开摄像头、打开系统相册、游戏内截图、文件创建通知
     * 
     * @param status 状态信息,详情请参见“云游戏中远端实例状态通知”
     */
    void onCloudDeviceStatus(String status);
    /**
     * intent拦截回调
     * 
     * @param intentData 拦截数据内容,详情请参见“Intent拦截”
     */
    void onInterceptIntent(String intentData);
}

7.5 多优先级用户排队参数增加说明

SDK状态回调增加多优先级用户排队状态返回。

表7-5 状态说明

状态 status data
需要排队 STATUS_WAIT_CHOOSE=7 {“message”:”配置的弹框话术”,”time”:”等待时间,秒”,”index”:”当前位置”,”waitTotalNum”:”总人数”,”queues”:”队列消息”}
进入队列消息 STATUS_OPERATION_INTERVAL_TIME=13 {“message”:”配置的弹框话术”,”time”:”等待时间,秒”,”index”:”当前位置”,”waitTotalNum”:”总人数”,”queues”:”队列消息”}
排队人数过多 STATUS_OPERATION_REFUSE_QUEUE=10 {“message”:“配置的弹框话术” “queues”:“队列消息”}

其中具体数据格式为:

{
  "message": "配置的弹框话术",
  "time":"1分钟",
  "index":"1",
  "waitTotalNum":"2",       
  "queues": [{
       "rank": 1,
       "timeStr": "09分15秒",
       "time": "555",
       "index": 1,
       "priorities": [
         0,
         1
       ]
    },
    {
       "rank": 2,
       "timeStr": "09分15秒",
       "time": "555",
       "index": 1,
       "priorities": [
         2,
         3
       ]
    }
  ]
}

表7-6 返回值说明

返回值 类型 说明
message String 返回的配置的弹框话术
waitTotalNum int 排队总人数
queues List 队列信息
rank int 队列等级
index int 排队人数
time String 预估时间,单位为s
timeStr String “09分15秒”格式字符串
priorities List 用户优先级列表,即配置的该等级队列中包含那些优先级的用户

7.6 清晰度信息ResolutionInfo类的定义

public class ResolutionInfo implements Serializable {
    // 清晰度信息ID
    public String ID; 
    // 清晰度名称
    public String name; 
    // 清晰度,形如<width>x<height>
    public String resolution; 
    // 峰值码率,单位KB/s
    public String peakBitRate;     
    // 码率,单位为bit/s,类型为long
    public String bitRate;     
    // 帧率,类型为Integer
    public int frameRate;     
    // 是否是默认选择
    public String defaultChoice; 
    // 是否开启
    public String close;         
    public final String choiced = "1";

    @Override
    public String toString() {
        return "ResolutionInfo{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", resolution='" + resolution + '\'' +
                ", peakBitRate='" + peakBitRate + '\'' +
                ", frameRate='" + frameRate + '\'' +
                ", bitRate=' " + bitRate + '\'' +
                ", defaultChoice='" + defaultChoice + '\'' +
                ", close='" + close + '\'' +
                '}';
    }
}
  1. 调用play()接口成功会有sceneId = “play” 的场景回调,此时可调用HmcpManager.getInstance().getResolutionDatas()得到游戏的清晰度列表。

  2. 调用hmcpVideoView.onSwitchRsolution()接口后也会有场景回调。

    • 收到sceneId = “crst”的场景回调,表示开始切换清晰度。

    • 收到scenedId = ”cred”的场景回调,表示切换清晰度完成。

    extraInfo.cur_rate表示切换成功后的码率peakBitRate。

    • extraInfo.result = 0表示切换失败。

    • extraInfo.result = 1表示切换成功。

另外如果开启了自动切换码率,网络卡顿时会收到sceneId = ”crtp”的场景回调,该场景回调下:

  • extraInfo.minimum=1表示当前为最低码率。
  • extraInfo.minimum=0表示当前不是最低码率,这种情况下启动切换码率后会收到 scenedId = ”cred”的场景回调,需要APP更新当前清晰度。

场景回调的参数详情请参见场景切换回调

8 注意事项

8.1 安卓6.0+系统需要申请权限

​ 申请权限代码如下:

private void requestCloudSdkPermission() {
    if (Build.VERSION.SDK_INT >= 23 && 
        ContextCompat.checkSelfPermission(this,Manifest.permission.READ_PHONE_STATE) 
        != PackageManager.PERMISSION_GRANTED) {
      String[] mPermissionList = new String[]{Manifest.permission.READ_PHONE_STATE};
      ActivityCompat.requestPermissions(CloudPlayActivity.this, mPermissionList, 100);
    } else {
        // 不需要权限
    }
}

8.2 虚拟导航栏兼容性设置问题

部分存在虚拟导航栏的手机会存在点击游戏画面错位现象,需要设置虚拟导航栏兼容性代码,添加如下代码即可:

/**
 ** 设置VideoView的触摸监听事件
 */
hmcpVideoView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int eventAction = event.getAction();
        switch (eventAction) {
            // 按下动作
            case MotionEvent.ACTION_DOWN:
                Log.e("MainActivity", "down");
                hideNavigationBar();
                break;
            // 移动
            case MotionEvent.ACTION_MOVE:
                Log.e("MainActivity", "move");
                break;
            // 抬起动作
            case MotionEvent.ACTION_UP:
                Log.e("MainActivity", "up");
                break;
        }
        return false;
    }
});

其中依赖的方法如下:

/**
* 隐藏导航栏
*/
private void hideNavigationBar(){
    boolean isHas = hasNavigationBar(getApplicationContext());
    if (isHas) {
        // 此处需要根据系统版本做兼容处理
        if ((Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB)) {
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_IMMERSIVE);
        }
    }
}

/**
 * 是否有底部导航条
 */
public static boolean hasNavigationBar(Context context) {
    boolean hasMenuKey = true, hasBackKey = true;
    boolean ret = false;
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
            hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
        }
        if ((!hasMenuKey) && (!hasBackKey)) {
            ret = true;
        }
    } catch (Exception e) {
        ret = false;
    }
    return ret;
}

8.3 全屏沉浸式效果

推荐设置游戏界面为全屏沉浸式效果,在onCreate()方法中添加如下代码:

public static boolean setTranslucentStatus(Activity activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && 
    Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { 
        // 4.4以上,状态栏透明
       activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        return true;
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // 5.0以上状态栏透明
        Window window = activity.getWindow();
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(Color.TRANSPARENT);
        return true;
    }
    return false;
}

8.4 一个登录账号开启多个游戏的场景

登录账号在设置用户登录信息中已经提到设置方法,其设置的登录账号可以在一个终端上同时打开多个窗口或者同时在多个终端上打开多个窗口,但是打开窗口的个数有限制。该个数限制由海马云server配置。现在的限制如下:

  • 一个账号可以打开同一款游戏的个数限制为2。
  • 一个账号可以打开多款游戏的个数限制为5。

如果超过上限,游戏就不能正常开始,SDK会有相应的提示信息。

8.5 保存上次使用的清晰度

记录用户上次使用的清晰度,下次使用该清晰度播流。

用户使用的清晰度会有场景切换的回调,详情请参见场景切换回调。回调传入的字符串中”cur_rate”表示当前使用的码率,单位为kB/s。在下次启动播流时把改值设置为HmcpVideoView.INTERNET_SPEED传入SDK即可用该码率波流。详情请参见申请服务

×

本篇文章对你是否有帮助?

更多建议

请输入您的建议