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