cordova-plugin-trtc/src/ios/VideoCallingViewController.m

342 lines
12 KiB
Objective-C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// VideoCallingViewController.m
// TRTC-API-Example-OC
//
// Created by bluedang on 2021/4/12.
//
/*
实时视频通话功能
TRTC APP 实时视频通话功能
本文件展示如何集成实时视频通话功能
1、切换摄像头 API:[[_trtcCloud getDeviceManager] switchCamera:_isFrontCamera];
2、打开关闭摄像头 API: [self.trtcCloud startLocalPreview:_isFrontCamera view:_localVideoView];
[self.trtcCloud stopLocalPreview];
3、切换听筒与扬声器 API[[_trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteEarpiece];
[[_trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteSpeakerphone];
4、静音当前设备其他人将无法听到该设备的声音 API: [_trtcCloud muteLocalAudio:YES];
参考文档https://cloud.tencent.com/document/product/647/42044
*/
/*
Real-Time Audio Call
TRTC Audio Call
This document shows how to integrate the real-time audio call feature.
1. Switch between the speaker and receiver: [[_trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteSpeakerphone]
2. Mute the device so that others wont hear the audio of the device: [_trtcCloud muteLocalAudio:YES]
3. Display other network and volume information: delegate -> onNetworkQuality, onUserVoiceVolume
Documentation: https://cloud.tencent.com/document/product/647/42046
*/
#import "VideoCallingViewController.h"
#import "TrtcUserInfo.m"
#import "CordovaEventKit.h"
#import "Toast/UIView+Toast.h"
#import "Events.h"
#import "UserUpdateListener.m"
static const NSInteger maxRemoteUserNum = 7;
@interface VideoCallingViewController ()<TRTCCloudDelegate>
@property (weak, nonatomic) IBOutlet UIButton *backButton;
@property (weak, nonatomic) IBOutlet UIButton *subVisibleButton;
@property (weak, nonatomic) IBOutlet UIButton *viewRotateButton;
@property (strong, nonatomic) IBOutletCollection(UIView) NSArray *remoteViewArr;
@property (strong, nonatomic) IBOutletCollection(UILabel) NSArray *displayLabelArr;
@property (weak, nonatomic) IBOutlet UILabel *displayLabel;
@property (assign, nonatomic) UInt32 roomId;
@property (strong, nonatomic) NSString* userId;
@property(nonatomic, assign) UInt32 sdkAppId;
@property (strong, nonatomic) NSString* userSig;
@property (strong, nonatomic) TRTCCloud *trtcCloud;
@property (strong, nonatomic) NSMutableOrderedSet *remoteUidSet;
@property (strong, nonatomic) NSMutableOrderedSet<TrtcUserInfo*> *viewUserSet;
@property (strong, nonatomic) TrtcUserInfo *sharedUser;
@property (assign, nonatomic) BOOL isFrontCamera;
@property (assign, nonatomic) NSInteger rotation;
@end
@implementation VideoCallingViewController
static VideoCallingViewController* _self;
+(VideoCallingViewController*)viewController{
return _self;
}
- (TRTCCloud*)trtcCloud {
if (!_trtcCloud) {
_trtcCloud = [TRTCCloud sharedInstance];
}
return _trtcCloud;
}
- (NSMutableOrderedSet *)remoteUidSet {
if (!_remoteUidSet) {
_remoteUidSet = [[NSMutableOrderedSet alloc] initWithCapacity:maxRemoteUserNum];
}
return _remoteUidSet;
}
- (NSMutableOrderedSet *)viewUserSet {
if (!_viewUserSet) {
_viewUserSet = [[NSMutableOrderedSet alloc] initWithCapacity:maxRemoteUserNum];
}
return _viewUserSet;
}
- (instancetype)initWithRoomId:(UInt32)roomId userId:(NSString *)userId appId:(UInt32)appId userSig:(NSString *)userSig{
NSLog(@"TRTC - initWithRoomId:::::");
self = [super initWithNibName:NSStringFromClass([self class]) bundle:nil];
if (self) {
_roomId = roomId;
_userId = userId;
_sdkAppId = appId;
_userSig = userSig;
}
NSLog(@"TRTC - roomid:%d,userID:%@,sdkAppid:%d,userSig:%@",_roomId,_userId,_sdkAppId,_userSig);
_self = self;
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.isFrontCamera = NO;
self.trtcCloud.delegate = self;
[self setupDefaultUIConfig];
[self setupTRTCCloud];
[self.view sendSubviewToBack:self.view];
}
- (void)setupDefaultUIConfig {
_displayLabel.text = @"";
_displayLabel.hidden = NO;
_rotation = 0;
[Events addListener:@"userinfo.update" listener: [UserUpdateListener init] ];
}
- (void)setupTRTCCloud {
[[self remoteUidSet] removeAllObjects];
[self.trtcCloud startLocalPreview:_isFrontCamera view:self.view];
TRTCParams *params = [TRTCParams new];
params.sdkAppId = _sdkAppId;
params.roomId = _roomId;
params.userId = _userId;
params.role = TRTCRoleAnchor;
params.userSig = _userSig;
[self.trtcCloud enterRoom:params appScene:TRTCAppSceneVideoCall];
TRTCVideoEncParam *encParams = [TRTCVideoEncParam new];
encParams.videoResolution = TRTCVideoResolution_640_360;
encParams.videoBitrate = 550;
encParams.videoFps = 15;
[self.trtcCloud setVideoEncoderParam:encParams];
[self.trtcCloud startLocalAudio:TRTCAudioQualityMusic];
}
- (void)dealloc {
[self.trtcCloud exitRoom];
[TRTCCloud destroySharedIntance];
}
#pragma mark - IBActions
- (IBAction)onSubVisibleChange:(UIButton*)sender {
NSLog(@"TRTC - onSubVisibleChange:::::");
sender.selected = !sender.selected;
[self refreshRemoteVideoViews];
}
- (IBAction)onVideoRotate:(UIButton*)sender {
NSLog(@"TRTC - onRouteChange:::::");
TRTCRenderParams *params = [[TRTCRenderParams alloc] init];
params.fillMode = TRTCVideoFillMode_Fit;
_rotation += 90;
_rotation = _rotation > 270 ? 0 : _rotation;
params.rotation = _rotation;
[_trtcCloud setRemoteRenderParams:[[self remoteUidSet][0] personid] streamType:TRTCVideoStreamTypeBig params:params];
}
- (IBAction)onBackClick:(UIButton*)sender {
NSLog(@"TRTC - onBackClick:::::");
[self.trtcCloud exitRoom];
[TRTCCloud destroySharedIntance];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)onSwitchCameraClick:(UIButton*)sender {
NSLog(@"TRTC - onSwitchCameraClick:::::");
_isFrontCamera = !_isFrontCamera;
[[_trtcCloud getDeviceManager] switchCamera:_isFrontCamera];
}
- (IBAction)onMicCaptureClick:(UIButton*)sender {
NSLog(@"TRTC - onMicCaptureClick:::::");
sender.selected = !sender.selected;
if ([sender isSelected]) {
[_trtcCloud muteLocalAudio:YES];
} else {
[_trtcCloud muteLocalAudio:NO];
}
}
- (IBAction)onSwitchSpeakerClick:(UIButton*)sender {
NSLog(@"TRTC - onSwitchSpeakerClick:::::");
sender.selected = !sender.selected;
if ([sender isSelected]) {
[[_trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteEarpiece];
} else {
[[_trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteSpeakerphone];
}
}
#pragma mark - TRTCCloud Delegate
- (void)onEnterRoom:(NSInteger) result{
NSLog(@"TRTC - onEnterRoom, %ld",result);
[_trtcCloud startLocalPreview:_isFrontCamera view:self.view];
// 添加本地用户到用户列表
TrtcUserInfo *info = [[TrtcUserInfo alloc] initWithPersonid:_userId];
[info setLocal:YES];
NSInteger index = [[self remoteUidSet] indexOfObject:info];
if (index != NSNotFound) {
return;
} else {
[[self remoteUidSet] addObject:info];
}
NSDictionary *event = [[NSDictionary alloc]initWithObjectsAndKeys:
[[NSString alloc] initWithFormat:@"%d",_roomId],@"room",_userId,@"userId", nil];
[CordovaEventKit fireEvent:@"onLayoutChangeMessage" obj:event];
}
- (void)onUserVideoAvailable:(NSString *)userId available:(BOOL)available {
NSLog(@"TRTC - onUserVideoAvailable, user:%@,available%@",userId, available ? @"YES":@"NO");
// 添加远端用户到用户列表
TrtcUserInfo *info = [[TrtcUserInfo alloc] initWithPersonid:userId];
NSInteger index = [[self remoteUidSet] indexOfObject:info];
if (available) {
if (index != NSNotFound) { return; }
if([info isShareUser]){
_sharedUser = info;
[[self remoteUidSet] setObject:info atIndex:0];
[_trtcCloud stopLocalPreview];
} else{
[[self remoteUidSet] addObject:info];
}
} else {
if (index != NSNotFound) { return; }
if([info isShareUser]){
_sharedUser = nil;
[_trtcCloud stopLocalPreview];
}
[_trtcCloud stopRemoteView:userId streamType:TRTCVideoStreamTypeSmall];
[[self remoteUidSet] removeObject:userId];
}
[self refreshRemoteVideoViews];
NSDictionary *event = [[NSDictionary alloc]initWithObjectsAndKeys:
[[NSString alloc] initWithFormat:@"%d",_roomId],@"room",userId,@"userId",available,@"available", nil];
[CordovaEventKit fireEvent:@"onUserVideoAvailable" obj:event];
}
- (void)refreshRemoteVideoViews {
NSLog(@"TRTC - refreshRemoteVideoViews");
// NSInteger index = 0;
// for (NSString* userId in [self remoteUidSet]) {0
// if (index >= maxRemoteUserNum) { return; }
// [_remoteViewArr[index] setHidden:NO];
// [_trtcCloud startRemoteView:userId streamType:TRTCVideoStreamTypeSmall
// view:_remoteViewArr[index++]];
// }
_subVisibleButton.hidden = _sharedUser != nil;
_viewRotateButton.hidden = _sharedUser == nil;
for (int i = 0; i <= _remoteViewArr.count; i++) {
TrtcUserInfo* nUser = [self remoteUidSet].count > i ? [self remoteUidSet][i] : nil;
TrtcUserInfo* oUser = [self viewUserSet].count > i ? [self viewUserSet][i] : nil;
UIView* view = i == 0 ? self.view : _remoteViewArr[i-1];
UILabel* label = i ==0 ? _displayLabel : _displayLabelArr[i-1];
if((_sharedUser != nil || [_subVisibleButton isSelected]) && i!=0){
[view setHidden:YES];
[label setHidden:YES];
}else{
if(nUser != nil){
if([nUser isEqual:oUser]){
if([nUser displayName] == nil || [nUser displayName].length == 0) {
[label setText:[NSString stringWithFormat:@"%@%@",[nUser personid], [nUser isShareUser] ? @"的屏幕分享" : @""]];
} else {
[label setText:[NSString stringWithFormat:@"%@%@",[nUser displayName], [nUser isShareUser] ? @"的屏幕分享" : @""]];
}
return;
}
TRTCRenderParams *params = [TRTCRenderParams init];
params.rotation = 0;
params.fillMode = [nUser isShareUser] ? TRTCVideoFillMode_Fit : TRTCVideoFillMode_Fill;
if([nUser isLocalUser]){
[_trtcCloud startLocalPreview:_isFrontCamera view:view];
[_trtcCloud setLocalRenderParams:params];
[label setText:@""];
} else {
[_trtcCloud setRemoteRenderParams:[nUser personid] streamType:i == 0 ? TRTCVideoStreamTypeBig : TRTCVideoStreamTypeSmall params:params];
[_trtcCloud startRemoteView:[nUser personid] streamType:i == 0 ? TRTCVideoStreamTypeBig : TRTCVideoStreamTypeSmall view:view];
if([nUser displayName] == nil || [nUser displayName].length == 0) {
[label setText:[NSString stringWithFormat:@"%@%@",[nUser personid], [nUser isShareUser] ? @"的屏幕分享" : @""]];
} else {
[label setText:[NSString stringWithFormat:@"%@%@",[nUser displayName], [nUser isShareUser] ? @"的屏幕分享" : @""]];
}
}
[label setHidden:NO];
[view setHidden:NO];
} else {
[view setHidden:YES];
[label setHidden:YES];
}
}
if( [self viewUserSet].count > i ){
[[self viewUserSet] setObject:nUser atIndex:i];
}
}
}
- (void) onError:(TXLiteAVError)errCode errMsg:(NSString *)errMsg extInfo:(NSDictionary *)extInfo{
NSLog(@"TRTC - onError::sdk callback onError code: %d,msg: %@,extInfo: %@",errCode,errMsg,extInfo);
dispatch_async(dispatch_get_main_queue(), ^{
[self.view makeToast: [[NSString alloc] initWithFormat:@"%@[%d]",errMsg,errCode]];
});
// [self.trtcCloud exitRoom];
// [TRTCCloud destroySharedIntance];
// [self dismissViewControllerAnimated:YES completion:nil];
}
- (void) onExitRoom:(NSInteger)reason{
if (reason == 2) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.view makeToast: @"远程协助已结束"];
});
}
[self dismissViewControllerAnimated:YES completion:nil];
}
@end