iOS - 網易雲信(天天狼人殺誰上麥誰音視訊,多人視訊)

weixin_34402408發表於2017-04-09

注:由於個人版本構建不同,所以備註程式碼和方案不同!

第一.多方視訊(自己整合NIMSDK和註冊網易雲信賬號)

0.匯入標頭檔案 //多人視訊
        #import <NIMSDK>
        #import <NIMAVChat>
        #import "UnityFunction.h"

1.註冊SDK(appKey 和 cerName根據自己賬號填寫,自己匯入標頭檔案)

        NSString *appKey = @"a543326452XXX285fd196b19524e0c55";
        NSString *cerName = @"https://app.nXXXase.im/api";
        [[NIMSDK sharedSDK] registerWithAppID:appKey cerName:cerName];

2.註冊網易雲信伺服器(token自己定義 和安卓統一,否則無法互通音視訊)(註冊和登入方法是另行封裝的)

      注:  #define Password @"NIMSDK/NIMSDK_User_PassWord"

    - (void)regist:(NSString*)account result:(LoginRegist)result {
    
        NSDictionary *params =@{@"accid":account,
                                @"props":@"",
                                @"token":Password,
                                @"icon":@""};
        [[NIMServerAPI sharedAPI] request:@"https://api.netease.im/nimserver/user/create.action" params:params completion:^(NSError *error, NSDictionary *resultDict) {
            self.result = result;
            if (error) {
                _result(@"註冊失敗", error.code);
            } else {
                _result(@"註冊成功", 200);
            }
        }];
    }

3.登入(token自己定義 和安卓統一,否則無法互通音視訊)

      - (void)login:(NSString*)account result:(LoginRegist)result {
        [[[NIMSDK sharedSDK] loginManager] login:account token:Password completion:^(NSError *error) {
            self.result = result;
            if (error) {
                _result(@"登入失敗", error.code);
            } else {
                _result(@"登入成功", 200);
               // if (_userInfo) {
                 //   _userInfo.userID =account;
                 //   _userInfo->userPswd =Password;
                }
    //            [_userInfo saveCurrentAccount];
            }
        }];
    }

4.建立音視訊和代理,建立meeting

    //音視訊相關
    - (void)createVideoAndAudio {
        NIMNetCallMeeting *meeting = [[NIMNetCallMeeting alloc] init];
        meeting.name = _roomModel.number;
        if (![[NIMSDK sharedSDK].loginManager isLogined]) {
            NSLog(@"當前登入使用者ID:%@",_currentUserID);
            [[LoginOrRegist shareUserInfo]regist:_currentUserID result:^(NSString *message, NSInteger code) {
                [[LoginOrRegist shareUserInfo] login:_currentUserID result:^(NSString *message, NSInteger code) {
                    if (code == 200) {
                        NSLog(@"登入成功,進入房間");
                        [self joinNetCallWithRMeeting:meeting];
                    } else {
                        NSLog(@"登入失敗原因%ld",(long)code);
                    }
                }];
            }];
        } else {
            NSLog(@"使用者已經登入, 無需再登入, 正加入房間");
            [self joinNetCallWithRMeeting:meeting];
        }
    }

5.預約會議相關方法(注:UnityFunction方法是封裝的是傳給U3D的訊息,可忽視)

    - (void)reserveMeetingWithRoomId:(NSString *)roomId{
        NIMNetCallMeeting *meeting = [[NIMNetCallMeeting alloc] init];
        meeting.name = roomId;
        meeting.type = NIMNetCallMediaTypeVideo;
        meeting.ext = @"哈哈哈哈";
        meeting.actor = NO;
        
        [[NIMAVChatSDK sharedSDK].netCallManager reserveMeeting:meeting completion:^(NIMNetCallMeeting * _Nonnull meeting, NSError * _Nonnull error) {
            if (!error) {
    //            [UnityFunction sendUnityMessage:0 function:UnityMessageCreateRoomResult error:meeting.name];
                NSLog(@"預定成功 ,進入房間");
                [self joinNetCallWithRMeeting:meeting];
            } else {
                if (error.code == 417) {
    //                [UnityFunction sendUnityMessage:417 function:UnityMessageCreateRoomResult error:@"該房間已存在"];
                    [self joinNetCallWithRMeeting:meeting];
                } else {
    //                [UnityFunction sendUnityMessage:(int)error.code function:UnityMessageCreateRoomResult error:error.domain];
                    NSLog(@"預定房間失敗");
                }
            }
        }];
    }

6.加入會議相關方法(PermissionTool方法是獨自封裝的相機許可權、麥克風許可權等手動方法,可刪除不管)

    - (void)joinNetCallWithRMeeting:(NIMNetCallMeeting *)rMeeting {
        [PermissionTool getCamerasPermission:^(NSInteger authStatus) {
            if (authStatus ==1) {
                [PermissionTool getMicrophonePermission:^(NSInteger authStatus) {
                    if (authStatus == 1) {
                        NIMNetCallOption *callOption =[[NIMNetCallOption alloc]init];
                        // 傳送視訊質量(SDK會處理 有可能無效)
                        callOption.preferredVideoQuality =NIMNetCallVideoQualityDefault;
                        // 禁止剪裁
                        callOption.disableVideoCropping =NO;
                        // 自動旋轉遠端畫面
                        callOption.autoRotateRemoteVideo =YES;
                        // 期望的視訊編碼器
                        callOption.preferredVideoEncoder =NIMNetCallVideoCodecDefault;
                        // 期望的視訊解碼器
                        callOption.preferredVideoDecoder =NIMNetCallVideoCodecDefault;
                        // 是否使用後置攝像頭
                        callOption.startWithBackCamera =NO;
                        // 啟用互動直播
                        callOption.enableBypassStreaming =YES;
                        // 互動直播推流地址
                        callOption.bypassStreamingUrl =nil;
                        // 是否在伺服器錄製音訊
                        callOption.serverRecordAudio =YES;
                        callOption.autoDeactivateAudioSession = NO;
                        // 是否在伺服器錄製視訊
                        callOption.serverRecordVideo =YES;
                        
                        // 加入會議的型別->音訊/視訊
                        rMeeting.type =NIMNetCallMediaTypeVideo;
                        // 是否傳送音視訊資料
                        rMeeting.actor = YES;
                        // 網路電話配置
                        rMeeting.option = callOption;
                        //進入房間聊天
                        [[NIMAVChatSDK sharedSDK].netCallManager joinMeeting:rMeeting completion:^(NIMNetCallMeeting * _Nonnull meeting, NSError * _Nonnull error) {
                            if (!error) {
                                NSLog(@"進入成功");
                                //預設關閉所有人視訊
                                [[NIMAVChatSDK sharedSDK].netCallManager setCameraDisable:YES];
                                [[NIMAVChatSDK sharedSDK].netCallManager setMute:YES];
                            } else {
                                NSLog(@"進入失敗");
                                [self reserveMeetingWithRoomId:_roomModel.number];
                            }
                        }];
                    } else {
                        NSLog(@"使用者拒絕訪問麥克風");
                    }
                }];
            } else {
                NSLog(@"使用者拒絕訪問攝像頭");
            }
        }];
    }
    
    **注:終點標註兩個屬性 **
            第一:callOption.autoDeactivateAudioSession = NO; 這個屬性是控制 “結束網路通話時自動停止AudioSession” 用的;做遊戲介面,由於需要進入主頁面有背景音樂,然後進入到遊戲房間需要停止背景音樂,並在中途插入類似狼人殺的法官語音,退出後由於退出meeting會議,背景音樂消失,這個時候想讓主頁的背景音樂響起來就需要設定這個屬性為NO!(我的理解是這個屬性控制了音訊相關控制裝置,預設為佔用狀態)
            第二:rMeeting.actor = YES; meeting的這個actor屬性是設定旁觀者模式或者說是音視訊顯示主角;actor設定成YES的話,預設進入meeting後會自動對進入房間所有人進行拉流和推流,產生流量使用,並且開啟所有人的攝像頭和麥克風,適用於雙人視訊;如果想做類似於輪到誰誰音視訊開啟這種,需要預設設定actor為YES,並關閉攝像頭和麥克風
             [[NIMAVChatSDK sharedSDK].netCallManager setCameraDisable:YES];
             [[NIMAVChatSDK sharedSDK].netCallManager setMute:YES];

7.離開會議

    - (void)MSUNetCallManagerLeaveMeeting {
        NIMNetCallMeeting *meeting = [[NIMNetCallMeeting alloc] init];
        meeting.name = _roomModel.number;
        [[NIMAVChatSDK sharedSDK].netCallManager leaveMeeting:meeting];
    }

8.代理方法(NIMNetCallManagerDelegate代理遵循)
    
    // 遠端視訊圖層(屬性相關)
    @property (nonatomic, strong) NTESGLView *videoView;
    // 遠本地視訊View;
    @property (nonatomic, weak) CALayer *localLayer;

    /// 遠端視訊 (是控制遠端視訊流)
    - (void)onRemoteYUVReady:(NSData *)yuvData width:(NSUInteger)width height:(NSUInteger)height from:(NSString *)user {
        if (yuvData) {
            _videoView.hidden = NO;
            [_videoView render:yuvData width:width height:height];
        } else {
            _videoView.hidden =YES;
        }
    }
    
    /// 本地視訊 (此處是控制本地視訊流)
    - (void)onLocalPreviewReady:(CALayer *)layer {
        [self isShowLocalPreviewPeady:NO aLayer:layer];
    }
    
    - (void)isShowLocalPreviewPeady:(BOOL)isShow aLayer:(CALayer*)layer {
        if (!layer) {
            layer =_localLayer;
        }
        layer.frame =CGRectMake(0, 0, WIDTH, HEIGHT);
        _localLayer =layer;
        _localLayer.hidden =!isShow;
        [_videoView.layer addSublayer:_localLayer];
    }
    
9.ijksdl (平心而論,此處這個是最坑爹的一個,無法言喻表達:呵呵噠!)

    ijksdl屬於IJKPlayer的不常用SDK的一部分,(對於這個,呵呵噠);IJKPlayer功能不敘述了,直播必須!整合這個ijksdl是雲信中必有得,其中 NTESGLView 就是對 NTESIJKSDLGLView 的拉流封裝;
    整合:1)匯入 ijksdl資料夾(此處切記,必須將此資料夾放置工程下的第一個位置,不然會出現莫名其妙的錯誤,相對和絕對路徑混亂等錯誤);
               2)拖入檔案路徑進入 TARGETS - Build Setting - Header Seacher Paths (此處一定要注意,思密達)
3018930-23d918f2d51f95c0.png
圖片.png
               3)整合 NIMSDK時候,會出現 $(inherited) 相關資訊警告,找到三個屬性分別將$(inherited)新增進去並放置到第一個位置;

10.更改 .m檔案型別,使之可以正常使用ijksdl相關檔案和程式碼
3018930-5b83cdada7ac86d7.png
圖片.png

相關文章