NADViewController.mm (6445B)
1 /* 2 * Copyright 2018 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 "NADViewController.h" 12 13 #import "sdk/objc/base/RTCVideoRenderer.h" 14 #import "sdk/objc/components/capturer/RTCCameraVideoCapturer.h" 15 #import "sdk/objc/components/renderer/metal/RTCMTLVideoView.h" 16 #import "sdk/objc/helpers/RTCCameraPreviewView.h" 17 18 #include <memory> 19 20 #include "examples/objcnativeapi/objc/objc_call_client.h" 21 22 @interface NADViewController () 23 24 @property(nonatomic) RTC_OBJC_TYPE(RTCCameraVideoCapturer) * capturer; 25 @property(nonatomic) RTC_OBJC_TYPE(RTCCameraPreviewView) * localVideoView; 26 @property(nonatomic) 27 __kindof UIView<RTC_OBJC_TYPE(RTCVideoRenderer)> *remoteVideoView; 28 @property(nonatomic) UIButton *callButton; 29 @property(nonatomic) UIButton *hangUpButton; 30 31 @end 32 33 @implementation NADViewController { 34 std::unique_ptr<webrtc_examples::ObjCCallClient> _call_client; 35 36 UIView *_view; 37 } 38 39 @synthesize capturer = _capturer; 40 @synthesize localVideoView = _localVideoView; 41 @synthesize remoteVideoView = _remoteVideoView; 42 @synthesize callButton = _callButton; 43 @synthesize hangUpButton = _hangUpButton; 44 45 #pragma mark - View controller lifecycle 46 47 - (void)loadView { 48 _view = [[UIView alloc] initWithFrame:CGRectZero]; 49 50 _remoteVideoView = 51 [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] initWithFrame:CGRectZero]; 52 _remoteVideoView.translatesAutoresizingMaskIntoConstraints = NO; 53 [_view addSubview:_remoteVideoView]; 54 55 _localVideoView = 56 [[RTC_OBJC_TYPE(RTCCameraPreviewView) alloc] initWithFrame:CGRectZero]; 57 _localVideoView.translatesAutoresizingMaskIntoConstraints = NO; 58 [_view addSubview:_localVideoView]; 59 60 _callButton = [UIButton buttonWithType:UIButtonTypeSystem]; 61 _callButton.translatesAutoresizingMaskIntoConstraints = NO; 62 [_callButton setTitle:@"Call" forState:UIControlStateNormal]; 63 [_callButton addTarget:self 64 action:@selector(call:) 65 forControlEvents:UIControlEventTouchUpInside]; 66 [_view addSubview:_callButton]; 67 68 _hangUpButton = [UIButton buttonWithType:UIButtonTypeSystem]; 69 _hangUpButton.translatesAutoresizingMaskIntoConstraints = NO; 70 [_hangUpButton setTitle:@"Hang up" forState:UIControlStateNormal]; 71 [_hangUpButton addTarget:self 72 action:@selector(hangUp:) 73 forControlEvents:UIControlEventTouchUpInside]; 74 [_view addSubview:_hangUpButton]; 75 76 UILayoutGuide *margin = _view.layoutMarginsGuide; 77 [_remoteVideoView.leadingAnchor constraintEqualToAnchor:margin.leadingAnchor] 78 .active = YES; 79 [_remoteVideoView.topAnchor constraintEqualToAnchor:margin.topAnchor].active = 80 YES; 81 [_remoteVideoView.trailingAnchor 82 constraintEqualToAnchor:margin.trailingAnchor] 83 .active = YES; 84 [_remoteVideoView.bottomAnchor constraintEqualToAnchor:margin.bottomAnchor] 85 .active = YES; 86 87 [_localVideoView.leadingAnchor constraintEqualToAnchor:margin.leadingAnchor 88 constant:8.0] 89 .active = YES; 90 [_localVideoView.topAnchor constraintEqualToAnchor:margin.topAnchor 91 constant:8.0] 92 .active = YES; 93 [_localVideoView.widthAnchor constraintEqualToConstant:60].active = YES; 94 [_localVideoView.heightAnchor constraintEqualToConstant:60].active = YES; 95 96 [_callButton.leadingAnchor constraintEqualToAnchor:margin.leadingAnchor 97 constant:8.0] 98 .active = YES; 99 [_callButton.bottomAnchor constraintEqualToAnchor:margin.bottomAnchor 100 constant:8.0] 101 .active = YES; 102 [_callButton.widthAnchor constraintEqualToConstant:100].active = YES; 103 [_callButton.heightAnchor constraintEqualToConstant:40].active = YES; 104 105 [_hangUpButton.trailingAnchor constraintEqualToAnchor:margin.trailingAnchor 106 constant:8.0] 107 .active = YES; 108 [_hangUpButton.bottomAnchor constraintEqualToAnchor:margin.bottomAnchor 109 constant:8.0] 110 .active = YES; 111 [_hangUpButton.widthAnchor constraintEqualToConstant:100].active = YES; 112 [_hangUpButton.heightAnchor constraintEqualToConstant:40].active = YES; 113 114 self.view = _view; 115 } 116 117 - (void)viewDidLoad { 118 [super viewDidLoad]; 119 120 self.capturer = [[RTC_OBJC_TYPE(RTCCameraVideoCapturer) alloc] init]; 121 self.localVideoView.captureSession = self.capturer.captureSession; 122 123 _call_client.reset(new webrtc_examples::ObjCCallClient()); 124 125 // Start capturer. 126 AVCaptureDevice *selectedDevice = nil; 127 NSArray<AVCaptureDevice *> *captureDevices = 128 [RTC_OBJC_TYPE(RTCCameraVideoCapturer) captureDevices]; 129 for (AVCaptureDevice *device in captureDevices) { 130 if (device.position == AVCaptureDevicePositionFront) { 131 selectedDevice = device; 132 break; 133 } 134 } 135 136 AVCaptureDeviceFormat *selectedFormat = nil; 137 int targetWidth = 640; 138 int targetHeight = 480; 139 int currentDiff = INT_MAX; 140 NSArray<AVCaptureDeviceFormat *> *formats = 141 [RTC_OBJC_TYPE(RTCCameraVideoCapturer) 142 supportedFormatsForDevice:selectedDevice]; 143 for (AVCaptureDeviceFormat *format in formats) { 144 CMVideoDimensions dimension = 145 CMVideoFormatDescriptionGetDimensions(format.formatDescription); 146 FourCharCode pixelFormat = 147 CMFormatDescriptionGetMediaSubType(format.formatDescription); 148 int diff = abs(targetWidth - dimension.width) + 149 abs(targetHeight - dimension.height); 150 if (diff < currentDiff) { 151 selectedFormat = format; 152 currentDiff = diff; 153 } else if (diff == currentDiff && 154 pixelFormat == [_capturer preferredOutputPixelFormat]) { 155 selectedFormat = format; 156 } 157 } 158 159 [self.capturer startCaptureWithDevice:selectedDevice 160 format:selectedFormat 161 fps:30]; 162 } 163 164 - (void)didReceiveMemoryWarning { 165 [super didReceiveMemoryWarning]; 166 // Dispose of any resources that can be recreated. 167 } 168 169 #pragma mark - Actions 170 171 - (IBAction)call:(id)sender { 172 _call_client->Call(self.capturer, self.remoteVideoView); 173 } 174 175 - (IBAction)hangUp:(id)sender { 176 _call_client->Hangup(); 177 } 178 179 @end