/* * Copyright 2018 The WebRTC Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #import "NADViewController.h" #import "sdk/objc/base/RTCVideoRenderer.h" #import "sdk/objc/components/capturer/RTCCameraVideoCapturer.h" #import "sdk/objc/components/renderer/metal/RTCMTLVideoView.h" #import "sdk/objc/helpers/RTCCameraPreviewView.h" #include #include "examples/objcnativeapi/objc/objc_call_client.h" @interface NADViewController () @property(nonatomic) RTC_OBJC_TYPE(RTCCameraVideoCapturer) * capturer; @property(nonatomic) RTC_OBJC_TYPE(RTCCameraPreviewView) * localVideoView; @property(nonatomic) __kindof UIView *remoteVideoView; @property(nonatomic) UIButton *callButton; @property(nonatomic) UIButton *hangUpButton; @end @implementation NADViewController { std::unique_ptr _call_client; UIView *_view; } @synthesize capturer = _capturer; @synthesize localVideoView = _localVideoView; @synthesize remoteVideoView = _remoteVideoView; @synthesize callButton = _callButton; @synthesize hangUpButton = _hangUpButton; #pragma mark - View controller lifecycle - (void)loadView { _view = [[UIView alloc] initWithFrame:CGRectZero]; _remoteVideoView = [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] initWithFrame:CGRectZero]; _remoteVideoView.translatesAutoresizingMaskIntoConstraints = NO; [_view addSubview:_remoteVideoView]; _localVideoView = [[RTC_OBJC_TYPE(RTCCameraPreviewView) alloc] initWithFrame:CGRectZero]; _localVideoView.translatesAutoresizingMaskIntoConstraints = NO; [_view addSubview:_localVideoView]; _callButton = [UIButton buttonWithType:UIButtonTypeSystem]; _callButton.translatesAutoresizingMaskIntoConstraints = NO; [_callButton setTitle:@"Call" forState:UIControlStateNormal]; [_callButton addTarget:self action:@selector(call:) forControlEvents:UIControlEventTouchUpInside]; [_view addSubview:_callButton]; _hangUpButton = [UIButton buttonWithType:UIButtonTypeSystem]; _hangUpButton.translatesAutoresizingMaskIntoConstraints = NO; [_hangUpButton setTitle:@"Hang up" forState:UIControlStateNormal]; [_hangUpButton addTarget:self action:@selector(hangUp:) forControlEvents:UIControlEventTouchUpInside]; [_view addSubview:_hangUpButton]; UILayoutGuide *margin = _view.layoutMarginsGuide; [_remoteVideoView.leadingAnchor constraintEqualToAnchor:margin.leadingAnchor].active = YES; [_remoteVideoView.topAnchor constraintEqualToAnchor:margin.topAnchor].active = YES; [_remoteVideoView.trailingAnchor constraintEqualToAnchor:margin.trailingAnchor].active = YES; [_remoteVideoView.bottomAnchor constraintEqualToAnchor:margin.bottomAnchor].active = YES; [_localVideoView.leadingAnchor constraintEqualToAnchor:margin.leadingAnchor constant:8.0].active = YES; [_localVideoView.topAnchor constraintEqualToAnchor:margin.topAnchor constant:8.0].active = YES; [_localVideoView.widthAnchor constraintEqualToConstant:60].active = YES; [_localVideoView.heightAnchor constraintEqualToConstant:60].active = YES; [_callButton.leadingAnchor constraintEqualToAnchor:margin.leadingAnchor constant:8.0].active = YES; [_callButton.bottomAnchor constraintEqualToAnchor:margin.bottomAnchor constant:8.0].active = YES; [_callButton.widthAnchor constraintEqualToConstant:100].active = YES; [_callButton.heightAnchor constraintEqualToConstant:40].active = YES; [_hangUpButton.trailingAnchor constraintEqualToAnchor:margin.trailingAnchor constant:8.0].active = YES; [_hangUpButton.bottomAnchor constraintEqualToAnchor:margin.bottomAnchor constant:8.0].active = YES; [_hangUpButton.widthAnchor constraintEqualToConstant:100].active = YES; [_hangUpButton.heightAnchor constraintEqualToConstant:40].active = YES; self.view = _view; } - (void)viewDidLoad { [super viewDidLoad]; self.capturer = [[RTC_OBJC_TYPE(RTCCameraVideoCapturer) alloc] init]; self.localVideoView.captureSession = self.capturer.captureSession; _call_client.reset(new webrtc_examples::ObjCCallClient()); // Start capturer. AVCaptureDevice *selectedDevice = nil; NSArray *captureDevices = [RTC_OBJC_TYPE(RTCCameraVideoCapturer) captureDevices]; for (AVCaptureDevice *device in captureDevices) { if (device.position == AVCaptureDevicePositionFront) { selectedDevice = device; break; } } AVCaptureDeviceFormat *selectedFormat = nil; int targetWidth = 640; int targetHeight = 480; int currentDiff = INT_MAX; NSArray *formats = [RTC_OBJC_TYPE(RTCCameraVideoCapturer) supportedFormatsForDevice:selectedDevice]; for (AVCaptureDeviceFormat *format in formats) { CMVideoDimensions dimension = CMVideoFormatDescriptionGetDimensions(format.formatDescription); FourCharCode pixelFormat = CMFormatDescriptionGetMediaSubType(format.formatDescription); int diff = abs(targetWidth - dimension.width) + abs(targetHeight - dimension.height); if (diff < currentDiff) { selectedFormat = format; currentDiff = diff; } else if (diff == currentDiff && pixelFormat == [_capturer preferredOutputPixelFormat]) { selectedFormat = format; } } [self.capturer startCaptureWithDevice:selectedDevice format:selectedFormat fps:30]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #pragma mark - Actions - (IBAction)call:(id)sender { _call_client->Call(self.capturer, self.remoteVideoView); } - (IBAction)hangUp:(id)sender { _call_client->Hangup(); } @end