tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ARDVideoCallViewController.m (8987B)


      1 /*
      2 *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #import "ARDVideoCallViewController.h"
     12 
     13 #import "sdk/objc/api/peerconnection/RTCMediaConstraints.h"
     14 #import "sdk/objc/base/RTCLogging.h"
     15 #import "sdk/objc/components/audio/RTCAudioSession.h"
     16 #import "sdk/objc/components/capturer/RTCCameraVideoCapturer.h"
     17 #import "sdk/objc/helpers/RTCDispatcher.h"
     18 
     19 #import "ARDAppClient.h"
     20 #import "ARDCaptureController.h"
     21 #import "ARDFileCaptureController.h"
     22 #import "ARDSettingsModel.h"
     23 #import "ARDVideoCallView.h"
     24 
     25 @interface ARDVideoCallViewController () <
     26    ARDAppClientDelegate,
     27    ARDVideoCallViewDelegate,
     28    RTC_OBJC_TYPE (RTCAudioSessionDelegate)>
     29 @property(nonatomic, strong) RTC_OBJC_TYPE(RTCVideoTrack) * remoteVideoTrack;
     30 @property(nonatomic, readonly) ARDVideoCallView *videoCallView;
     31 @property(nonatomic, assign) AVAudioSessionPortOverride portOverride;
     32 @end
     33 
     34 @implementation ARDVideoCallViewController {
     35  ARDAppClient *_client;
     36  RTC_OBJC_TYPE(RTCVideoTrack) * _remoteVideoTrack;
     37  ARDCaptureController *_captureController;
     38  ARDFileCaptureController *_fileCaptureController NS_AVAILABLE_IOS(10);
     39 }
     40 
     41 @synthesize videoCallView = _videoCallView;
     42 @synthesize remoteVideoTrack = _remoteVideoTrack;
     43 @synthesize delegate = _delegate;
     44 @synthesize portOverride = _portOverride;
     45 
     46 - (instancetype)initForRoom:(NSString *)room
     47                 isLoopback:(BOOL)isLoopback
     48                   delegate:(id<ARDVideoCallViewControllerDelegate>)delegate {
     49  self = [super init];
     50  if (self) {
     51    ARDSettingsModel *settingsModel = [[ARDSettingsModel alloc] init];
     52    _delegate = delegate;
     53 
     54    _client = [[ARDAppClient alloc] initWithDelegate:self];
     55    [_client connectToRoomWithId:room
     56                        settings:settingsModel
     57                      isLoopback:isLoopback];
     58  }
     59  return self;
     60 }
     61 
     62 - (void)loadView {
     63  _videoCallView = [[ARDVideoCallView alloc] initWithFrame:CGRectZero];
     64  _videoCallView.delegate = self;
     65  _videoCallView.statusLabel.text =
     66      [self statusTextForState:RTCIceConnectionStateNew];
     67  self.view = _videoCallView;
     68 
     69  RTC_OBJC_TYPE(RTCAudioSession) *session =
     70      [RTC_OBJC_TYPE(RTCAudioSession) sharedInstance];
     71  [session addDelegate:self];
     72 }
     73 
     74 - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
     75  return UIInterfaceOrientationMaskAll;
     76 }
     77 
     78 #pragma mark - ARDAppClientDelegate
     79 
     80 - (void)appClient:(ARDAppClient *)client
     81    didChangeState:(ARDAppClientState)state {
     82  switch (state) {
     83    case kARDAppClientStateConnected:
     84      RTCLog(@"Client connected.");
     85      break;
     86    case kARDAppClientStateConnecting:
     87      RTCLog(@"Client connecting.");
     88      break;
     89    case kARDAppClientStateDisconnected:
     90      RTCLog(@"Client disconnected.");
     91      [self hangup];
     92      break;
     93  }
     94 }
     95 
     96 - (void)appClient:(ARDAppClient *)client
     97    didChangeConnectionState:(RTCIceConnectionState)state {
     98  RTCLog(@"ICE state changed: %ld", (long)state);
     99  __weak ARDVideoCallViewController *weakSelf = self;
    100  dispatch_async(dispatch_get_main_queue(), ^{
    101    ARDVideoCallViewController *strongSelf = weakSelf;
    102    strongSelf.videoCallView.statusLabel.text =
    103        [strongSelf statusTextForState:state];
    104  });
    105 }
    106 
    107 - (void)appClient:(ARDAppClient *)client
    108    didCreateLocalCapturer:
    109        (RTC_OBJC_TYPE(RTCCameraVideoCapturer) *)localCapturer {
    110  _videoCallView.localVideoView.captureSession = localCapturer.captureSession;
    111  ARDSettingsModel *settingsModel = [[ARDSettingsModel alloc] init];
    112  _captureController =
    113      [[ARDCaptureController alloc] initWithCapturer:localCapturer
    114                                            settings:settingsModel];
    115  [_captureController startCapture];
    116 }
    117 
    118 - (void)appClient:(ARDAppClient *)client
    119    didCreateLocalFileCapturer:
    120        (RTC_OBJC_TYPE(RTCFileVideoCapturer) *)fileCapturer {
    121 #if defined(__IPHONE_11_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0)
    122  if (@available(iOS 10, *)) {
    123    _fileCaptureController =
    124        [[ARDFileCaptureController alloc] initWithCapturer:fileCapturer];
    125    [_fileCaptureController startCapture];
    126  }
    127 #endif
    128 }
    129 
    130 - (void)appClient:(ARDAppClient *)client
    131    didReceiveLocalVideoTrack:(RTC_OBJC_TYPE(RTCVideoTrack) *)localVideoTrack {
    132 }
    133 
    134 - (void)appClient:(ARDAppClient *)client
    135    didReceiveRemoteVideoTrack:
    136        (RTC_OBJC_TYPE(RTCVideoTrack) *)remoteVideoTrack {
    137  self.remoteVideoTrack = remoteVideoTrack;
    138  __weak ARDVideoCallViewController *weakSelf = self;
    139  dispatch_async(dispatch_get_main_queue(), ^{
    140    ARDVideoCallViewController *strongSelf = weakSelf;
    141    strongSelf.videoCallView.statusLabel.hidden = YES;
    142  });
    143 }
    144 
    145 - (void)appClient:(ARDAppClient *)client
    146      didGetStats:(RTC_OBJC_TYPE(RTCStatisticsReport) *)stats {
    147  _videoCallView.statsView.stats = stats;
    148  [_videoCallView setNeedsLayout];
    149 }
    150 
    151 - (void)appClient:(ARDAppClient *)client didError:(NSError *)error {
    152  NSString *message =
    153      [NSString stringWithFormat:@"%@", error.localizedDescription];
    154  [self hangup];
    155  [self showAlertWithMessage:message];
    156 }
    157 
    158 #pragma mark - ARDVideoCallViewDelegate
    159 
    160 - (void)videoCallViewDidHangup:(ARDVideoCallView *)view {
    161  [self hangup];
    162 }
    163 
    164 - (void)videoCallView:(ARDVideoCallView *)view
    165    shouldSwitchCameraWithCompletion:(void (^)(NSError *))completion {
    166  [_captureController switchCamera:completion];
    167 }
    168 
    169 - (void)videoCallView:(ARDVideoCallView *)view
    170    shouldChangeRouteWithCompletion:(void (^)(void))completion {
    171  NSParameterAssert(completion);
    172  AVAudioSessionPortOverride override = AVAudioSessionPortOverrideNone;
    173  if (_portOverride == AVAudioSessionPortOverrideNone) {
    174    override = AVAudioSessionPortOverrideSpeaker;
    175  }
    176  [RTC_OBJC_TYPE(RTCDispatcher)
    177      dispatchAsyncOnType:RTCDispatcherTypeAudioSession
    178                    block:^{
    179                      RTC_OBJC_TYPE(RTCAudioSession) *session =
    180                          [RTC_OBJC_TYPE(RTCAudioSession) sharedInstance];
    181                      [session lockForConfiguration];
    182                      NSError *error = nil;
    183                      if ([session overrideOutputAudioPort:override
    184                                                     error:&error]) {
    185                        self.portOverride = override;
    186                      } else {
    187                        RTCLogError(@"Error overriding output port: %@",
    188                                    error.localizedDescription);
    189                      }
    190                      [session unlockForConfiguration];
    191                      completion();
    192                    }];
    193 }
    194 
    195 - (void)videoCallViewDidEnableStats:(ARDVideoCallView *)view {
    196  _client.shouldGetStats = YES;
    197  _videoCallView.statsView.hidden = NO;
    198 }
    199 
    200 #pragma mark - RTC_OBJC_TYPE(RTCAudioSessionDelegate)
    201 
    202 - (void)audioSession:(RTC_OBJC_TYPE(RTCAudioSession) *)audioSession
    203    didDetectPlayoutGlitch:(int64_t)totalNumberOfGlitches {
    204  RTCLog(@"Audio session detected glitch, total: %lld", totalNumberOfGlitches);
    205 }
    206 
    207 #pragma mark - Private
    208 
    209 - (void)setRemoteVideoTrack:(RTC_OBJC_TYPE(RTCVideoTrack) *)remoteVideoTrack {
    210  if (_remoteVideoTrack == remoteVideoTrack) {
    211    return;
    212  }
    213  [_remoteVideoTrack removeRenderer:_videoCallView.remoteVideoView];
    214  _remoteVideoTrack = nil;
    215  [_videoCallView.remoteVideoView renderFrame:nil];
    216  _remoteVideoTrack = remoteVideoTrack;
    217  [_remoteVideoTrack addRenderer:_videoCallView.remoteVideoView];
    218 }
    219 
    220 - (void)hangup {
    221  self.remoteVideoTrack = nil;
    222  _videoCallView.localVideoView.captureSession = nil;
    223  [_captureController stopCapture];
    224  _captureController = nil;
    225  [_fileCaptureController stopCapture];
    226  _fileCaptureController = nil;
    227  [_client disconnect];
    228  [_delegate viewControllerDidFinish:self];
    229 }
    230 
    231 - (NSString *)statusTextForState:(RTCIceConnectionState)state {
    232  switch (state) {
    233    case RTCIceConnectionStateNew:
    234    case RTCIceConnectionStateChecking:
    235      return @"Connecting...";
    236    case RTCIceConnectionStateConnected:
    237    case RTCIceConnectionStateCompleted:
    238    case RTCIceConnectionStateFailed:
    239    case RTCIceConnectionStateDisconnected:
    240    case RTCIceConnectionStateClosed:
    241    case RTCIceConnectionStateCount:
    242      return nil;
    243  }
    244 }
    245 
    246 - (void)showAlertWithMessage:(NSString *)message {
    247  UIAlertController *alert =
    248      [UIAlertController alertControllerWithTitle:nil
    249                                          message:message
    250                                   preferredStyle:UIAlertControllerStyleAlert];
    251 
    252  UIAlertAction *defaultAction =
    253      [UIAlertAction actionWithTitle:@"OK"
    254                               style:UIAlertActionStyleDefault
    255                             handler:^(UIAlertAction *action){
    256                             }];
    257 
    258  [alert addAction:defaultAction];
    259  [self presentViewController:alert animated:YES completion:nil];
    260 }
    261 
    262 @end