From 30e222d90ee9b80091c36a71e4a092da18c3004f Mon Sep 17 00:00:00 2001 From: tonychan Date: Tue, 8 Nov 2022 17:11:18 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4pitch=E8=B0=83=E8=8A=82?= =?UTF-8?q?=E6=97=B6=E6=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I187d9a3d76dbd5249271ba4b73b68f3f5d174608 --- .../P2P/Controller/TIoTDemoPreviewDeviceVC.m | 22 +- .../Video/P2P/Controller/TIoTSessionManager.h | 24 ++ .../Video/P2P/Controller/TIoTSessionManager.m | 276 ++++++++++++++++++ .../SDK/LinkVideo/FLV/TIoTPCMXEchoRecord.mm | 24 +- Source/SDK/LinkVideo/TIoTCoreAudioConfig.h | 5 + Source/SDK/LinkVideo/TIoTCoreXP2PBridge.mm | 4 +- TIoTLinkKit.xcodeproj/project.pbxproj | 6 + 7 files changed, 349 insertions(+), 12 deletions(-) create mode 100644 Source/LinkSDKDemo/Video/P2P/Controller/TIoTSessionManager.h create mode 100644 Source/LinkSDKDemo/Video/P2P/Controller/TIoTSessionManager.m diff --git a/Source/LinkSDKDemo/Video/P2P/Controller/TIoTDemoPreviewDeviceVC.m b/Source/LinkSDKDemo/Video/P2P/Controller/TIoTDemoPreviewDeviceVC.m index 18997c44..cd30c439 100644 --- a/Source/LinkSDKDemo/Video/P2P/Controller/TIoTDemoPreviewDeviceVC.m +++ b/Source/LinkSDKDemo/Video/P2P/Controller/TIoTDemoPreviewDeviceVC.m @@ -25,6 +25,7 @@ #import "TIoTXp2pInfoModel.h" #import #import "ReachabilityManager.h" +#import "TIoTSessionManager.h" static CGFloat const kPadding = 16; static NSString *const kPreviewDeviceCellID = @"kPreviewDeviceCellID"; @@ -107,7 +108,7 @@ - (void)viewDidLoad { // [TIoTCoreXP2PBridge sharedInstance].logEnable = NO; self.navigationController.navigationBar.tintColor = [UIColor blackColor]; - self.qualityString = quality_standard; + self.qualityString = quality_high; self.screenRect = [UIApplication sharedApplication].delegate.window.frame; if (self.isNVR == NO) { @@ -214,6 +215,8 @@ - (void)dealloc{ [[NSNotificationCenter defaultCenter]removeObserver:self]; if (self.isNVR == NO) { [[TIoTCoreXP2PBridge sharedInstance] stopService:self.deviceName?:@""]; + + [[TIoTSessionManager sharedInstance] resetToCachedAudioSession]; } printf("debugdeinit---%s,%s,%d", __FILE__, __FUNCTION__, __LINE__); @@ -254,21 +257,28 @@ - (void)getDeviceStatusWithType:(NSString *)singleType qualityType:(NSString *)q channel = [NSString stringWithFormat:@"channel=%d",channelNum.intValue]; } - [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil]; - [[AVAudioSession sharedInstance] setActive:YES error:nil]; - // [[TIoTCoreXP2PBridge sharedInstance] sendVoiceToServer:weakSelf.deviceName?:@"" channel:channel]; + [[TIoTSessionManager sharedInstance] resumeRTCAudioSession]; + + static int tt_pitch = -6; TIoTCoreAudioConfig *audio_config = [TIoTCoreAudioConfig new]; + audio_config.refreshSession = YES; audio_config.sampleRate = TIoTAVCaptionFLVAudio_8; audio_config.channels = 1; audio_config.isEchoCancel = YES; - audio_config.pitch = -6; //声音会变粗一点 + audio_config.pitch = tt_pitch; // -6声音会变粗一点; 6声音会变细一点 TIoTCoreVideoConfig *video_config = [TIoTCoreVideoConfig new]; video_config.localView = nil; video_config.videoPosition = AVCaptureDevicePositionFront; [[TIoTCoreXP2PBridge sharedInstance] sendVoiceToServer:weakSelf.deviceName?:@"" channel:channel audioConfig:audio_config videoConfig:video_config]; + + if(tt_pitch == 6){ + tt_pitch = -6; + }else { + tt_pitch = 6; + } } }else { @@ -654,6 +664,8 @@ - (void)clickTalkback:(UIButton *)button { }else { self.talkbackIcon.image = [UIImage imageNamed:@"talkback_unselect"]; [[TIoTCoreXP2PBridge sharedInstance] stopVoiceToServer]; + + [[TIoTSessionManager sharedInstance] resetToCachedAudioSession]; } button.selected = !button.selected; diff --git a/Source/LinkSDKDemo/Video/P2P/Controller/TIoTSessionManager.h b/Source/LinkSDKDemo/Video/P2P/Controller/TIoTSessionManager.h new file mode 100644 index 00000000..7de6e040 --- /dev/null +++ b/Source/LinkSDKDemo/Video/P2P/Controller/TIoTSessionManager.h @@ -0,0 +1,24 @@ +// +// TIoTCoreASessionManager.h +// TIoTLinkVideo +// +// Created by eagleychen on 2022/11/2. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface TIoTSessionManager : NSObject ++ (instancetype)sharedInstance; +//需要录音时,AudioSession的设置代码如下 +- (void)resumeRTCAudioSession; + +//功能结束时重置audioSession,重置到缓存的audioSession设置 +- (void)resetToCachedAudioSession; + +- (NSString *)description; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/LinkSDKDemo/Video/P2P/Controller/TIoTSessionManager.m b/Source/LinkSDKDemo/Video/P2P/Controller/TIoTSessionManager.m new file mode 100644 index 00000000..ce4a2ae9 --- /dev/null +++ b/Source/LinkSDKDemo/Video/P2P/Controller/TIoTSessionManager.m @@ -0,0 +1,276 @@ +// +// TIoTSessionManager.m +// TIoTLinkVideo +// +// Created by eagleychen on 2022/11/2. +// + +#import "TIoTSessionManager.h" +#import + +static AVAudioSessionCategory cachedCategory = nil; +static AVAudioSessionCategoryOptions cachedCategoryOptions = 0; + +@interface TIoTSessionManager () +@property(nonatomic, assign) AVAudioSessionPortOverride portOverride; +@property (nonatomic,weak) AVAudioSession *session; +@end + +@implementation TIoTSessionManager + ++ (instancetype)sharedInstance { + static dispatch_once_t onceToken; + static TIoTSessionManager *sharedInstance = nil; + dispatch_once(&onceToken, ^{ + sharedInstance = [[self alloc] init]; + }); + return sharedInstance; +} + + +- (instancetype)init { + if (self = [super init]) { + + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center addObserver:self + selector:@selector(handleInterruptionNotification:) + name:AVAudioSessionInterruptionNotification + object:nil]; + [center addObserver:self + selector:@selector(handleRouteChangeNotification:) + name:AVAudioSessionRouteChangeNotification + object:nil]; + [center addObserver:self + selector:@selector(handleMediaServicesWereLost:) + name:AVAudioSessionMediaServicesWereLostNotification + object:nil]; + [center addObserver:self + selector:@selector(handleMediaServicesWereReset:) + name:AVAudioSessionMediaServicesWereResetNotification + object:nil]; + // Posted on the main thread when the primary audio from other applications + // starts and stops. Foreground applications may use this notification as a + // hint to enable or disable audio that is secondary. + [center addObserver:self + selector:@selector(handleSilenceSecondaryAudioHintNotification:) + name:AVAudioSessionSilenceSecondaryAudioHintNotification + object:nil]; + // Also track foreground event in order to deal with interruption ended situation. + [center addObserver:self + selector:@selector(handleApplicationDidBecomeActive:) + name:UIApplicationDidBecomeActiveNotification + object:nil]; + + NSLog(@"RTC_OBJC_TYPE(RTCAudioSession) (%p): init.", self); + } + return self; +} + +//更改audioSession前缓存RTC当下的设置 +- (void)cacheCurrentAudioSession { + NSLog(@"cache-->%@",[self description]); + + @synchronized (self) { + cachedCategory = [AVAudioSession sharedInstance].category; + cachedCategoryOptions = [AVAudioSession sharedInstance].categoryOptions; + + NSLog(@"cacheCategory==>%@,cacheOptions==>%d", cachedCategory, cachedCategoryOptions); + } +} + + +//需要录音时,AudioSession的设置代码如下: +- (void)resumeRTCAudioSession { + self.session = [AVAudioSession sharedInstance]; + if (self.session.category != AVAudioSessionCategoryPlayAndRecord) { + [self cacheCurrentAudioSession]; //先缓存之前的 + + NSLog(@"resumeToCachegory===>%@, categoryOption==>%ld",cachedCategory, cachedCategoryOptions); +// NSError *error; + +// [self.session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error]; +// [self.session setMode:AVAudioSessionModeVideoChat error:nil]; +// [self.session setActive:YES error:&error]; + + AVAudioSessionCategoryOptions categoryOptions = AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionMixWithOthers; + if (@available(iOS 10.0, *)) { + categoryOptions |= AVAudioSessionCategoryOptionAllowBluetooth; + } + [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:categoryOptions error:nil]; + [[AVAudioSession sharedInstance] setActive:YES error:nil]; + } +} +//功能结束时重置audioSession,重置到缓存的audioSession设置 +- (void)resetToCachedAudioSession { + if (!cachedCategory) { + return; + } + BOOL needResetAudioSession = ![[AVAudioSession sharedInstance].category isEqualToString:cachedCategory] || [AVAudioSession sharedInstance].categoryOptions != cachedCategoryOptions; + NSLog(@"resetToCachegory===>%@, categoryOption==>%ld, needrest==%d",cachedCategory, cachedCategoryOptions, needResetAudioSession); + if (needResetAudioSession) { + dispatch_async(dispatch_get_main_queue(), ^{ +// dispatch_async(dispatch_get_global_queue(0, 0), ^{ + [[AVAudioSession sharedInstance] setCategory:cachedCategory withOptions:cachedCategoryOptions error:nil]; + [[AVAudioSession sharedInstance] setActive:YES error:nil]; + @synchronized (self) { + cachedCategory = nil; + cachedCategoryOptions = 0; + } + }); + } +} + +- (NSString *)description { + NSString *format = @"RTC_OBJC_TYPE(RTCAudioSession): {\n" + " category: %@\n" + " categoryOptions: %ld\n" + " mode: %@\n" + " isActive: %d\n" + " sampleRate: %.2f\n" + " IOBufferDuration: %f\n" + " outputNumberOfChannels: %ld\n" + " inputNumberOfChannels: %ld\n" + " outputLatency: %f\n" + " inputLatency: %f\n" + " outputVolume: %f\n" + "}"; + + AVAudioSession *session = [AVAudioSession sharedInstance]; + AVAudioSessionCategory category = session.category; + AVAudioSessionCategoryOptions categoryOptions = session.categoryOptions; + AVAudioSessionMode mode = session.mode; + BOOL isActive = YES; + double sampleRate = session.sampleRate; + double preferredSampleRate = session.preferredSampleRate; + NSTimeInterval IOBufferDuration = session.IOBufferDuration; + NSInteger outputNumberOfChannels = session.outputNumberOfChannels; + NSInteger inputNumberOfChannels = session.inputNumberOfChannels; + NSTimeInterval outputLatency = session.outputLatency; + NSTimeInterval inputLatency = session.inputLatency; + float outputVolume = session.outputVolume; + AVAudioSessionRouteDescription *currentRoute = session.currentRoute; + NSLog(@"currentRout===>%@",currentRoute); + NSString *description = [NSString stringWithFormat:format, + category, (long)categoryOptions, mode, + isActive, sampleRate, IOBufferDuration, + outputNumberOfChannels, inputNumberOfChannels, + outputLatency, inputLatency, outputVolume]; + + return description; +} + + +#pragma mark - Notifications + +- (void)handleInterruptionNotification:(NSNotification *)notification { + NSNumber* typeNumber = + notification.userInfo[AVAudioSessionInterruptionTypeKey]; + AVAudioSessionInterruptionType type = + (AVAudioSessionInterruptionType)typeNumber.unsignedIntegerValue; + switch (type) { + case AVAudioSessionInterruptionTypeBegan: + NSLog(@"Audio session interruption began."); + // self.isActive = NO; + // self.isInterrupted = YES; + // [self notifyDidBeginInterruption]; + break; + case AVAudioSessionInterruptionTypeEnded: { + NSLog(@"Audio session interruption ended."); + // self.isInterrupted = NO; + // [self updateAudioSessionAfterEvent]; + NSNumber *optionsNumber = notification.userInfo[AVAudioSessionInterruptionOptionKey]; + AVAudioSessionInterruptionOptions options = optionsNumber.unsignedIntegerValue; + BOOL shouldResume = options & AVAudioSessionInterruptionOptionShouldResume; + // [self notifyDidEndInterruptionWithShouldResumeSession:shouldResume]; + break; + } + } +} + +- (void)handleRouteChangeNotification:(NSNotification *)notification { + // Get reason for current route change. + NSNumber* reasonNumber = + notification.userInfo[AVAudioSessionRouteChangeReasonKey]; + AVAudioSessionRouteChangeReason reason = + (AVAudioSessionRouteChangeReason)reasonNumber.unsignedIntegerValue; + NSLog(@"Audio route changed:"); + switch (reason) { + case AVAudioSessionRouteChangeReasonUnknown: + NSLog(@"Audio route changed: ReasonUnknown"); + break; + case AVAudioSessionRouteChangeReasonNewDeviceAvailable: + NSLog(@"Audio route changed: NewDeviceAvailable"); + break; + case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: + NSLog(@"Audio route changed: OldDeviceUnavailable"); + break; + case AVAudioSessionRouteChangeReasonCategoryChange: + NSLog(@"Audio route changed: CategoryChange to :%@", + [AVAudioSession sharedInstance].category); + break; + case AVAudioSessionRouteChangeReasonOverride: + NSLog(@"Audio route changed: Override"); + break; + case AVAudioSessionRouteChangeReasonWakeFromSleep: + NSLog(@"Audio route changed: WakeFromSleep"); + break; + case AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory: + NSLog(@"Audio route changed: NoSuitableRouteForCategory"); + break; + case AVAudioSessionRouteChangeReasonRouteConfigurationChange: + NSLog(@"Audio route changed: RouteConfigurationChange"); + break; + } + AVAudioSessionRouteDescription* previousRoute = + notification.userInfo[AVAudioSessionRouteChangePreviousRouteKey]; + // Log previous route configuration. + NSLog(@"Previous route: %@\nCurrent route:%@", + previousRoute, [AVAudioSession sharedInstance].currentRoute); + +// [self.session setActive:YES error:nil]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"testAudioSession" object:nil]; +} + +- (void)handleMediaServicesWereLost:(NSNotification *)notification { + NSLog(@"Media services were lost."); +// [self updateAudioSessionAfterEvent]; +// [self notifyMediaServicesWereLost]; +} + +- (void)handleMediaServicesWereReset:(NSNotification *)notification { + NSLog(@"Media services were reset."); +// [self updateAudioSessionAfterEvent]; +// [self notifyMediaServicesWereReset]; +} + +- (void)handleSilenceSecondaryAudioHintNotification:(NSNotification *)notification { + // TODO(henrika): just adding logs here for now until we know if we are ever + // see this notification and might be affected by it or if further actions + // are required. + NSNumber *typeNumber = + notification.userInfo[AVAudioSessionSilenceSecondaryAudioHintTypeKey]; + AVAudioSessionSilenceSecondaryAudioHintType type = + (AVAudioSessionSilenceSecondaryAudioHintType)typeNumber.unsignedIntegerValue; + switch (type) { + case AVAudioSessionSilenceSecondaryAudioHintTypeBegin: + NSLog(@"Another application's primary audio has started."); + break; + case AVAudioSessionSilenceSecondaryAudioHintTypeEnd: + NSLog(@"Another application's primary audio has stopped."); + break; + } +} + +- (void)handleApplicationDidBecomeActive:(NSNotification *)notification { + BOOL isInterrupted = YES; //self.isInterrupted; + NSLog(@"Application became active after an interruption. Treating as interruption " + "end. isInterrupted changed from %d to 0.", + isInterrupted); +// if (isInterrupted) { +// self.isInterrupted = NO; +// [self updateAudioSessionAfterEvent]; +// } + // Always treat application becoming active as an interruption end event. +// [self notifyDidEndInterruptionWithShouldResumeSession:YES]; +} +@end diff --git a/Source/SDK/LinkVideo/FLV/TIoTPCMXEchoRecord.mm b/Source/SDK/LinkVideo/FLV/TIoTPCMXEchoRecord.mm index 27a26ca1..a138bb4c 100644 --- a/Source/SDK/LinkVideo/FLV/TIoTPCMXEchoRecord.mm +++ b/Source/SDK/LinkVideo/FLV/TIoTPCMXEchoRecord.mm @@ -7,6 +7,9 @@ #import +static int kOutputBus = 0; +static int kInputBus = 1; + @interface TIoTPCMXEchoRecord() { AudioUnit audioUnit; @@ -51,12 +54,22 @@ - (instancetype)initWithChannel:(int)channel isEcho:(BOOL)isEcho outStreamDes.mReserved = 0; _pcmStreamDescription = outStreamDes; - UInt32 flags = 1; - ret = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &flags, sizeof(flags)); + UInt32 enableOutput = 1; + ret = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &enableOutput, sizeof(enableOutput)); if (ret != noErr) return nil; - ret = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &outStreamDes, sizeof(outStreamDes)); + ret = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &outStreamDes, sizeof(outStreamDes)); + if (ret != noErr) + return nil; + + ret = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &outStreamDes, sizeof(outStreamDes)); + if (ret != noErr) + return nil; + + // Enable the microphone input + UInt32 enableInput = 1; + ret = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &enableInput, sizeof(enableInput)); if (ret != noErr) return nil; @@ -74,8 +87,9 @@ - (instancetype)initWithChannel:(int)channel isEcho:(BOOL)isEcho if (ret != noErr) return nil; - return self; -} + AudioUnitInitialize(audioUnit); + + return self;} #define kTVURecoderPCMMaxBuffSize 2048 static int pcm_buffer_size = 0; diff --git a/Source/SDK/LinkVideo/TIoTCoreAudioConfig.h b/Source/SDK/LinkVideo/TIoTCoreAudioConfig.h index 62ddc16b..f380ce7d 100644 --- a/Source/SDK/LinkVideo/TIoTCoreAudioConfig.h +++ b/Source/SDK/LinkVideo/TIoTCoreAudioConfig.h @@ -36,6 +36,11 @@ typedef NS_ENUM(NSInteger, TIoTAVCaptionFLVAudioType) { */ @property (nonatomic,assign) int pitch; +/** + * 需要重启录音器和编码器设置为yes + */ +@property (nonatomic,assign) BOOL refreshSession; + @end NS_ASSUME_NONNULL_END diff --git a/Source/SDK/LinkVideo/TIoTCoreXP2PBridge.mm b/Source/SDK/LinkVideo/TIoTCoreXP2PBridge.mm index 934767bc..0dbb6872 100644 --- a/Source/SDK/LinkVideo/TIoTCoreXP2PBridge.mm +++ b/Source/SDK/LinkVideo/TIoTCoreXP2PBridge.mm @@ -344,12 +344,12 @@ - (void)sendVoiceToServer:(NSString *)dev_name channel:(NSString *)channel_numbe _serverHandle = runSendService(dev_name.UTF8String, channel, false); //发送数据前需要告知http proxy - if (systemAvCapture == nil) { + if (systemAvCapture == nil || audio_config.refreshSession) { systemAvCapture = [[TIoTAVCaptionFLV alloc] initWithAudioConfig:audio_config.sampleRate channel:audio_config.channels]; systemAvCapture.videoLocalView = video_config.localView; systemAvCapture.isEchoCancel = audio_config.isEchoCancel; - systemAvCapture.pitch = audio_config.pitch; } + systemAvCapture.pitch = audio_config.pitch; systemAvCapture.devicePosition = video_config.videoPosition; systemAvCapture.videoLocalView = video_config.localView; [systemAvCapture setResolutionRatio:self.resolution]; diff --git a/TIoTLinkKit.xcodeproj/project.pbxproj b/TIoTLinkKit.xcodeproj/project.pbxproj index 93600aa0..74e460a0 100644 --- a/TIoTLinkKit.xcodeproj/project.pbxproj +++ b/TIoTLinkKit.xcodeproj/project.pbxproj @@ -395,6 +395,7 @@ F42B874B27218FFE0002FD5C /* TIoTAuthentationVC.m in Sources */ = {isa = PBXBuildFile; fileRef = F42B874A27218FFE0002FD5C /* TIoTAuthentationVC.m */; }; F42B874E27229E9D0002FD5C /* TIoTAlertAuthorsizeView.m in Sources */ = {isa = PBXBuildFile; fileRef = F42B874D27229E9D0002FD5C /* TIoTAlertAuthorsizeView.m */; }; F42B875127268F610002FD5C /* TIoTRegionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F42B875027268F610002FD5C /* TIoTRegionViewController.m */; }; + F42D023A291A405800E1B36B /* TIoTSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F42D0238291A405800E1B36B /* TIoTSessionManager.m */; }; F44D679F25B6D96D001B413C /* TIoTPlayMovieVC.m in Sources */ = {isa = PBXBuildFile; fileRef = F44D679D25B6D96D001B413C /* TIoTPlayMovieVC.m */; }; F44D67A025B6D96D001B413C /* TIoTPlayMovieVC.xib in Resources */ = {isa = PBXBuildFile; fileRef = F44D679E25B6D96D001B413C /* TIoTPlayMovieVC.xib */; }; F46FE31B26A5735700543EFD /* TIoTLLSyncViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F46FE31A26A5735700543EFD /* TIoTLLSyncViewController.m */; }; @@ -1238,6 +1239,8 @@ F42B874D27229E9D0002FD5C /* TIoTAlertAuthorsizeView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TIoTAlertAuthorsizeView.m; sourceTree = ""; }; F42B874F27268F610002FD5C /* TIoTRegionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TIoTRegionViewController.h; sourceTree = ""; }; F42B875027268F610002FD5C /* TIoTRegionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TIoTRegionViewController.m; sourceTree = ""; }; + F42D0238291A405800E1B36B /* TIoTSessionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TIoTSessionManager.m; sourceTree = ""; }; + F42D0239291A405800E1B36B /* TIoTSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TIoTSessionManager.h; sourceTree = ""; }; F44D679C25B6D96D001B413C /* TIoTPlayMovieVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TIoTPlayMovieVC.h; sourceTree = ""; }; F44D679D25B6D96D001B413C /* TIoTPlayMovieVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TIoTPlayMovieVC.m; sourceTree = ""; }; F44D679E25B6D96D001B413C /* TIoTPlayMovieVC.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TIoTPlayMovieVC.xib; sourceTree = ""; }; @@ -1979,6 +1982,8 @@ 6DAF8B78266B937500CD0328 /* TIoTDemoPreviewDeviceVC.m */, 6D204D4C265F8A2D007F6F27 /* TIoTDemoSameScreenVC.h */, 6D204D4D265F8A2D007F6F27 /* TIoTDemoSameScreenVC.m */, + F42D0239291A405800E1B36B /* TIoTSessionManager.h */, + F42D0238291A405800E1B36B /* TIoTSessionManager.m */, ); path = Controller; sourceTree = ""; @@ -3959,6 +3964,7 @@ 6DE5D1E826DCBCC800C6EFCA /* TIoTDemoLocalDayTimeListModel.m in Sources */, 6D204C9D265CF987007F6F27 /* TIoTDemoDeviceHeaderView.m in Sources */, F4F325DF25919A1200A4CAAB /* TRTCVideoCallViewController.swift in Sources */, + F42D023A291A405800E1B36B /* TIoTSessionManager.m in Sources */, 6D1E3C5A2791924300D0DBBF /* TIoTRegionPickerView.m in Sources */, F4F3D7B324938EBE005D3396 /* InviteVC.m in Sources */, F4F3D7B024938EBE005D3396 /* TIoTCoreAddFamilyVC.m in Sources */,