# 一、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.微信拉起游戏开播

  1. 监听游戏被第三方应用拉起时,传递过来的参数,确认是被微信视频号拉起时,调用onMessageFromWeChat接口将相关参数传给直播SDK。
  2. 判断游戏是否已经登录
    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);
					}
				}
			}
		};

# 二、一键开播完整流程图

flow_chart