Add setting to AppRTCMobile for iOS, that can change capture resolution.
To achieve this, several changes needed to be made on both UI and app logic level. * Settings view controller is added (modally shown when the settings button is pressed). - From there the user can see the current capture resolution and select another capture resolution. * Model class for the capture resolution added. - Improves readability and makes separation of concerns cleaner - Handles persisting - Provides defaults - Maps video resolution setting to RTCMediaConstraints dictionary * Test for the model class In future it would be possible to extend this CL and add further settings (i.e bit rate). Also it would be easy to remove the hardcoded resolutions and use dynamic values depending on device capability. BUG=webrtc:6473 Review-Url: https://codereview.webrtc.org/2462623002 Cr-Commit-Position: refs/heads/master@{#14881}
This commit is contained in:
parent
b763e39beb
commit
d17d536577
@ -241,6 +241,12 @@ if (is_ios || (is_mac && target_cpu != "x86")) {
|
||||
"objc/AppRTCMobile/ios/ARDMainView.m",
|
||||
"objc/AppRTCMobile/ios/ARDMainViewController.h",
|
||||
"objc/AppRTCMobile/ios/ARDMainViewController.m",
|
||||
"objc/AppRTCMobile/ios/ARDMediaConstraintsModel.h",
|
||||
"objc/AppRTCMobile/ios/ARDMediaConstraintsModel.m",
|
||||
"objc/AppRTCMobile/ios/ARDMediaConstraintsSettingsStore.h",
|
||||
"objc/AppRTCMobile/ios/ARDMediaConstraintsSettingsStore.m",
|
||||
"objc/AppRTCMobile/ios/ARDSettingsViewController.h",
|
||||
"objc/AppRTCMobile/ios/ARDSettingsViewController.m",
|
||||
"objc/AppRTCMobile/ios/ARDStatsView.h",
|
||||
"objc/AppRTCMobile/ios/ARDStatsView.m",
|
||||
"objc/AppRTCMobile/ios/ARDVideoCallView.h",
|
||||
|
||||
@ -23,6 +23,8 @@ typedef NS_ENUM(NSInteger, ARDAppClientState) {
|
||||
};
|
||||
|
||||
@class ARDAppClient;
|
||||
@class RTCMediaConstraints;
|
||||
|
||||
// The delegate is informed of pertinent events and will be called on the
|
||||
// main queue.
|
||||
@protocol ARDAppClientDelegate <NSObject>
|
||||
@ -56,11 +58,13 @@ typedef NS_ENUM(NSInteger, ARDAppClientState) {
|
||||
@property(nonatomic, assign) BOOL shouldGetStats;
|
||||
@property(nonatomic, readonly) ARDAppClientState state;
|
||||
@property(nonatomic, weak) id<ARDAppClientDelegate> delegate;
|
||||
|
||||
// Convenience constructor since all expected use cases will need a delegate
|
||||
// in order to receive remote tracks.
|
||||
- (instancetype)initWithDelegate:(id<ARDAppClientDelegate>)delegate;
|
||||
|
||||
// Sets camera constraints.
|
||||
- (void)setCameraConstraints:(RTCMediaConstraints *)mediaConstraints;
|
||||
|
||||
// Establishes a connection with the AppRTC servers for the given room id.
|
||||
// If |isLoopback| is true, the call will connect to itself.
|
||||
// If |isAudioOnly| is true, video will be disabled for the call.
|
||||
|
||||
@ -101,6 +101,7 @@ static int64_t const kARDAppClientRtcEventLogMaxSizeInBytes = 5e6; // 5 MB.
|
||||
@implementation ARDAppClient {
|
||||
RTCFileLogger *_fileLogger;
|
||||
ARDTimerProxy *_statsTimer;
|
||||
RTCMediaConstraints *_cameraConstraints;
|
||||
}
|
||||
|
||||
@synthesize shouldGetStats = _shouldGetStats;
|
||||
@ -321,6 +322,10 @@ static int64_t const kARDAppClientRtcEventLogMaxSizeInBytes = 5e6; // 5 MB.
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)setCameraConstraints:(RTCMediaConstraints *)mediaConstraints {
|
||||
_cameraConstraints = mediaConstraints;
|
||||
}
|
||||
|
||||
#pragma mark - ARDSignalingChannelDelegate
|
||||
|
||||
- (void)channel:(id<ARDSignalingChannel>)channel
|
||||
@ -695,10 +700,10 @@ static int64_t const kARDAppClientRtcEventLogMaxSizeInBytes = 5e6; // 5 MB.
|
||||
// trying to open a local stream.
|
||||
#if !TARGET_IPHONE_SIMULATOR
|
||||
if (!_isAudioOnly) {
|
||||
RTCMediaConstraints *mediaConstraints =
|
||||
[self defaultMediaStreamConstraints];
|
||||
RTCMediaConstraints *cameraConstraints =
|
||||
[self cameraConstraints];
|
||||
RTCAVFoundationVideoSource *source =
|
||||
[_factory avFoundationVideoSourceWithConstraints:mediaConstraints];
|
||||
[_factory avFoundationVideoSourceWithConstraints:cameraConstraints];
|
||||
localVideoTrack =
|
||||
[_factory videoTrackWithSource:source
|
||||
trackId:kARDVideoTrackId];
|
||||
@ -737,18 +742,14 @@ static int64_t const kARDAppClientRtcEventLogMaxSizeInBytes = 5e6; // 5 MB.
|
||||
NSString *valueLevelControl = _shouldUseLevelControl ?
|
||||
kRTCMediaConstraintsValueTrue : kRTCMediaConstraintsValueFalse;
|
||||
NSDictionary *mandatoryConstraints = @{ kRTCMediaConstraintsLevelControl : valueLevelControl };
|
||||
RTCMediaConstraints* constraints =
|
||||
[[RTCMediaConstraints alloc] initWithMandatoryConstraints:mandatoryConstraints
|
||||
optionalConstraints:nil];
|
||||
RTCMediaConstraints *constraints =
|
||||
[[RTCMediaConstraints alloc] initWithMandatoryConstraints:mandatoryConstraints
|
||||
optionalConstraints:nil];
|
||||
return constraints;
|
||||
}
|
||||
|
||||
- (RTCMediaConstraints *)defaultMediaStreamConstraints {
|
||||
RTCMediaConstraints* constraints =
|
||||
[[RTCMediaConstraints alloc]
|
||||
initWithMandatoryConstraints:nil
|
||||
optionalConstraints:nil];
|
||||
return constraints;
|
||||
- (RTCMediaConstraints *)cameraConstraints {
|
||||
return _cameraConstraints;
|
||||
}
|
||||
|
||||
- (RTCMediaConstraints *)defaultAnswerConstraints {
|
||||
|
||||
@ -19,9 +19,11 @@
|
||||
|
||||
#import "ARDAppClient.h"
|
||||
#import "ARDMainView.h"
|
||||
#import "ARDMediaConstraintsModel.h"
|
||||
#import "ARDSettingsViewController.h"
|
||||
#import "ARDVideoCallViewController.h"
|
||||
|
||||
static NSString *barButtonImageString = @"ic_settings_black_24dp.png";
|
||||
static NSString *const barButtonImageString = @"ic_settings_black_24dp.png";
|
||||
|
||||
@interface ARDMainViewController () <
|
||||
ARDMainViewDelegate,
|
||||
@ -169,6 +171,16 @@ static NSString *barButtonImageString = @"ic_settings_black_24dp.png";
|
||||
|
||||
#pragma mark - Private
|
||||
- (void)showSettings:(id)sender {
|
||||
ARDSettingsViewController *settingsController =
|
||||
[[ARDSettingsViewController alloc] initWithStyle:UITableViewStylePlain
|
||||
mediaConstraintsModel:[[ARDMediaConstraintsModel alloc] init]];
|
||||
UINavigationController *navigationController =
|
||||
[[UINavigationController alloc] initWithRootViewController:settingsController];
|
||||
[self presentViewControllerAsModal:navigationController];
|
||||
}
|
||||
|
||||
- (void)presentViewControllerAsModal:(UIViewController *)viewController {
|
||||
[self presentViewController:viewController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)configureAudioSession {
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2016 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 <Foundation/Foundation.h>
|
||||
#import "ARDMediaConstraintsModel.h"
|
||||
|
||||
@class ARDMediaConstraintsSettingsStore;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@interface ARDMediaConstraintsModel ()
|
||||
- (ARDMediaConstraintsSettingsStore *)settingsStore;
|
||||
- (nullable NSString *)currentVideoResolutionWidthFromStore;
|
||||
- (nullable NSString *)currentVideoResolutionHeightFromStore;
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2016 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 <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
/**
|
||||
* Model class for user defined media constraints.
|
||||
*
|
||||
* Currently used for streaming media constraints only.
|
||||
* In future audio media constraints support can be added as well.
|
||||
* Offers list of avaliable video resolutions that can construct streaming media constraint.
|
||||
* Exposes methods for reading and storing media constraints from persistent store.
|
||||
* Also translates current user defined media constraint into RTCMediaConstraints
|
||||
* dictionary.
|
||||
*/
|
||||
@interface ARDMediaConstraintsModel : NSObject
|
||||
|
||||
/**
|
||||
* Returns array of available capture resoultions.
|
||||
*
|
||||
* The capture resolutions are represented as strings in the following format
|
||||
* [width]x[height]
|
||||
*/
|
||||
- (NSArray<NSString *> *)availableVideoResoultionsMediaConstraints;
|
||||
|
||||
/**
|
||||
* Returns current video resolution media constraint string.
|
||||
* If no constraint is in store, default value of 640x480 is returned.
|
||||
* When defaulting to value, the default is saved in store for consistency reasons.
|
||||
*/
|
||||
- (NSString *)currentVideoResoultionConstraintFromStore;
|
||||
|
||||
/**
|
||||
* Stores the provided video resolution media constraint string into the store.
|
||||
*
|
||||
* If the provided constraint is no part of the available video resolutions
|
||||
* the store operation will not be executed and NO will be returned.
|
||||
* @param constraint the string to be stored.
|
||||
* @return YES/NO depending on success.
|
||||
*/
|
||||
- (BOOL)storeVideoResoultionConstraint:(NSString *)constraint;
|
||||
|
||||
/**
|
||||
* Converts the current media constraints from store into dictionary with RTCMediaConstraints
|
||||
* values.
|
||||
*
|
||||
* @return NSDictionary with RTC width and height parameters
|
||||
*/
|
||||
- (nullable NSDictionary *)currentMediaConstraintFromStoreAsRTCDictionary;
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
104
webrtc/examples/objc/AppRTCMobile/ios/ARDMediaConstraintsModel.m
Normal file
104
webrtc/examples/objc/AppRTCMobile/ios/ARDMediaConstraintsModel.m
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2016 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 "ARDMediaConstraintsModel+Private.h"
|
||||
#import "ARDMediaConstraintsSettingsStore.h"
|
||||
#import "WebRTC/RTCMediaConstraints.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
static NSArray<NSString *> *videoResolutionsStaticValues() {
|
||||
return @[ @"640x480", @"960x540", @"1280x720" ];
|
||||
}
|
||||
|
||||
@interface ARDMediaConstraintsModel () {
|
||||
ARDMediaConstraintsSettingsStore *_settingsStore;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation ARDMediaConstraintsModel
|
||||
|
||||
- (NSArray<NSString *> *)availableVideoResoultionsMediaConstraints {
|
||||
return videoResolutionsStaticValues();
|
||||
}
|
||||
|
||||
- (NSString *)currentVideoResoultionConstraintFromStore {
|
||||
NSString *constraint = [[self settingsStore] videoResolutionConstraintsSetting];
|
||||
if (!constraint) {
|
||||
constraint = [self defaultVideoResolutionMediaConstraint];
|
||||
// To ensure consistency add the default to the store.
|
||||
[[self settingsStore] setVideoResolutionConstraintsSetting:constraint];
|
||||
}
|
||||
return constraint;
|
||||
}
|
||||
|
||||
- (BOOL)storeVideoResoultionConstraint:(NSString *)constraint {
|
||||
if (![[self availableVideoResoultionsMediaConstraints] containsObject:constraint]) {
|
||||
return NO;
|
||||
}
|
||||
[[self settingsStore] setVideoResolutionConstraintsSetting:constraint];
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - Testable
|
||||
|
||||
- (ARDMediaConstraintsSettingsStore *)settingsStore {
|
||||
if (!_settingsStore) {
|
||||
_settingsStore = [[ARDMediaConstraintsSettingsStore alloc] init];
|
||||
}
|
||||
return _settingsStore;
|
||||
}
|
||||
|
||||
- (nullable NSString *)currentVideoResolutionWidthFromStore {
|
||||
NSString *mediaConstraintFromStore = [self currentVideoResoultionConstraintFromStore];
|
||||
|
||||
return [self videoResolutionComponentAtIndex:0 inConstraintsString:mediaConstraintFromStore];
|
||||
}
|
||||
|
||||
- (nullable NSString *)currentVideoResolutionHeightFromStore {
|
||||
NSString *mediaConstraintFromStore = [self currentVideoResoultionConstraintFromStore];
|
||||
return [self videoResolutionComponentAtIndex:1 inConstraintsString:mediaConstraintFromStore];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSString *)defaultVideoResolutionMediaConstraint {
|
||||
return videoResolutionsStaticValues()[0];
|
||||
}
|
||||
|
||||
- (nullable NSString *)videoResolutionComponentAtIndex:(int)index
|
||||
inConstraintsString:(NSString *)constraint {
|
||||
if (index != 0 && index != 1) {
|
||||
return nil;
|
||||
}
|
||||
NSArray *components = [constraint componentsSeparatedByString:@"x"];
|
||||
if (components.count != 2) {
|
||||
return nil;
|
||||
}
|
||||
return components[index];
|
||||
}
|
||||
|
||||
#pragma mark - Conversion to RTCMediaConstraints
|
||||
|
||||
- (nullable NSDictionary *)currentMediaConstraintFromStoreAsRTCDictionary {
|
||||
NSDictionary *mediaConstraintsDictionary = nil;
|
||||
|
||||
NSString *widthConstraint = [self currentVideoResolutionWidthFromStore];
|
||||
NSString *heightConstraint = [self currentVideoResolutionHeightFromStore];
|
||||
if (widthConstraint && heightConstraint) {
|
||||
mediaConstraintsDictionary = @{
|
||||
kRTCMediaConstraintsMinWidth : widthConstraint,
|
||||
kRTCMediaConstraintsMinHeight : heightConstraint
|
||||
};
|
||||
}
|
||||
return mediaConstraintsDictionary;
|
||||
}
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2016 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 <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* Light-weight persistent store for media constraints user settings.
|
||||
*
|
||||
* It will persist between application launches and application updates.
|
||||
*/
|
||||
@interface ARDMediaConstraintsSettingsStore : NSObject
|
||||
|
||||
/**
|
||||
* Returns current video resolution media constraint string stored in the store.
|
||||
*/
|
||||
- (nullable NSString *)videoResolutionConstraintsSetting;
|
||||
|
||||
/**
|
||||
* Stores the provided value as video resolution media constraint.
|
||||
* @param value the string to be stored
|
||||
*/
|
||||
- (void)setVideoResolutionConstraintsSetting:(NSString *)value;
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2016 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 "ARDMediaConstraintsSettingsStore.h"
|
||||
|
||||
static NSString *const kUserDefaultsMediaConstraintsKey =
|
||||
@"rtc_video_resolution_media_constraints_key";
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@implementation ARDMediaConstraintsSettingsStore
|
||||
|
||||
- (nullable NSString *)videoResolutionConstraintsSetting {
|
||||
return [[NSUserDefaults standardUserDefaults] objectForKey:kUserDefaultsMediaConstraintsKey];
|
||||
}
|
||||
|
||||
- (void)setVideoResolutionConstraintsSetting:(NSString *)constraintsString {
|
||||
[[NSUserDefaults standardUserDefaults] setObject:constraintsString
|
||||
forKey:kUserDefaultsMediaConstraintsKey];
|
||||
}
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2016 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 <UIKit/UIKit.h>
|
||||
|
||||
@class ARDMediaConstraintsModel;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
/**
|
||||
* Displays settings options.
|
||||
*/
|
||||
@interface ARDSettingsViewController : UITableViewController
|
||||
|
||||
/**
|
||||
* Creates new instance.
|
||||
*
|
||||
* @param style the table view style that should be used
|
||||
* @param mediaConstraintsModel model class for the media constraints settings.
|
||||
*/
|
||||
- (instancetype)initWithStyle:(UITableViewStyle)style
|
||||
mediaConstraintsModel:(ARDMediaConstraintsModel *)mediaConstraintsModel;
|
||||
|
||||
#pragma mark - Unavailable
|
||||
|
||||
- (instancetype)initWithStyle:(UITableViewStyle)style NS_UNAVAILABLE;
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype) new NS_UNAVAILABLE;
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright 2016 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 "ARDSettingsViewController.h"
|
||||
#import "ARDMediaConstraintsModel.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@interface ARDSettingsViewController () {
|
||||
ARDMediaConstraintsModel *_mediaConstraintsModel;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ARDSettingsViewController
|
||||
|
||||
- (instancetype)initWithStyle:(UITableViewStyle)style
|
||||
mediaConstraintsModel:(ARDMediaConstraintsModel *)mediaConstraintsModel {
|
||||
self = [super initWithStyle:style];
|
||||
if (self) {
|
||||
_mediaConstraintsModel = mediaConstraintsModel;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - View lifecycle
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
self.title = @"Settings";
|
||||
[self addDoneBarButton];
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated {
|
||||
[super viewDidAppear:animated];
|
||||
[self selectCurrentlyStoredOrDefaultMediaConstraints];
|
||||
}
|
||||
|
||||
#pragma mark - Data source
|
||||
|
||||
- (NSArray<NSString *> *)mediaConstraintsArray {
|
||||
return _mediaConstraintsModel.availableVideoResoultionsMediaConstraints;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)addDoneBarButton {
|
||||
UIBarButtonItem *barItem =
|
||||
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
|
||||
target:self
|
||||
action:@selector(dismissModally:)];
|
||||
self.navigationItem.leftBarButtonItem = barItem;
|
||||
}
|
||||
|
||||
- (void)selectCurrentlyStoredOrDefaultMediaConstraints {
|
||||
NSString *currentSelection = [_mediaConstraintsModel currentVideoResoultionConstraintFromStore];
|
||||
|
||||
NSUInteger indexOfSelection = [[self mediaConstraintsArray] indexOfObject:currentSelection];
|
||||
NSIndexPath *pathToBeSelected = [NSIndexPath indexPathForRow:indexOfSelection inSection:0];
|
||||
[self.tableView selectRowAtIndexPath:pathToBeSelected
|
||||
animated:NO
|
||||
scrollPosition:UITableViewScrollPositionNone];
|
||||
// Manully invoke the delegate method because the previous invocation will not.
|
||||
[self tableView:self.tableView didSelectRowAtIndexPath:pathToBeSelected];
|
||||
}
|
||||
|
||||
#pragma mark - Dismissal of view controller
|
||||
|
||||
- (void)dismissModally:(id)sender {
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
#pragma mark - Table view data source
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
return self.mediaConstraintsArray.count;
|
||||
}
|
||||
|
||||
#pragma mark - Table view delegate
|
||||
|
||||
- (BOOL)sectionIsMediaConstraints:(int)section {
|
||||
return section == 0;
|
||||
}
|
||||
|
||||
- (BOOL)indexPathIsMediaConstraints:(NSIndexPath *)indexPath {
|
||||
return [self sectionIsMediaConstraints:indexPath.section];
|
||||
}
|
||||
|
||||
- (nullable NSString *)tableView:(UITableView *)tableView
|
||||
titleForHeaderInSection:(NSInteger)section {
|
||||
if ([self sectionIsMediaConstraints:section]) {
|
||||
return @"Media constraints";
|
||||
}
|
||||
return @"";
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView
|
||||
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if ([self indexPathIsMediaConstraints:indexPath]) {
|
||||
return [self mediaConstraintsTableViewCellForTableView:tableView atIndexPath:indexPath];
|
||||
}
|
||||
return [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
|
||||
reuseIdentifier:@"identifier"];
|
||||
}
|
||||
|
||||
- (nullable NSIndexPath *)tableView:(UITableView *)tableView
|
||||
willSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
|
||||
if ([self indexPathIsMediaConstraints:indexPath]) {
|
||||
return [self tableView:tableView willDeselectMediaConstraintsRowAtIndexPath:indexPath];
|
||||
}
|
||||
return indexPath;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if ([self indexPathIsMediaConstraints:indexPath]) {
|
||||
[self tableView:tableView didSelectMediaConstraintsCellAtIndexPath:indexPath];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Table view delegate(Media Constraints)
|
||||
|
||||
- (UITableViewCell *)mediaConstraintsTableViewCellForTableView:(UITableView *)tableView
|
||||
atIndexPath:(NSIndexPath *)indexPath {
|
||||
NSString *dequeueIdentifier = @"ARDSettingsMediaConstraintsViewCellIdentifier";
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
|
||||
if (!cell) {
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
|
||||
reuseIdentifier:dequeueIdentifier];
|
||||
}
|
||||
cell.textLabel.text = self.mediaConstraintsArray[indexPath.row];
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView
|
||||
didSelectMediaConstraintsCellAtIndexPath:(NSIndexPath *)indexPath {
|
||||
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
|
||||
cell.accessoryType = UITableViewCellAccessoryCheckmark;
|
||||
|
||||
NSString *mediaConstraintsString = self.mediaConstraintsArray[indexPath.row];
|
||||
[_mediaConstraintsModel storeVideoResoultionConstraint:mediaConstraintsString];
|
||||
}
|
||||
|
||||
- (NSIndexPath *)tableView:(UITableView *)tableView
|
||||
willDeselectMediaConstraintsRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
NSIndexPath *oldSelection = [tableView indexPathForSelectedRow];
|
||||
UITableViewCell *cell = [tableView cellForRowAtIndexPath:oldSelection];
|
||||
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||
return indexPath;
|
||||
}
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
@ -12,12 +12,13 @@
|
||||
|
||||
#import "webrtc/modules/audio_device/ios/objc/RTCAudioSession.h"
|
||||
|
||||
#import "ARDAppClient.h"
|
||||
#import "ARDMediaConstraintsModel.h"
|
||||
#import "ARDVideoCallView.h"
|
||||
#import "WebRTC/RTCAVFoundationVideoSource.h"
|
||||
#import "WebRTC/RTCDispatcher.h"
|
||||
#import "WebRTC/RTCLogging.h"
|
||||
|
||||
#import "ARDAppClient.h"
|
||||
#import "ARDVideoCallView.h"
|
||||
#import "WebRTC/RTCMediaConstraints.h"
|
||||
|
||||
@interface ARDVideoCallViewController () <ARDAppClientDelegate,
|
||||
ARDVideoCallViewDelegate>
|
||||
@ -45,6 +46,12 @@
|
||||
if (self = [super init]) {
|
||||
_delegate = delegate;
|
||||
_client = [[ARDAppClient alloc] initWithDelegate:self];
|
||||
ARDMediaConstraintsModel *mediaConstraintsModel = [[ARDMediaConstraintsModel alloc] init];
|
||||
RTCMediaConstraints *cameraConstraints = [[RTCMediaConstraints alloc]
|
||||
initWithMandatoryConstraints:nil
|
||||
optionalConstraints:[mediaConstraintsModel
|
||||
currentMediaConstraintFromStoreAsRTCDictionary]];
|
||||
[_client setCameraConstraints:cameraConstraints];
|
||||
[_client connectToRoomWithId:room
|
||||
isLoopback:isLoopback
|
||||
isAudioOnly:isAudioOnly
|
||||
|
||||
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright 2016 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 <Foundation/Foundation.h>
|
||||
#import <OCMock/OCMock.h>
|
||||
#import "ARDMediaConstraintsModel+Private.h"
|
||||
#import "ARDMediaConstraintsSettingsStore.h"
|
||||
#import "WebRTC/RTCMediaConstraints.h"
|
||||
#include "webrtc/base/gunit.h"
|
||||
|
||||
|
||||
@interface ARDMediaConstraintsModelTests : NSObject {
|
||||
ARDMediaConstraintsModel *_model;
|
||||
}
|
||||
|
||||
- (void)testStoringInavlidConstraintReturnsNo;
|
||||
- (void)testDefaultMediaFromStore;
|
||||
- (void)testWidthConstraintFromStore;
|
||||
- (void)testHeightConstraintFromStore;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ARDMediaConstraintsModelTests
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_model = [[ARDMediaConstraintsModel alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)setupMockStoreWithMediaConstraintString:(NSString *)constraintString {
|
||||
id storeMock = [OCMockObject mockForClass:[ARDMediaConstraintsSettingsStore class]];
|
||||
[([[storeMock stub] andReturn:constraintString]) videoResolutionConstraintsSetting];
|
||||
|
||||
id partialMock = [OCMockObject partialMockForObject:_model];
|
||||
[[[partialMock stub] andReturn:storeMock] settingsStore];
|
||||
|
||||
return storeMock;
|
||||
}
|
||||
|
||||
- (void)testDefaultMediaFromStore {
|
||||
// given
|
||||
id storeMock = [self setupMockStoreWithMediaConstraintString:nil];
|
||||
|
||||
[[storeMock expect] setVideoResolutionConstraintsSetting:@"640x480"];
|
||||
|
||||
// when
|
||||
NSString *string = [_model currentVideoResoultionConstraintFromStore];
|
||||
|
||||
// then
|
||||
EXPECT_TRUE([string isEqualToString:@"640x480"]);
|
||||
[storeMock verify];
|
||||
}
|
||||
|
||||
- (void)testStoringInavlidConstraintReturnsNo {
|
||||
// given
|
||||
id storeMock = [self setupMockStoreWithMediaConstraintString:@"960x480"];
|
||||
|
||||
// when
|
||||
BOOL result = [_model storeVideoResoultionConstraint:@"960x480"];
|
||||
|
||||
// then
|
||||
EXPECT_TRUE(result);
|
||||
}
|
||||
|
||||
- (void)testWidthConstraintFromStore {
|
||||
// given
|
||||
[self setupMockStoreWithMediaConstraintString:@"1270x480"];
|
||||
|
||||
// when
|
||||
NSString *width = [_model currentVideoResolutionWidthFromStore];
|
||||
|
||||
// then
|
||||
EXPECT_TRUE([width isEqualToString:@"1270"]);
|
||||
}
|
||||
|
||||
- (void)testHeightConstraintFromStore {
|
||||
// given
|
||||
[self setupMockStoreWithMediaConstraintString:@"960x540"];
|
||||
// when
|
||||
NSString *height = [_model currentVideoResolutionHeightFromStore];
|
||||
|
||||
// then
|
||||
EXPECT_TRUE([height isEqualToString:@"540"]);
|
||||
}
|
||||
|
||||
- (void)testConstraintComponentIsNilWhenInvalidConstraintString {
|
||||
// given
|
||||
[self setupMockStoreWithMediaConstraintString:@"invalid"];
|
||||
|
||||
// when
|
||||
NSString *width = [_model currentVideoResolutionWidthFromStore];
|
||||
|
||||
// then
|
||||
EXPECT_TRUE(width == nil);
|
||||
}
|
||||
|
||||
- (void)testConstraintsDictionaryIsNilWhenInvalidConstraintString {
|
||||
// given
|
||||
[self setupMockStoreWithMediaConstraintString:@"invalid"];
|
||||
|
||||
// when
|
||||
NSDictionary *constraintsDictionary = [_model currentMediaConstraintFromStoreAsRTCDictionary];
|
||||
|
||||
// then
|
||||
EXPECT_TRUE(constraintsDictionary == nil);
|
||||
}
|
||||
@end
|
||||
|
||||
class ARDMediaConstraintsModelTest : public ::testing::Test {
|
||||
protected:
|
||||
ARDMediaConstraintsModelTests *test;
|
||||
ARDMediaConstraintsModelTest() { test = [[ARDMediaConstraintsModelTests alloc] init]; }
|
||||
};
|
||||
|
||||
TEST_F(ARDMediaConstraintsModelTest, DefaultMediaFromStore) {
|
||||
@autoreleasepool {
|
||||
[test testDefaultMediaFromStore];
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ARDMediaConstraintsModelTest, StoringInvalidConstraintsReturnsNo) {
|
||||
@autoreleasepool {
|
||||
[test testStoringInavlidConstraintReturnsNo];
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ARDMediaConstraintsModelTest, WidthConstraintFromStore) {
|
||||
@autoreleasepool {
|
||||
[test testWidthConstraintFromStore];
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ARDMediaConstraintsModelTest, HeightConstraintFromStore) {
|
||||
@autoreleasepool {
|
||||
[test testHeightConstraintFromStore];
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ARDMediaConstraintsModelTest, ConstratintIsNil) {
|
||||
@autoreleasepool {
|
||||
[test testConstraintComponentIsNilWhenInvalidConstraintString];
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ARDMediaConstraintsModelTest, DictionaryIsNil) {
|
||||
@autoreleasepool {
|
||||
[test testConstraintsDictionaryIsNilWhenInvalidConstraintString];
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user