| Index: webrtc/examples/objc/AppRTCDemo/mac/APPRTCViewController.m
|
| diff --git a/webrtc/examples/objc/AppRTCDemo/mac/APPRTCViewController.m b/webrtc/examples/objc/AppRTCDemo/mac/APPRTCViewController.m
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..710b8a5ea40e1264c73d60d2c9be953e84111d93
|
| --- /dev/null
|
| +++ b/webrtc/examples/objc/AppRTCDemo/mac/APPRTCViewController.m
|
| @@ -0,0 +1,328 @@
|
| +/*
|
| + * Copyright 2014 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 "APPRTCViewController.h"
|
| +
|
| +#import <AVFoundation/AVFoundation.h>
|
| +
|
| +#import "WebRTC/RTCNSGLVideoView.h"
|
| +#import "WebRTC/RTCVideoTrack.h"
|
| +
|
| +#import "ARDAppClient.h"
|
| +
|
| +static NSUInteger const kContentWidth = 1280;
|
| +static NSUInteger const kContentHeight = 720;
|
| +static NSUInteger const kRoomFieldWidth = 80;
|
| +static NSUInteger const kLogViewHeight = 280;
|
| +static NSUInteger const kPreviewWidth = 490;
|
| +
|
| +@class APPRTCMainView;
|
| +@protocol APPRTCMainViewDelegate
|
| +
|
| +- (void)appRTCMainView:(APPRTCMainView*)mainView
|
| + didEnterRoomId:(NSString*)roomId;
|
| +
|
| +@end
|
| +
|
| +@interface APPRTCMainView : NSView
|
| +
|
| +@property(nonatomic, weak) id<APPRTCMainViewDelegate> delegate;
|
| +@property(nonatomic, readonly) RTCNSGLVideoView* localVideoView;
|
| +@property(nonatomic, readonly) RTCNSGLVideoView* remoteVideoView;
|
| +
|
| +- (void)displayLogMessage:(NSString*)message;
|
| +
|
| +@end
|
| +
|
| +@interface APPRTCMainView () <NSTextFieldDelegate, RTCNSGLVideoViewDelegate>
|
| +@end
|
| +@implementation APPRTCMainView {
|
| + NSScrollView* _scrollView;
|
| + NSTextField* _roomLabel;
|
| + NSTextField* _roomField;
|
| + NSTextView* _logView;
|
| + CGSize _localVideoSize;
|
| + CGSize _remoteVideoSize;
|
| +}
|
| +
|
| +@synthesize delegate = _delegate;
|
| +@synthesize localVideoView = _localVideoView;
|
| +@synthesize remoteVideoView = _remoteVideoView;
|
| +
|
| ++ (BOOL)requiresConstraintBasedLayout {
|
| + return YES;
|
| +}
|
| +
|
| +- (instancetype)initWithFrame:(NSRect)frame {
|
| + if (self = [super initWithFrame:frame]) {
|
| + [self setupViews];
|
| + }
|
| + return self;
|
| +}
|
| +
|
| +- (void)updateConstraints {
|
| + NSParameterAssert(
|
| + _roomField != nil && _scrollView != nil && _remoteVideoView != nil);
|
| + [self removeConstraints:[self constraints]];
|
| + NSDictionary* viewsDictionary =
|
| + NSDictionaryOfVariableBindings(_roomLabel,
|
| + _roomField,
|
| + _scrollView,
|
| + _remoteVideoView,
|
| + _localVideoView);
|
| +
|
| + NSSize remoteViewSize = [self remoteVideoViewSize];
|
| + NSDictionary* metrics = @{
|
| + @"kLogViewHeight" : @(kLogViewHeight),
|
| + @"kPreviewWidth" : @(kPreviewWidth),
|
| + @"kRoomFieldWidth" : @(kRoomFieldWidth),
|
| + @"remoteViewWidth" : @(remoteViewSize.width),
|
| + @"remoteViewHeight" : @(remoteViewSize.height),
|
| + @"localViewHeight" : @(remoteViewSize.height),
|
| + @"scrollViewWidth" : @(kContentWidth - kPreviewWidth),
|
| + };
|
| + // Declare this separately to avoid compiler warning about splitting string
|
| + // within an NSArray expression.
|
| + NSString* verticalConstraint =
|
| + @"V:|-[_roomLabel]-[_roomField]-[_scrollView(kLogViewHeight)]"
|
| + "-[_remoteVideoView(remoteViewHeight)]-|";
|
| + NSArray* constraintFormats = @[
|
| + verticalConstraint,
|
| + @"V:[_localVideoView]-[_remoteVideoView]",
|
| + @"V:[_localVideoView(kLogViewHeight)]",
|
| + @"|-[_roomLabel]",
|
| + @"|-[_roomField(kRoomFieldWidth)]",
|
| + @"|-[_scrollView(scrollViewWidth)]",
|
| + @"[_scrollView]-[_localVideoView]",
|
| + @"|-[_remoteVideoView(remoteViewWidth)]-|",
|
| + @"[_localVideoView(kPreviewWidth)]-|",
|
| + ];
|
| + for (NSString* constraintFormat in constraintFormats) {
|
| + NSArray* constraints =
|
| + [NSLayoutConstraint constraintsWithVisualFormat:constraintFormat
|
| + options:0
|
| + metrics:metrics
|
| + views:viewsDictionary];
|
| + for (NSLayoutConstraint* constraint in constraints) {
|
| + [self addConstraint:constraint];
|
| + }
|
| + }
|
| + [super updateConstraints];
|
| +}
|
| +
|
| +- (void)displayLogMessage:(NSString*)message {
|
| + _logView.string =
|
| + [NSString stringWithFormat:@"%@%@\n", _logView.string, message];
|
| + NSRange range = NSMakeRange([_logView.string length], 0);
|
| + [_logView scrollRangeToVisible:range];
|
| +}
|
| +
|
| +#pragma mark - NSControl delegate
|
| +
|
| +- (void)controlTextDidEndEditing:(NSNotification*)notification {
|
| + NSDictionary* userInfo = [notification userInfo];
|
| + NSInteger textMovement = [userInfo[@"NSTextMovement"] intValue];
|
| + if (textMovement == NSReturnTextMovement) {
|
| + [self.delegate appRTCMainView:self didEnterRoomId:_roomField.stringValue];
|
| + }
|
| +}
|
| +
|
| +#pragma mark - RTCNSGLVideoViewDelegate
|
| +
|
| +- (void)videoView:(RTCNSGLVideoView*)videoView
|
| + didChangeVideoSize:(NSSize)size {
|
| + if (videoView == _remoteVideoView) {
|
| + _remoteVideoSize = size;
|
| + } else if (videoView == _localVideoView) {
|
| + _localVideoSize = size;
|
| + } else {
|
| + return;
|
| + }
|
| + [self setNeedsUpdateConstraints:YES];
|
| +}
|
| +
|
| +#pragma mark - Private
|
| +
|
| +- (void)setupViews {
|
| + NSParameterAssert([[self subviews] count] == 0);
|
| +
|
| + _roomLabel = [[NSTextField alloc] initWithFrame:NSZeroRect];
|
| + [_roomLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
|
| + [_roomLabel setBezeled:NO];
|
| + [_roomLabel setDrawsBackground:NO];
|
| + [_roomLabel setEditable:NO];
|
| + [_roomLabel setStringValue:@"Enter AppRTC room id:"];
|
| + [self addSubview:_roomLabel];
|
| +
|
| + _roomField = [[NSTextField alloc] initWithFrame:NSZeroRect];
|
| + [_roomField setTranslatesAutoresizingMaskIntoConstraints:NO];
|
| + [self addSubview:_roomField];
|
| + [_roomField setEditable:YES];
|
| + [_roomField setDelegate:self];
|
| +
|
| + _logView = [[NSTextView alloc] initWithFrame:NSZeroRect];
|
| + [_logView setMinSize:NSMakeSize(0, kLogViewHeight)];
|
| + [_logView setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
|
| + [_logView setVerticallyResizable:YES];
|
| + [_logView setAutoresizingMask:NSViewWidthSizable];
|
| + NSTextContainer* textContainer = [_logView textContainer];
|
| + NSSize containerSize = NSMakeSize(kContentWidth, FLT_MAX);
|
| + [textContainer setContainerSize:containerSize];
|
| + [textContainer setWidthTracksTextView:YES];
|
| + [_logView setEditable:NO];
|
| +
|
| + _scrollView = [[NSScrollView alloc] initWithFrame:NSZeroRect];
|
| + [_scrollView setTranslatesAutoresizingMaskIntoConstraints:NO];
|
| + [_scrollView setHasVerticalScroller:YES];
|
| + [_scrollView setDocumentView:_logView];
|
| + [self addSubview:_scrollView];
|
| +
|
| + NSOpenGLPixelFormatAttribute attributes[] = {
|
| + NSOpenGLPFADoubleBuffer,
|
| + NSOpenGLPFADepthSize, 24,
|
| + NSOpenGLPFAOpenGLProfile,
|
| + NSOpenGLProfileVersion3_2Core,
|
| + 0
|
| + };
|
| + NSOpenGLPixelFormat* pixelFormat =
|
| + [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
|
| + _remoteVideoView = [[RTCNSGLVideoView alloc] initWithFrame:NSZeroRect
|
| + pixelFormat:pixelFormat];
|
| + [_remoteVideoView setTranslatesAutoresizingMaskIntoConstraints:NO];
|
| + _remoteVideoView.delegate = self;
|
| + [self addSubview:_remoteVideoView];
|
| +
|
| + _localVideoView = [[RTCNSGLVideoView alloc] initWithFrame:NSZeroRect
|
| + pixelFormat:pixelFormat];
|
| + [_localVideoView setTranslatesAutoresizingMaskIntoConstraints:NO];
|
| + _localVideoView.delegate = self;
|
| + [self addSubview:_localVideoView];
|
| +}
|
| +
|
| +- (NSSize)remoteVideoViewSize {
|
| + NSInteger width = MAX(_remoteVideoSize.width, kContentWidth);
|
| + NSInteger height = (width/16) * 9;
|
| + return NSMakeSize(width, height);
|
| +}
|
| +
|
| +@end
|
| +
|
| +@interface APPRTCViewController ()
|
| + <ARDAppClientDelegate, APPRTCMainViewDelegate>
|
| +@property(nonatomic, readonly) APPRTCMainView* mainView;
|
| +@end
|
| +
|
| +@implementation APPRTCViewController {
|
| + ARDAppClient* _client;
|
| + RTCVideoTrack* _localVideoTrack;
|
| + RTCVideoTrack* _remoteVideoTrack;
|
| +}
|
| +
|
| +- (void)dealloc {
|
| + [self disconnect];
|
| +}
|
| +
|
| +- (void)loadView {
|
| + APPRTCMainView* view = [[APPRTCMainView alloc] initWithFrame:NSZeroRect];
|
| + [view setTranslatesAutoresizingMaskIntoConstraints:NO];
|
| + view.delegate = self;
|
| + self.view = view;
|
| +}
|
| +
|
| +- (void)windowWillClose:(NSNotification*)notification {
|
| + [self disconnect];
|
| +}
|
| +
|
| +#pragma mark - ARDAppClientDelegate
|
| +
|
| +- (void)appClient:(ARDAppClient *)client
|
| + didChangeState:(ARDAppClientState)state {
|
| + switch (state) {
|
| + case kARDAppClientStateConnected:
|
| + NSLog(@"Client connected.");
|
| + break;
|
| + case kARDAppClientStateConnecting:
|
| + NSLog(@"Client connecting.");
|
| + break;
|
| + case kARDAppClientStateDisconnected:
|
| + NSLog(@"Client disconnected.");
|
| + [self resetUI];
|
| + _client = nil;
|
| + break;
|
| + }
|
| +}
|
| +
|
| +- (void)appClient:(ARDAppClient *)client
|
| + didChangeConnectionState:(RTCIceConnectionState)state {
|
| +}
|
| +
|
| +- (void)appClient:(ARDAppClient *)client
|
| + didReceiveLocalVideoTrack:(RTCVideoTrack *)localVideoTrack {
|
| + _localVideoTrack = localVideoTrack;
|
| + [_localVideoTrack addRenderer:self.mainView.localVideoView];
|
| +}
|
| +
|
| +- (void)appClient:(ARDAppClient *)client
|
| + didReceiveRemoteVideoTrack:(RTCVideoTrack *)remoteVideoTrack {
|
| + _remoteVideoTrack = remoteVideoTrack;
|
| + [_remoteVideoTrack addRenderer:self.mainView.remoteVideoView];
|
| +}
|
| +
|
| +- (void)appClient:(ARDAppClient *)client
|
| + didError:(NSError *)error {
|
| + [self showAlertWithMessage:[NSString stringWithFormat:@"%@", error]];
|
| + [self disconnect];
|
| +}
|
| +
|
| +- (void)appClient:(ARDAppClient *)client
|
| + didGetStats:(NSArray *)stats {
|
| +}
|
| +
|
| +#pragma mark - APPRTCMainViewDelegate
|
| +
|
| +- (void)appRTCMainView:(APPRTCMainView*)mainView
|
| + didEnterRoomId:(NSString*)roomId {
|
| + [_client disconnect];
|
| + ARDAppClient *client = [[ARDAppClient alloc] initWithDelegate:self];
|
| + [client connectToRoomWithId:roomId
|
| + isLoopback:NO
|
| + isAudioOnly:NO
|
| + shouldMakeAecDump:NO
|
| + shouldUseLevelControl:NO];
|
| + _client = client;
|
| +}
|
| +
|
| +#pragma mark - Private
|
| +
|
| +- (APPRTCMainView*)mainView {
|
| + return (APPRTCMainView*)self.view;
|
| +}
|
| +
|
| +- (void)showAlertWithMessage:(NSString*)message {
|
| + NSAlert* alert = [[NSAlert alloc] init];
|
| + [alert setMessageText:message];
|
| + [alert runModal];
|
| +}
|
| +
|
| +- (void)resetUI {
|
| + [_remoteVideoTrack removeRenderer:self.mainView.remoteVideoView];
|
| + [_localVideoTrack removeRenderer:self.mainView.localVideoView];
|
| + _remoteVideoTrack = nil;
|
| + _localVideoTrack = nil;
|
| + [self.mainView.remoteVideoView renderFrame:nil];
|
| + [self.mainView.localVideoView renderFrame:nil];
|
| +}
|
| +
|
| +- (void)disconnect {
|
| + [self resetUI];
|
| + [_client disconnect];
|
| +}
|
| +
|
| +@end
|
|
|