# 一、IOS接入流程
# 1.直播入口检测 (在登录后执行)
- (void)liveCheckSupport {
NSDictionary *userDic = @{@"openid":_openId,
@"appid":_wxAppId,
@"renderer":_gpuModel};
NSData *userData = [NSJSONSerialization dataWithJSONObject:userDic options:0 error:nil];
NSString *userString = [[NSString alloc] initWithData:userData encoding:NSUTF8StringEncoding];
[[WXGameLive shareInstance] checkSupport:userString testEnv:_testEnv source:(_launchFromWeChat ? 1 : 0) onSupport:^(WXCheckSupportResult result, NSString* message){
if (result == WXLiveSupport) {
// 显示直播入口
// 初始化SDK
[[WXGameLive shareInstance] initLiveWithGameName:@"游戏中文名" gameAppId:@"wx..." ilinkAppId:@"ilinkappId..." viewController: gameViewCtrl renderingApi:kRenderingAPI_xxx];
[WXGameLive shareInstance].supportStartChannelLive = YES;
if (_launchFromWeChat) {
// 如果是从微信拉起开播的场景,此时需要拉起挂件,挂件会自动进入开播倒计时
[self launchLiveWidget];
_launchFromWeChat = false;
}
} else {
NSLog(@"CheckSupport result: %ld message: %@", result, message);
}
_checkSupported = true;
}];
}
# 2.拉起直播挂件(包含初始化,直播事件注册)
-(void) launchLiveWidget {
// 注册直播事件回调
[WXGameLive shareInstance].liveEventDelegate = self; // 所在Class实现WXLiveEventDelegate
// 加载直播挂件
[[WXGameLive shareInstance] loadLiveWebViewWithUserId:_userId];
}
// WXLiveEventDelegate回调接口实现
#pragma mark WXLiveEventDelegate
- (void)onRequireAuthorize:(int)taskid {
//需要保存下taskId,授权同意后作为第一个参数传入authorizeFinish接口
_authTaskId = taskid;
// 调用MSDK的ChannelPermissionAuth接口实现跳转微信完成视频号授权
MSDKLogin::ChannelPermissionAuth(MSDKChannel.WeChat, "snsapi_channels_livestream","","")
}
- (void)onStartChannelLive:(nonnull NSString *)liveJsonInfo {
// 使用MSDK完成跳转微信操作
MSDKFriendReqInfo reqInfo = new MSDKFriendReqInfo();
reqInfo.type = kMSDKFriendReqTypeWXChannelStartLive;
reqInfo.extraJson = liveJsonInfo;
MSDKFriend::SendMessage(reqInfo,MSDKChannel.WeChat);
}
- (void)onOpenUrl:(nonnull NSString *)url screenType:(int)screenType isFullScreen:(bool)isFullScreen isBrowser:(bool)isBrowser {
// 使用MSDKWebView 打开挂件内链接
MSDKWebView::OpenUrl(url, screenType, isFullScreen, true, "", isBrowser);
}
- (void)onStartLive:(BOOL)isAudioPermissionGranted {
// 开始直播回调,需要这里执行启动音频采集相关逻辑,比如启动gvoice的pcm回调
if (isAudioPermissionGranted) {
// 已获得麦克风权限,设置GVoice的PCM回调逻辑
mVoiceEngine.invoke(4, 1, 0, null); // 启用OnRecordingData回调,务必在同意麦克风权限后调用
mVoiceEngine.SetMode(Mode.RealTime);
mVoiceEngine.EnableMultiRoom(true);
// 加入直播专用的语音房间,mLiveRoomName命名可以是前缀+时戳,确保每个房间名都是唯一的
mVoiceEngine.JoinTeamRoom(mLiveRoomName, 5000);
} else {
// 如果没有设置innerAudioPermissionAuth=true, 此时需要申请麦克风权限,等用户同意麦克风权限后再调用mVoiceEngine.invoke(4, 1, 0, null)
// 如果已经设置了EnableInnerAudioPermissionAuth(true),说明用于拒绝了麦克风权限,需要提示用户无法采集主播语音
}
}
- (void)onStopLive {
// 结束直播回调,需要这里执行停止音频采集相关逻辑,比如停止gvoice的pcm回调
if (mAudioPermissionGranted)
{
mVoiceEngine.invoke(4, 0, 0, null); // 禁用OnRecordingData回调
mVoiceEngine.EnableRoomMicrophone(mLiveRoomName, false);
mVoiceEngine.QuitRoom(mLiveRoomName, 5000);
}
}
- (void)onWebViewLoaded {
// 挂件加载完成回调
}
// 挂件关闭回调
-(void) onWebViewClosed {
// 挂件关闭回调
}
// 其他扩展事件回调
-(void) onToastWithMessage:(NSString*)message {
// SDK内部提示回调,游戏侧可选择弹提示框
}
/**
其他扩展事件回调
@param params 传递给游戏的json字串
*/
-(void) onExtraEvent:(NSString*)params {
// 其他扩展事件回调
}
# 3.游戏生命周期埋点
- (void)applicationDidEnterBackground:(UIApplication*)application
{
...
// 游戏进入后台
[[WXGameLive shareInstance] appDidEnterBackground];
}
- (void)applicationWillEnterForeground:(UIApplication*)application
{
...
// 游戏切回前台
[[WXGameLive shareInstance] appWillEnterForeground];
}
- (void)applicationWillTerminate:(UIApplication*)application
{
...
// 游戏被杀进程退出
[[WXGameLive shareInstance] uninitLive];
}
# 4.微信拉起游戏开播流程
- 监听游戏被第三方应用拉起时,传递过来的参数,确认是被微信视频号拉起时,调用onMessageFromWeChat接口将相关参数传给直播SDK。
- 判断游戏是否已经登录
a.如果已经登录,则判断当前挂件是否已经存在,如果不存在则拉起挂件,如果已经存在,则挂件会自动进入开播倒计时。
b.如果游戏未登录,等待用户登录后,执行游戏内开播的流程。与游戏内开播的区别在于,不需要校验CheckSupport 的result回包,直接执行开播的流程。具体流程见流程图。
以MSDK为例,示例如下:
// 在MSDK的登录监听中增加如下逻辑
// 登录回调,包括 login、bind、autologin、switchuser 等
void OnLoginRetNotify(const MSDKLoginRet &loginRet) {
if (loginRet.methodNameID == kMethodNameAutoLogin || loginRet.methodNameID == kMethodNameLogin) {
// 如果是微信登录的话,记录下openid和accesstoken
_openId = loginRet.channelInfo['openid'];
_accessToken = loginRet.channelInfo['access_token'];
// 登录成功后调用 CheckSupport 接口
liveCheckSupport();
}
};
// 登出回调、应用唤醒回调
void OnBaseRetNotify(const MSDKBaseRet &baseRet) {
if (baseRet.methodNameID == kMethodNameChannelPermissionAuth) {
// 执行onRequireAuthorize回调之后的拿到视频号授权的票据
// 提取baseRet.extraJson参数中“tdiAuthBuffer”字段
// 再将该字段进行一次Base64的解码后,传入authorizeFinish接口,完成视频号的“一键登录”
// 伪代码如下:
string tdiAuthString = baseRet.extraJson['tdiAuthBuffer'];
NSData* tdiAuthBuffer = Base64.decode(tdiAuthString);
[[WXGameLive shareInstance] authorizeFinish:_authTaskId errcode:baseRet.retCode tdiAuthBuffer:tdiAuthBuffer];
} else if (baseRet.methodNameID == kMethodNameWakeUp) {
// 游戏被微信等第三方app拉起
// 提取baseRet.extraJson参数中“params”字段
// 解析params字段,提取其中的“openId”,“messageExt”字段,伪代码如下:
dict params = baseRet.extraJson['params'];
_openId = params['openId'];
_messageFromWx = params['messageExt'];
// 校验是否是被视频号拉起
if (_messageFromWx.contains("WeChatLive_ShiPinHao")) {
_launchFromWeChat = true;
// 将微信的参数设置给SDK
[[WXGameLive shareInstance] onMessageFromWeChat: _messageFromWx];
if ( _isLogined) {
// 游戏已经登录, 调用CheckSupport
liveCheckSupport();
} else {
// 等待用户执行游戏登录
}
}
}
};