# 一、Android接入流程
# 1.直播入口检测 (在登录后执行)
void liveCheckSupport() {
JSONObject jsonObject = new JSONObject();
try {
// 微信登录之后拿到的openid
jsonObject.put("openid", mOpenId);
// 游戏在微信开平注册的id
jsonObject.put("appid", mWxAppId);
// gpu型号, 可在gl线程中调用glGetString(GL_RENDERER)获取
jsonObject.put("renderer",mGpuModel);
} catch (JSONException e) {
throw new RuntimeException(e);
}
String userInfo = jsonObject.toString();
// mContext 为游戏所在的Activity对象
WXGameLiveWrapper.checkSupport(userInfo, mContext, testEnv, mLaunchFromWeChat ? 1:0,new ICheckSupportCallback() {
@Override
public void onResult(int result, String message) {
if (result == WXGameLive.LIVE_SUPPORT) {
// 初始化SDK
WXGameLiveWrapper.init(mGameName, mGameWxAppId, mIlinkAppId);
WXGameLiveWrapper.supportStartChannelLive(true);
// 显示直播入口
if (mLaunchFromWeChat) {
// 如果是从微信拉起开播的场景,此时需要拉起挂件,挂件会自动进入开播倒计时
launchLiveWidget();
mLaunchFromWeChat = false;
}
} else {
Log.i("WXGameLive", "CheckSupport result: " + result + " message: " + message);
}
}
});
}
# 2.拉起直播挂件(包含初始化,直播事件注册)
void launchLiveWidget() {
// 注册直播事件回调
WXGameLiveWrapper.setLiveEventDelegate(new ILiveEventDelegate() {
@Override
public void onRequireAuthorize(long taskId) {
//需要保存下taskId,授权同意后作为第一个参数传入authorizeFinish接口
mAuthTaskId = taskId;
// 使用MSDK 执行跳转微信完成视频号授权登录
MSDKPlatform.Login.channelPermissionAuth(MSDKChannel.WeChat, "snsapi_channels_livestream","","");
}
@Override
public void onStartChannelLive(String liveJsonInfo) {
// 使用MSDK完成跳转微信操作
MSDKFriendReqInfo reqInfo = new MSDKFriendReqInfo();
reqInfo.type = MSDKFriendReqInfo.FRIEND_REQ_WX_CHANNEL_START_LIVE;
reqInfo.extraJson = liveJsonInfo;
MSDKFriend.sendMessage(reqInfo,MSDKChannel.WeChat);
}
@Override
public void onOpenUrl(String url, int screenType, boolean isFullScreen, boolean isBrowser) {
// 使用MSDKWebView打开挂件内链接
MSDKWebView.openUrl(url,screenType,isFullScreen,true,"", isBrowser);
}
@Override
public void onStartLive(boolean isAudioPermissionGranted) {
// 开始直播回调,需要这里执行启动音频采集相关逻辑
if (isAudioPermissionGranted) {
// 已获得麦克风权限,设置GVoice的PCM回调逻辑
mVoiceEngine.invoke(4, 1, 0, null); // 启用OnRecordingData回调,务必在同意麦克风权限后调用
mVoiceEngine.SetMode(Mode.RealTime);
mVoiceEngine.EnableMultiRoom(true);
// 加入直播专用的语音房间,mLiveRoomName命名可以是前缀+时戳,确保每个房间名都是唯一的
mVoiceEngine.JoinTeamRoom(mLiveRoomName, 5000);
} else {
// 如果没有设置enableInnerAudioPermissionAuth(true), 此时需要申请麦克风权限,等用户同意麦克风权限后再调用mVoiceEngine.invoke(4, 1, 0, null)
// 如果已经设置了enableInnerAudioPermissionAuth(true),说明用于拒绝了麦克风权限,需要提示用户无法采集主播语音
}
}
@Override
public void onStopLive() {
// 结束直播回调,需要这里执行停止音频采集相关逻辑
// 停止直播时,退出GVoice语音房间
if (mAudioPermissionGranted)
{
mVoiceEngine.invoke(4, 0, 0, null); // 禁用OnRecordingData回调
mVoiceEngine.EnableRoomMicrophone(mLiveRoomName, false);
mVoiceEngine.QuitRoom(mLiveRoomName, 5000);
}
}
@Override
public void onWebViewLoaded() {
// 挂件加载完成回调
}
@Override
public void onWebViewClosed() {
// 挂件关闭回调
}
@Override
public void onToast(String msg) {
// SDK内部提示回调,游戏侧可选择弹提示框
}
@Override
public void onExtraEvent(String msgJson) {
// 其他扩展事件回调
}
});
// 拉起直播挂件
WXGameLiveWrapper.loadLiveWebView(mOpenId, mAccessToken);
}
# 3.游戏生命周期埋点
import com.tencent.wx.gamelive.WXGameLiveWrapper;
public class MainActivity {
...
@Override
public void onStart() {
...
// 可修复游戏因为失去焦点导致黑屏的问题
onWindowFocusChanged(true);
}
@Override
public void onResume() {
super.onResume();
...
WXGameLiveWrapper.onResume();
}
@Override
public void onPause() {
super.onPause();
...
WXGameLiveWrapper.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
...
WXGameLiveWrapper.onDestroy();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
...
WXGameLiveWrapper.onActivityResult(requestCode,resultCode, data);
}
@Override
public void onRequestPermissionsResult(int arg0, String[] arg1, int[] arg2)
{
super.onRequestPermissionsResult(arg0, arg1, arg2);
...
WXGameLiveWrapper.onRequestPermissionsResult(arg0, arg1, arg2);
}
@Override
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
...
WXGameLiveWrapper.onWindowFocusChanged(hasFocus);
}
}
# 4.视频采集埋点
// 以Cocos2dx引擎为例
import com.tencent.wx.gamelive.WXGameLiveWrapper;
public class Cocos2dxRenderer implements GLSurfaceView.Renderer {
...
@Override
public void onDrawFrame(final GL10 gl) {
...
WXGameLiveWrapper.onDraw();
}
}
# 5.微信拉起游戏开播
- 监听游戏被第三方应用拉起时,传递过来的参数,确认是被微信视频号拉起时,调用onMessageFromWeChat接口将相关参数传给直播SDK。
- 判断游戏是否已经登录
a. 如果已经登录,则判断当前挂件是否已经存在,如果不存在则拉起挂件,如果已经存在,则挂件会自动进入开播倒计时。
b. 如果游戏未登录,等待用户登录后,执行游戏内开播的流程。具体流程见流程图。
以MSDK为例,示例如下:
new MSDKLoginObserver() {
@Override
public void onBaseRetNotify(MSDKRet msdkRet) {
if (msdkRet.methodNameID == MSDKMethodNameID.MSDK_METHOD_CHANNEL_PERMISSION_AUTH) {
// 执行onRequireAuthorize回调之后的拿到视频号授权的票据
try {
JSONObject jsonObject = new JSONObject(msdkRet.extraJson);
String tdiAuthBufferBase64 = jsonObject.getString("tdiAuthBuffer");
byte[] tdiAuthBuffer = Base64.decode(tdiAuthBufferBase64,Base64.DEFAULT);
// 完成视频号的“一键登录”
WXGameLiveWrapper.authorizeFinish(mAuthTaskId, msdkRet.retCode, tdiAuthBuffer);
} catch (JSONException e) {
throw new RuntimeException(e);
}
} else if (msdkRet.methodNameID == MSDKMethodNameID.MSDK_METHOD_WAKEUP) {
// 游戏被微信等第三方app拉起
try {
JSONObject extraJsonObject = new JSONObject(msdkRet.extraJson);
String params = extraJsonObject.getString("params");
JSONObject paramsObject = new JSONObject(params);
mOpenId = paramsObject.getString("openid");
mMessageFromWx = paramsObject.getString("_wxappextendobject_extInfo");
if (mMessageFromWx.contains("WeChatLive_ShiPinHao")) {
mLaunchFromWeChat = true;
// 将微信的参数设置给SDK
WXGameLiveWrapper.onMessageFromWeChat(mMessageFromWx);
if (mLogined) {
// 游戏已经登录, 调用CheckSupprot
liveCheckSupport();
}
}
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
}
@Override
public void onLoginRetNotify(MSDKLoginRet msdkLoginRet) {
if (msdkLoginRet.methodNameID == MSDKMethodNameID.MSDK_METHOD_LOGIN ||
msdkLoginRet.methodNameID == MSDKMethodNameID.MSDK_METHOD_AUTOLOGIN) {
try {
JSONObject jsonObject = new JSONObject(msdkLoginRet.channelInfo);
mOpenId = jsonObject.getString("channel_openid");
mAccessToken = jsonObject.getString("access_token");
// 调用 WXGameLiveWrapper.checkSupport接口
liveCheckSupport();
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
}
};