diff options
Diffstat (limited to 'third_party/libwebrtc/examples/objc/AppRTCMobile/ios/ARDVideoCallView.m')
-rw-r--r-- | third_party/libwebrtc/examples/objc/AppRTCMobile/ios/ARDVideoCallView.m | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/third_party/libwebrtc/examples/objc/AppRTCMobile/ios/ARDVideoCallView.m b/third_party/libwebrtc/examples/objc/AppRTCMobile/ios/ARDVideoCallView.m new file mode 100644 index 0000000000..437aea8d56 --- /dev/null +++ b/third_party/libwebrtc/examples/objc/AppRTCMobile/ios/ARDVideoCallView.m @@ -0,0 +1,213 @@ +/* + * Copyright 2015 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 "ARDVideoCallView.h" + +#import <AVFoundation/AVFoundation.h> + +#import "sdk/objc/components/renderer/metal/RTCMTLVideoView.h" + +#import "UIImage+ARDUtilities.h" + +static CGFloat const kButtonPadding = 16; +static CGFloat const kButtonSize = 48; +static CGFloat const kLocalVideoViewSize = 120; +static CGFloat const kLocalVideoViewPadding = 8; +static CGFloat const kStatusBarHeight = 20; + +@interface ARDVideoCallView () <RTC_OBJC_TYPE (RTCVideoViewDelegate)> +@end + +@implementation ARDVideoCallView { + UIButton *_routeChangeButton; + UIButton *_cameraSwitchButton; + UIButton *_hangupButton; + CGSize _remoteVideoSize; +} + +@synthesize statusLabel = _statusLabel; +@synthesize localVideoView = _localVideoView; +@synthesize remoteVideoView = _remoteVideoView; +@synthesize statsView = _statsView; +@synthesize delegate = _delegate; + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + + _remoteVideoView = [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] initWithFrame:CGRectZero]; + + [self addSubview:_remoteVideoView]; + + _localVideoView = [[RTC_OBJC_TYPE(RTCCameraPreviewView) alloc] initWithFrame:CGRectZero]; + [self addSubview:_localVideoView]; + + _statsView = [[ARDStatsView alloc] initWithFrame:CGRectZero]; + _statsView.hidden = YES; + [self addSubview:_statsView]; + + _routeChangeButton = [UIButton buttonWithType:UIButtonTypeCustom]; + _routeChangeButton.backgroundColor = [UIColor grayColor]; + _routeChangeButton.layer.cornerRadius = kButtonSize / 2; + _routeChangeButton.layer.masksToBounds = YES; + UIImage *image = [UIImage imageForName:@"ic_surround_sound_black_24dp.png" + color:[UIColor whiteColor]]; + [_routeChangeButton setImage:image forState:UIControlStateNormal]; + [_routeChangeButton addTarget:self + action:@selector(onRouteChange:) + forControlEvents:UIControlEventTouchUpInside]; + [self addSubview:_routeChangeButton]; + + // TODO(tkchin): don't display this if we can't actually do camera switch. + _cameraSwitchButton = [UIButton buttonWithType:UIButtonTypeCustom]; + _cameraSwitchButton.backgroundColor = [UIColor grayColor]; + _cameraSwitchButton.layer.cornerRadius = kButtonSize / 2; + _cameraSwitchButton.layer.masksToBounds = YES; + image = [UIImage imageForName:@"ic_switch_video_black_24dp.png" color:[UIColor whiteColor]]; + [_cameraSwitchButton setImage:image forState:UIControlStateNormal]; + [_cameraSwitchButton addTarget:self + action:@selector(onCameraSwitch:) + forControlEvents:UIControlEventTouchUpInside]; + [self addSubview:_cameraSwitchButton]; + + _hangupButton = [UIButton buttonWithType:UIButtonTypeCustom]; + _hangupButton.backgroundColor = [UIColor redColor]; + _hangupButton.layer.cornerRadius = kButtonSize / 2; + _hangupButton.layer.masksToBounds = YES; + image = [UIImage imageForName:@"ic_call_end_black_24dp.png" + color:[UIColor whiteColor]]; + [_hangupButton setImage:image forState:UIControlStateNormal]; + [_hangupButton addTarget:self + action:@selector(onHangup:) + forControlEvents:UIControlEventTouchUpInside]; + [self addSubview:_hangupButton]; + + _statusLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + _statusLabel.font = [UIFont fontWithName:@"Roboto" size:16]; + _statusLabel.textColor = [UIColor whiteColor]; + [self addSubview:_statusLabel]; + + UITapGestureRecognizer *tapRecognizer = + [[UITapGestureRecognizer alloc] + initWithTarget:self + action:@selector(didTripleTap:)]; + tapRecognizer.numberOfTapsRequired = 3; + [self addGestureRecognizer:tapRecognizer]; + } + return self; +} + +- (void)layoutSubviews { + CGRect bounds = self.bounds; + if (_remoteVideoSize.width > 0 && _remoteVideoSize.height > 0) { + // Aspect fill remote video into bounds. + CGRect remoteVideoFrame = + AVMakeRectWithAspectRatioInsideRect(_remoteVideoSize, bounds); + CGFloat scale = 1; + if (remoteVideoFrame.size.width > remoteVideoFrame.size.height) { + // Scale by height. + scale = bounds.size.height / remoteVideoFrame.size.height; + } else { + // Scale by width. + scale = bounds.size.width / remoteVideoFrame.size.width; + } + remoteVideoFrame.size.height *= scale; + remoteVideoFrame.size.width *= scale; + _remoteVideoView.frame = remoteVideoFrame; + _remoteVideoView.center = + CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds)); + } else { + _remoteVideoView.frame = bounds; + } + + // Aspect fit local video view into a square box. + CGRect localVideoFrame = + CGRectMake(0, 0, kLocalVideoViewSize, kLocalVideoViewSize); + // Place the view in the bottom right. + localVideoFrame.origin.x = CGRectGetMaxX(bounds) + - localVideoFrame.size.width - kLocalVideoViewPadding; + localVideoFrame.origin.y = CGRectGetMaxY(bounds) + - localVideoFrame.size.height - kLocalVideoViewPadding; + _localVideoView.frame = localVideoFrame; + + // Place stats at the top. + CGSize statsSize = [_statsView sizeThatFits:bounds.size]; + _statsView.frame = CGRectMake(CGRectGetMinX(bounds), + CGRectGetMinY(bounds) + kStatusBarHeight, + statsSize.width, statsSize.height); + + // Place hangup button in the bottom left. + _hangupButton.frame = + CGRectMake(CGRectGetMinX(bounds) + kButtonPadding, + CGRectGetMaxY(bounds) - kButtonPadding - + kButtonSize, + kButtonSize, + kButtonSize); + + // Place button to the right of hangup button. + CGRect cameraSwitchFrame = _hangupButton.frame; + cameraSwitchFrame.origin.x = + CGRectGetMaxX(cameraSwitchFrame) + kButtonPadding; + _cameraSwitchButton.frame = cameraSwitchFrame; + + // Place route button to the right of camera button. + CGRect routeChangeFrame = _cameraSwitchButton.frame; + routeChangeFrame.origin.x = + CGRectGetMaxX(routeChangeFrame) + kButtonPadding; + _routeChangeButton.frame = routeChangeFrame; + + [_statusLabel sizeToFit]; + _statusLabel.center = + CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds)); +} + +#pragma mark - RTC_OBJC_TYPE(RTCVideoViewDelegate) + +- (void)videoView:(id<RTC_OBJC_TYPE(RTCVideoRenderer)>)videoView didChangeVideoSize:(CGSize)size { + if (videoView == _remoteVideoView) { + _remoteVideoSize = size; + } + [self setNeedsLayout]; +} + +#pragma mark - Private + +- (void)onCameraSwitch:(UIButton *)sender { + sender.enabled = false; + [_delegate videoCallView:self + shouldSwitchCameraWithCompletion:^(NSError *error) { + dispatch_async(dispatch_get_main_queue(), ^(void) { + sender.enabled = true; + }); + }]; +} + +- (void)onRouteChange:(UIButton *)sender { + sender.enabled = false; + __weak ARDVideoCallView *weakSelf = self; + [_delegate videoCallView:self + shouldChangeRouteWithCompletion:^(void) { + ARDVideoCallView *strongSelf = weakSelf; + if (strongSelf) { + dispatch_async(dispatch_get_main_queue(), ^(void) { + sender.enabled = true; + }); + } + }]; +} + +- (void)onHangup:(id)sender { + [_delegate videoCallViewDidHangup:self]; +} + +- (void)didTripleTap:(UITapGestureRecognizer *)recognizer { + [_delegate videoCallViewDidEnableStats:self]; +} + +@end |