Use new RTCCameraVideoCapturer in AppRTCMobile.
Because the new API doesn't use constraints, refactors settings to instead have a video resolution setting. BUG=webrtc:7177 Review-Url: https://codereview.webrtc.org/2778163005 Cr-Commit-Position: refs/heads/master@{#17545}
This commit is contained in:
@ -192,6 +192,8 @@ if (is_ios || (is_mac && target_cpu != "x86")) {
|
||||
"objc/AppRTCMobile/ARDAppEngineClient.m",
|
||||
"objc/AppRTCMobile/ARDBitrateTracker.h",
|
||||
"objc/AppRTCMobile/ARDBitrateTracker.m",
|
||||
"objc/AppRTCMobile/ARDCaptureController.h",
|
||||
"objc/AppRTCMobile/ARDCaptureController.m",
|
||||
"objc/AppRTCMobile/ARDJoinResponse+Internal.h",
|
||||
"objc/AppRTCMobile/ARDJoinResponse.h",
|
||||
"objc/AppRTCMobile/ARDJoinResponse.m",
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "WebRTC/RTCCameraVideoCapturer.h"
|
||||
#import "WebRTC/RTCPeerConnection.h"
|
||||
#import "WebRTC/RTCVideoTrack.h"
|
||||
|
||||
@ -36,6 +37,9 @@ typedef NS_ENUM(NSInteger, ARDAppClientState) {
|
||||
- (void)appClient:(ARDAppClient *)client
|
||||
didChangeConnectionState:(RTCIceConnectionState)state;
|
||||
|
||||
- (void)appClient:(ARDAppClient *)client
|
||||
didCreateLocalCapturer:(RTCCameraVideoCapturer *)localCapturer;
|
||||
|
||||
- (void)appClient:(ARDAppClient *)client
|
||||
didReceiveLocalVideoTrack:(RTCVideoTrack *)localVideoTrack;
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
#import "WebRTC/RTCAVFoundationVideoSource.h"
|
||||
#import "WebRTC/RTCAudioTrack.h"
|
||||
#import "WebRTC/RTCCameraVideoCapturer.h"
|
||||
#import "WebRTC/RTCConfiguration.h"
|
||||
#import "WebRTC/RTCFileLogger.h"
|
||||
#import "WebRTC/RTCIceServer.h"
|
||||
@ -21,6 +22,7 @@
|
||||
#import "WebRTC/RTCPeerConnectionFactory.h"
|
||||
#import "WebRTC/RTCRtpSender.h"
|
||||
#import "WebRTC/RTCTracing.h"
|
||||
#import "WebRTC/RTCVideoTrack.h"
|
||||
|
||||
#import "ARDAppEngineClient.h"
|
||||
#import "ARDJoinResponse.h"
|
||||
@ -100,6 +102,7 @@ static int const kKbpsMultiplier = 1000;
|
||||
RTCFileLogger *_fileLogger;
|
||||
ARDTimerProxy *_statsTimer;
|
||||
ARDSettingsModel *_settings;
|
||||
RTCVideoTrack *_localVideoTrack;
|
||||
}
|
||||
|
||||
@synthesize shouldGetStats = _shouldGetStats;
|
||||
@ -305,6 +308,7 @@ static int const kKbpsMultiplier = 1000;
|
||||
_isInitiator = NO;
|
||||
_hasReceivedSdp = NO;
|
||||
_messageQueue = [NSMutableArray array];
|
||||
_localVideoTrack = nil;
|
||||
#if defined(WEBRTC_IOS)
|
||||
[_factory stopAecDump];
|
||||
[_peerConnection stopRtcEventLog];
|
||||
@ -666,10 +670,10 @@ static int const kKbpsMultiplier = 1000;
|
||||
RTCRtpSender *sender =
|
||||
[_peerConnection senderWithKind:kRTCMediaStreamTrackKindVideo
|
||||
streamId:kARDMediaStreamId];
|
||||
RTCVideoTrack *track = [self createLocalVideoTrack];
|
||||
if (track) {
|
||||
sender.track = track;
|
||||
[_delegate appClient:self didReceiveLocalVideoTrack:track];
|
||||
_localVideoTrack = [self createLocalVideoTrack];
|
||||
if (_localVideoTrack) {
|
||||
sender.track = _localVideoTrack;
|
||||
[_delegate appClient:self didReceiveLocalVideoTrack:_localVideoTrack];
|
||||
}
|
||||
|
||||
return sender;
|
||||
@ -716,10 +720,9 @@ static int const kKbpsMultiplier = 1000;
|
||||
// trying to open a local stream.
|
||||
#if !TARGET_IPHONE_SIMULATOR
|
||||
if (!_isAudioOnly) {
|
||||
RTCMediaConstraints *cameraConstraints =
|
||||
[self cameraConstraints];
|
||||
RTCAVFoundationVideoSource *source =
|
||||
[_factory avFoundationVideoSourceWithConstraints:cameraConstraints];
|
||||
RTCVideoSource *source = [_factory videoSource];
|
||||
RTCCameraVideoCapturer *capturer = [[RTCCameraVideoCapturer alloc] initWithDelegate:source];
|
||||
[_delegate appClient:self didCreateLocalCapturer:capturer];
|
||||
localVideoTrack =
|
||||
[_factory videoTrackWithSource:source
|
||||
trackId:kARDVideoTrackId];
|
||||
@ -764,13 +767,6 @@ static int const kKbpsMultiplier = 1000;
|
||||
return constraints;
|
||||
}
|
||||
|
||||
- (RTCMediaConstraints *)cameraConstraints {
|
||||
RTCMediaConstraints *cameraConstraints = [[RTCMediaConstraints alloc]
|
||||
initWithMandatoryConstraints:nil
|
||||
optionalConstraints:[_settings currentMediaConstraintFromStoreAsRTCDictionary]];
|
||||
return cameraConstraints;
|
||||
}
|
||||
|
||||
- (RTCMediaConstraints *)defaultAnswerConstraints {
|
||||
return [self defaultOfferConstraints];
|
||||
}
|
||||
|
||||
24
webrtc/examples/objc/AppRTCMobile/ARDCaptureController.h
Normal file
24
webrtc/examples/objc/AppRTCMobile/ARDCaptureController.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2017 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.
|
||||
*/
|
||||
|
||||
#include <WebRTC/RTCCameraVideoCapturer.h>
|
||||
|
||||
@class ARDSettingsModel;
|
||||
|
||||
// Controls the camera. Handles starting the capture, switching cameras etc.
|
||||
@interface ARDCaptureController : NSObject
|
||||
|
||||
- (instancetype)initWithCapturer:(RTCCameraVideoCapturer *)capturer
|
||||
settings:(ARDSettingsModel *)settings;
|
||||
- (void)startCapture;
|
||||
- (void)stopCapture;
|
||||
- (void)switchCamera;
|
||||
|
||||
@end
|
||||
92
webrtc/examples/objc/AppRTCMobile/ARDCaptureController.m
Normal file
92
webrtc/examples/objc/AppRTCMobile/ARDCaptureController.m
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2017 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 "ARDCaptureController.h"
|
||||
|
||||
#import "ARDSettingsModel.h"
|
||||
|
||||
@implementation ARDCaptureController {
|
||||
RTCCameraVideoCapturer *_capturer;
|
||||
ARDSettingsModel *_settings;
|
||||
BOOL _usingFrontCamera;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCapturer:(RTCCameraVideoCapturer *)capturer
|
||||
settings:(ARDSettingsModel *)settings {
|
||||
if ([super init]) {
|
||||
_capturer = capturer;
|
||||
_settings = settings;
|
||||
_usingFrontCamera = YES;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)startCapture {
|
||||
AVCaptureDevicePosition position =
|
||||
_usingFrontCamera ? AVCaptureDevicePositionFront : AVCaptureDevicePositionBack;
|
||||
AVCaptureDevice *device = [self findDeviceForPosition:position];
|
||||
AVCaptureDeviceFormat *format = [self selectFormatForDevice:device];
|
||||
int fps = [self selectFpsForFormat:format];
|
||||
|
||||
[_capturer startCaptureWithDevice:device format:format fps:fps];
|
||||
}
|
||||
|
||||
- (void)stopCapture {
|
||||
[_capturer stopCapture];
|
||||
}
|
||||
|
||||
- (void)switchCamera {
|
||||
_usingFrontCamera = !_usingFrontCamera;
|
||||
[self startCapture];
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (AVCaptureDevice *)findDeviceForPosition:(AVCaptureDevicePosition)position {
|
||||
NSArray<AVCaptureDevice *> *captureDevices = [RTCCameraVideoCapturer captureDevices];
|
||||
for (AVCaptureDevice *device in captureDevices) {
|
||||
if (device.position == position) {
|
||||
return device;
|
||||
}
|
||||
}
|
||||
return captureDevices[0];
|
||||
}
|
||||
|
||||
- (AVCaptureDeviceFormat *)selectFormatForDevice:(AVCaptureDevice *)device {
|
||||
NSArray<AVCaptureDeviceFormat *> *formats =
|
||||
[RTCCameraVideoCapturer supportedFormatsForDevice:device];
|
||||
int targetWidth = [_settings currentVideoResolutionWidthFromStore];
|
||||
int targetHeight = [_settings currentVideoResolutionHeightFromStore];
|
||||
AVCaptureDeviceFormat *selectedFormat = nil;
|
||||
int currentDiff = INT_MAX;
|
||||
|
||||
for (AVCaptureDeviceFormat *format in formats) {
|
||||
CMVideoDimensions dimension = CMVideoFormatDescriptionGetDimensions(format.formatDescription);
|
||||
int diff = abs(targetWidth - dimension.width) + abs(targetHeight - dimension.height);
|
||||
if (diff < currentDiff) {
|
||||
selectedFormat = format;
|
||||
currentDiff = diff;
|
||||
}
|
||||
}
|
||||
|
||||
NSAssert(selectedFormat != nil, @"No suitable capture format found.");
|
||||
return selectedFormat;
|
||||
}
|
||||
|
||||
- (int)selectFpsForFormat:(AVCaptureDeviceFormat *)format {
|
||||
Float64 maxFramerate = 0;
|
||||
for (AVFrameRateRange *fpsRange in format.videoSupportedFrameRateRanges) {
|
||||
maxFramerate = fmax(maxFramerate, fpsRange.maxFrameRate);
|
||||
}
|
||||
return maxFramerate;
|
||||
}
|
||||
|
||||
@end
|
||||
@ -16,7 +16,5 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@interface ARDSettingsModel ()
|
||||
- (ARDSettingsStore *)settingsStore;
|
||||
- (nullable NSString *)currentVideoResolutionWidthFromStore;
|
||||
- (nullable NSString *)currentVideoResolutionHeightFromStore;
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -14,12 +14,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/**
|
||||
* Model class for user defined settings.
|
||||
*
|
||||
* Currently used for streaming media constraints and bitrate 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.
|
||||
* Handles storing the settings and provides default values if setting is not
|
||||
* set. Also provides list of available options for different settings. Stores
|
||||
* for example video codec, video resolution and maximum bitrate.
|
||||
*/
|
||||
@interface ARDSettingsModel : NSObject
|
||||
|
||||
@ -29,24 +26,26 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
* The capture resolutions are represented as strings in the following format
|
||||
* [width]x[height]
|
||||
*/
|
||||
- (NSArray<NSString *> *)availableVideoResoultionsMediaConstraints;
|
||||
- (NSArray<NSString *> *)availableVideoResolutions;
|
||||
|
||||
/**
|
||||
* Returns current video resolution media constraint string.
|
||||
* If no constraint is in store, default value of 640x480 is returned.
|
||||
* Returns current video resolution string.
|
||||
* If no resolution is in store, default value of 640x480 is returned.
|
||||
* When defaulting to value, the default is saved in store for consistency reasons.
|
||||
*/
|
||||
- (NSString *)currentVideoResoultionConstraintFromStore;
|
||||
- (NSString *)currentVideoResolutionSettingFromStore;
|
||||
- (int)currentVideoResolutionWidthFromStore;
|
||||
- (int)currentVideoResolutionHeightFromStore;
|
||||
|
||||
/**
|
||||
* Stores the provided video resolution media constraint string into the store.
|
||||
* Stores the provided video resolution string into the store.
|
||||
*
|
||||
* If the provided constraint is no part of the available video resolutions
|
||||
* If the provided resolution 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.
|
||||
* @param resolution the string to be stored.
|
||||
* @return YES/NO depending on success.
|
||||
*/
|
||||
- (BOOL)storeVideoResoultionConstraint:(NSString *)constraint;
|
||||
- (BOOL)storeVideoResolutionSetting:(NSString *)resolution;
|
||||
|
||||
/**
|
||||
* Returns array of available video codecs.
|
||||
@ -61,21 +60,13 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/**
|
||||
* Stores the provided video codec setting into the store.
|
||||
*
|
||||
* If the provided constraint is not part of the available video codecs
|
||||
* If the provided video codec is not part of the available video codecs
|
||||
* the store operation will not be executed and NO will be returned.
|
||||
* @param video codec settings the string to be stored.
|
||||
* @return YES/NO depending on success.
|
||||
*/
|
||||
- (BOOL)storeVideoCodecSetting:(NSString *)videoCodec;
|
||||
|
||||
/**
|
||||
* Converts the current media constraints from store into dictionary with RTCMediaConstraints
|
||||
* values.
|
||||
*
|
||||
* @return NSDictionary with RTC width and height parameters
|
||||
*/
|
||||
- (nullable NSDictionary *)currentMediaConstraintFromStoreAsRTCDictionary;
|
||||
|
||||
/**
|
||||
* Returns current max bitrate setting from store if present.
|
||||
*/
|
||||
|
||||
@ -28,25 +28,25 @@ static NSArray<NSString *> *videoCodecsStaticValues() {
|
||||
|
||||
@implementation ARDSettingsModel
|
||||
|
||||
- (NSArray<NSString *> *)availableVideoResoultionsMediaConstraints {
|
||||
- (NSArray<NSString *> *)availableVideoResolutions {
|
||||
return videoResolutionsStaticValues();
|
||||
}
|
||||
|
||||
- (NSString *)currentVideoResoultionConstraintFromStore {
|
||||
NSString *constraint = [[self settingsStore] videoResolutionConstraints];
|
||||
if (!constraint) {
|
||||
constraint = [self defaultVideoResolutionMediaConstraint];
|
||||
- (NSString *)currentVideoResolutionSettingFromStore {
|
||||
NSString *resolution = [[self settingsStore] videoResolution];
|
||||
if (!resolution) {
|
||||
resolution = [self defaultVideoResolutionSetting];
|
||||
// To ensure consistency add the default to the store.
|
||||
[[self settingsStore] setVideoResolutionConstraints:constraint];
|
||||
[[self settingsStore] setVideoResolution:resolution];
|
||||
}
|
||||
return constraint;
|
||||
return resolution;
|
||||
}
|
||||
|
||||
- (BOOL)storeVideoResoultionConstraint:(NSString *)constraint {
|
||||
if (![[self availableVideoResoultionsMediaConstraints] containsObject:constraint]) {
|
||||
- (BOOL)storeVideoResolutionSetting:(NSString *)resolution {
|
||||
if (![[self availableVideoResolutions] containsObject:resolution]) {
|
||||
return NO;
|
||||
}
|
||||
[[self settingsStore] setVideoResolutionConstraints:constraint];
|
||||
[[self settingsStore] setVideoResolution:resolution];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@ -88,54 +88,37 @@ static NSArray<NSString *> *videoCodecsStaticValues() {
|
||||
return _settingsStore;
|
||||
}
|
||||
|
||||
- (nullable NSString *)currentVideoResolutionWidthFromStore {
|
||||
NSString *mediaConstraintFromStore = [self currentVideoResoultionConstraintFromStore];
|
||||
- (int)currentVideoResolutionWidthFromStore {
|
||||
NSString *resolution = [self currentVideoResolutionSettingFromStore];
|
||||
|
||||
return [self videoResolutionComponentAtIndex:0 inConstraintsString:mediaConstraintFromStore];
|
||||
return [self videoResolutionComponentAtIndex:0 inString:resolution];
|
||||
}
|
||||
|
||||
- (nullable NSString *)currentVideoResolutionHeightFromStore {
|
||||
NSString *mediaConstraintFromStore = [self currentVideoResoultionConstraintFromStore];
|
||||
return [self videoResolutionComponentAtIndex:1 inConstraintsString:mediaConstraintFromStore];
|
||||
- (int)currentVideoResolutionHeightFromStore {
|
||||
NSString *resolution = [self currentVideoResolutionSettingFromStore];
|
||||
return [self videoResolutionComponentAtIndex:1 inString:resolution];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSString *)defaultVideoResolutionMediaConstraint {
|
||||
- (NSString *)defaultVideoResolutionSetting {
|
||||
return videoResolutionsStaticValues()[0];
|
||||
}
|
||||
|
||||
- (nullable NSString *)videoResolutionComponentAtIndex:(int)index
|
||||
inConstraintsString:(NSString *)constraint {
|
||||
- (int)videoResolutionComponentAtIndex:(int)index inString:(NSString *)resolution {
|
||||
if (index != 0 && index != 1) {
|
||||
return nil;
|
||||
return 0;
|
||||
}
|
||||
NSArray *components = [constraint componentsSeparatedByString:@"x"];
|
||||
NSArray<NSString *> *components = [resolution componentsSeparatedByString:@"x"];
|
||||
if (components.count != 2) {
|
||||
return nil;
|
||||
return 0;
|
||||
}
|
||||
return components[index];
|
||||
return components[index].intValue;
|
||||
}
|
||||
|
||||
- (NSString *)defaultVideoCodecSetting {
|
||||
return videoCodecsStaticValues()[0];
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
@ -19,19 +19,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
@interface ARDSettingsStore : NSObject
|
||||
|
||||
@property(nonatomic) NSString *videoResolution;
|
||||
@property(nonatomic) NSString *videoCodec;
|
||||
|
||||
/**
|
||||
* Returns current video resolution media constraint string stored in the store.
|
||||
*/
|
||||
- (nullable NSString *)videoResolutionConstraints;
|
||||
|
||||
/**
|
||||
* Stores the provided value as video resolution media constraint.
|
||||
* @param value the string to be stored
|
||||
*/
|
||||
- (void)setVideoResolutionConstraints:(NSString *)value;
|
||||
|
||||
/**
|
||||
* Returns current max bitrate number stored in the store.
|
||||
*/
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
|
||||
#import "ARDSettingsStore.h"
|
||||
|
||||
static NSString *const kMediaConstraintsKey = @"rtc_video_resolution_media_constraints_key";
|
||||
static NSString *const kVideoResolutionKey = @"rtc_video_resolution_key";
|
||||
static NSString *const kVideoCodecKey = @"rtc_video_codec_key";
|
||||
static NSString *const kBitrateKey = @"rtc_max_bitrate_key";
|
||||
|
||||
@ -30,12 +30,12 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
return _storage;
|
||||
}
|
||||
|
||||
- (nullable NSString *)videoResolutionConstraints {
|
||||
return [self.storage objectForKey:kMediaConstraintsKey];
|
||||
- (NSString *)videoResolution {
|
||||
return [self.storage objectForKey:kVideoResolutionKey];
|
||||
}
|
||||
|
||||
- (void)setVideoResolutionConstraints:(NSString *)constraintsString {
|
||||
[self.storage setObject:constraintsString forKey:kMediaConstraintsKey];
|
||||
- (void)setVideoResolution:(NSString *)resolution {
|
||||
[self.storage setObject:resolution forKey:kVideoResolutionKey];
|
||||
[self.storage synchronize];
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(int, ARDSettingsSections) {
|
||||
ARDSettingsSectionMediaConstraints = 0,
|
||||
ARDSettingsSectionVideoResolution = 0,
|
||||
ARDSettingsSectionVideoCodec,
|
||||
ARDSettingsSectionBitRate,
|
||||
};
|
||||
@ -46,9 +46,9 @@ typedef NS_ENUM(int, ARDSettingsSections) {
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
[super viewWillAppear:animated];
|
||||
[self addCheckmarkInSection:ARDSettingsSectionMediaConstraints
|
||||
withArray:[self mediaConstraintsArray]
|
||||
selecting:[_settingsModel currentVideoResoultionConstraintFromStore]];
|
||||
[self addCheckmarkInSection:ARDSettingsSectionVideoResolution
|
||||
withArray:[self videoResolutionArray]
|
||||
selecting:[_settingsModel currentVideoResolutionSettingFromStore]];
|
||||
[self addCheckmarkInSection:ARDSettingsSectionVideoCodec
|
||||
withArray:[self videoCodecArray]
|
||||
selecting:[_settingsModel currentVideoCodecSettingFromStore]];
|
||||
@ -60,8 +60,8 @@ typedef NS_ENUM(int, ARDSettingsSections) {
|
||||
|
||||
#pragma mark - Data source
|
||||
|
||||
- (NSArray<NSString *> *)mediaConstraintsArray {
|
||||
return _settingsModel.availableVideoResoultionsMediaConstraints;
|
||||
- (NSArray<NSString *> *)videoResolutionArray {
|
||||
return _settingsModel.availableVideoResolutions;
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)videoCodecArray {
|
||||
@ -102,8 +102,8 @@ typedef NS_ENUM(int, ARDSettingsSections) {
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
switch (section) {
|
||||
case ARDSettingsSectionMediaConstraints:
|
||||
return self.mediaConstraintsArray.count;
|
||||
case ARDSettingsSectionVideoResolution:
|
||||
return self.videoResolutionArray.count;
|
||||
case ARDSettingsSectionVideoCodec:
|
||||
return self.videoCodecArray.count;
|
||||
default:
|
||||
@ -137,8 +137,8 @@ updateListSelectionAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (nullable NSString *)tableView:(UITableView *)tableView
|
||||
titleForHeaderInSection:(NSInteger)section {
|
||||
switch (section) {
|
||||
case ARDSettingsSectionMediaConstraints:
|
||||
return @"Media constraints";
|
||||
case ARDSettingsSectionVideoResolution:
|
||||
return @"Video resolution";
|
||||
case ARDSettingsSectionVideoCodec:
|
||||
return @"Video codec";
|
||||
case ARDSettingsSectionBitRate:
|
||||
@ -151,8 +151,8 @@ updateListSelectionAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView
|
||||
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
switch (indexPath.section) {
|
||||
case ARDSettingsSectionMediaConstraints:
|
||||
return [self mediaConstraintsTableViewCellForTableView:tableView atIndexPath:indexPath];
|
||||
case ARDSettingsSectionVideoResolution:
|
||||
return [self videoResolutionTableViewCellForTableView:tableView atIndexPath:indexPath];
|
||||
|
||||
case ARDSettingsSectionVideoCodec:
|
||||
return [self videoCodecTableViewCellForTableView:tableView atIndexPath:indexPath];
|
||||
@ -168,8 +168,8 @@ updateListSelectionAtIndexPath:(NSIndexPath *)indexPath
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
switch (indexPath.section) {
|
||||
case ARDSettingsSectionMediaConstraints:
|
||||
[self tableView:tableView didSelectMediaConstraintsCellAtIndexPath:indexPath];
|
||||
case ARDSettingsSectionVideoResolution:
|
||||
[self tableView:tableView disSelectVideoResolutionAtIndex:indexPath];
|
||||
break;
|
||||
|
||||
case ARDSettingsSectionVideoCodec:
|
||||
@ -178,28 +178,28 @@ updateListSelectionAtIndexPath:(NSIndexPath *)indexPath
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Table view delegate(Media Constraints)
|
||||
#pragma mark - Table view delegate(Video Resolution)
|
||||
|
||||
- (UITableViewCell *)mediaConstraintsTableViewCellForTableView:(UITableView *)tableView
|
||||
atIndexPath:(NSIndexPath *)indexPath {
|
||||
NSString *dequeueIdentifier = @"ARDSettingsMediaConstraintsViewCellIdentifier";
|
||||
- (UITableViewCell *)videoResolutionTableViewCellForTableView:(UITableView *)tableView
|
||||
atIndexPath:(NSIndexPath *)indexPath {
|
||||
NSString *dequeueIdentifier = @"ARDSettingsVideoResolutionViewCellIdentifier";
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
|
||||
if (!cell) {
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
|
||||
reuseIdentifier:dequeueIdentifier];
|
||||
}
|
||||
cell.textLabel.text = self.mediaConstraintsArray[indexPath.row];
|
||||
cell.textLabel.text = self.videoResolutionArray[indexPath.row];
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView
|
||||
didSelectMediaConstraintsCellAtIndexPath:(NSIndexPath *)indexPath {
|
||||
disSelectVideoResolutionAtIndex:(NSIndexPath *)indexPath {
|
||||
[self tableView:tableView
|
||||
updateListSelectionAtIndexPath:indexPath
|
||||
inSection:ARDSettingsSectionMediaConstraints];
|
||||
updateListSelectionAtIndexPath:indexPath
|
||||
inSection:ARDSettingsSectionVideoResolution];
|
||||
|
||||
NSString *mediaConstraintsString = self.mediaConstraintsArray[indexPath.row];
|
||||
[_settingsModel storeVideoResoultionConstraint:mediaConstraintsString];
|
||||
NSString *videoResolution = self.videoResolutionArray[indexPath.row];
|
||||
[_settingsModel storeVideoResolutionSetting:videoResolution];
|
||||
}
|
||||
|
||||
#pragma mark - Table view delegate(Video Codec)
|
||||
|
||||
@ -31,7 +31,6 @@ static CGFloat const kStatusBarHeight = 20;
|
||||
UIButton *_cameraSwitchButton;
|
||||
UIButton *_hangupButton;
|
||||
CGSize _remoteVideoSize;
|
||||
BOOL _useRearCamera;
|
||||
}
|
||||
|
||||
@synthesize statusLabel = _statusLabel;
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#import "webrtc/modules/audio_device/ios/objc/RTCAudioSession.h"
|
||||
|
||||
#import "ARDAppClient.h"
|
||||
#import "ARDCaptureController.h"
|
||||
#import "ARDSettingsModel.h"
|
||||
#import "ARDVideoCallView.h"
|
||||
#import "WebRTC/RTCAVFoundationVideoSource.h"
|
||||
@ -22,7 +23,6 @@
|
||||
|
||||
@interface ARDVideoCallViewController () <ARDAppClientDelegate,
|
||||
ARDVideoCallViewDelegate>
|
||||
@property(nonatomic, strong) RTCVideoTrack *localVideoTrack;
|
||||
@property(nonatomic, strong) RTCVideoTrack *remoteVideoTrack;
|
||||
@property(nonatomic, readonly) ARDVideoCallView *videoCallView;
|
||||
@end
|
||||
@ -30,12 +30,11 @@
|
||||
@implementation ARDVideoCallViewController {
|
||||
ARDAppClient *_client;
|
||||
RTCVideoTrack *_remoteVideoTrack;
|
||||
RTCVideoTrack *_localVideoTrack;
|
||||
ARDCaptureController *_captureController;
|
||||
AVAudioSessionPortOverride _portOverride;
|
||||
}
|
||||
|
||||
@synthesize videoCallView = _videoCallView;
|
||||
@synthesize localVideoTrack = _localVideoTrack;
|
||||
@synthesize remoteVideoTrack = _remoteVideoTrack;
|
||||
@synthesize delegate = _delegate;
|
||||
|
||||
@ -48,6 +47,7 @@
|
||||
if (self = [super init]) {
|
||||
ARDSettingsModel *settingsModel = [[ARDSettingsModel alloc] init];
|
||||
_delegate = delegate;
|
||||
|
||||
_client = [[ARDAppClient alloc] initWithDelegate:self];
|
||||
[_client connectToRoomWithId:room
|
||||
settings:settingsModel
|
||||
@ -96,9 +96,17 @@
|
||||
});
|
||||
}
|
||||
|
||||
- (void)appClient:(ARDAppClient *)client
|
||||
didCreateLocalCapturer:(RTCCameraVideoCapturer *)localCapturer {
|
||||
_videoCallView.localVideoView.captureSession = localCapturer.captureSession;
|
||||
ARDSettingsModel *settingsModel = [[ARDSettingsModel alloc] init];
|
||||
_captureController =
|
||||
[[ARDCaptureController alloc] initWithCapturer:localCapturer settings:settingsModel];
|
||||
[_captureController startCapture];
|
||||
}
|
||||
|
||||
- (void)appClient:(ARDAppClient *)client
|
||||
didReceiveLocalVideoTrack:(RTCVideoTrack *)localVideoTrack {
|
||||
self.localVideoTrack = localVideoTrack;
|
||||
}
|
||||
|
||||
- (void)appClient:(ARDAppClient *)client
|
||||
@ -130,7 +138,7 @@
|
||||
- (void)videoCallViewDidSwitchCamera:(ARDVideoCallView *)view {
|
||||
// TODO(tkchin): Rate limit this so you can't tap continously on it.
|
||||
// Probably through an animation.
|
||||
[self switchCamera];
|
||||
[_captureController switchCamera];
|
||||
}
|
||||
|
||||
- (void)videoCallViewDidChangeRoute:(ARDVideoCallView *)view {
|
||||
@ -160,20 +168,6 @@
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)setLocalVideoTrack:(RTCVideoTrack *)localVideoTrack {
|
||||
if (_localVideoTrack == localVideoTrack) {
|
||||
return;
|
||||
}
|
||||
_localVideoTrack = nil;
|
||||
_localVideoTrack = localVideoTrack;
|
||||
RTCAVFoundationVideoSource *source = nil;
|
||||
if ([localVideoTrack.source
|
||||
isKindOfClass:[RTCAVFoundationVideoSource class]]) {
|
||||
source = (RTCAVFoundationVideoSource*)localVideoTrack.source;
|
||||
}
|
||||
_videoCallView.localVideoView.captureSession = source.captureSession;
|
||||
}
|
||||
|
||||
- (void)setRemoteVideoTrack:(RTCVideoTrack *)remoteVideoTrack {
|
||||
if (_remoteVideoTrack == remoteVideoTrack) {
|
||||
return;
|
||||
@ -187,19 +181,13 @@
|
||||
|
||||
- (void)hangup {
|
||||
self.remoteVideoTrack = nil;
|
||||
self.localVideoTrack = nil;
|
||||
_videoCallView.localVideoView.captureSession = nil;
|
||||
[_captureController stopCapture];
|
||||
_captureController = nil;
|
||||
[_client disconnect];
|
||||
[_delegate viewControllerDidFinish:self];
|
||||
}
|
||||
|
||||
- (void)switchCamera {
|
||||
RTCVideoSource* source = self.localVideoTrack.source;
|
||||
if ([source isKindOfClass:[RTCAVFoundationVideoSource class]]) {
|
||||
RTCAVFoundationVideoSource* avSource = (RTCAVFoundationVideoSource*)source;
|
||||
avSource.useBackCamera = !avSource.useBackCamera;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)statusTextForState:(RTCIceConnectionState)state {
|
||||
switch (state) {
|
||||
case RTCIceConnectionStateNew:
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#import "WebRTC/RTCVideoTrack.h"
|
||||
|
||||
#import "ARDAppClient.h"
|
||||
#import "ARDCaptureController.h"
|
||||
#import "ARDSettingsModel.h"
|
||||
|
||||
static NSUInteger const kContentWidth = 900;
|
||||
@ -299,6 +300,7 @@ static NSUInteger const kBottomViewHeight = 200;
|
||||
ARDAppClient* _client;
|
||||
RTCVideoTrack* _localVideoTrack;
|
||||
RTCVideoTrack* _remoteVideoTrack;
|
||||
ARDCaptureController* _captureController;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
@ -353,6 +355,14 @@ static NSUInteger const kBottomViewHeight = 200;
|
||||
didChangeConnectionState:(RTCIceConnectionState)state {
|
||||
}
|
||||
|
||||
- (void)appClient:(ARDAppClient*)client
|
||||
didCreateLocalCapturer:(RTCCameraVideoCapturer*)localCapturer {
|
||||
_captureController =
|
||||
[[ARDCaptureController alloc] initWithCapturer:localCapturer
|
||||
settings:[[ARDSettingsModel alloc] init]];
|
||||
[_captureController startCapture];
|
||||
}
|
||||
|
||||
- (void)appClient:(ARDAppClient *)client
|
||||
didReceiveLocalVideoTrack:(RTCVideoTrack *)localVideoTrack {
|
||||
_localVideoTrack = localVideoTrack;
|
||||
@ -386,7 +396,7 @@ static NSUInteger const kBottomViewHeight = 200;
|
||||
return;
|
||||
}
|
||||
|
||||
[_client disconnect];
|
||||
[self disconnect];
|
||||
ARDAppClient* client = [[ARDAppClient alloc] initWithDelegate:self];
|
||||
[client connectToRoomWithId:roomId
|
||||
settings:[[ARDSettingsModel alloc] init] // Use default settings.
|
||||
@ -420,6 +430,8 @@ static NSUInteger const kBottomViewHeight = 200;
|
||||
|
||||
- (void)disconnect {
|
||||
[self resetUI];
|
||||
[_captureController stopCapture];
|
||||
_captureController = nil;
|
||||
[_client disconnect];
|
||||
}
|
||||
|
||||
|
||||
@ -25,9 +25,9 @@
|
||||
|
||||
@implementation ARDSettingsModelTests
|
||||
|
||||
- (id)setupMockStoreWithMediaConstraintString:(NSString *)constraintString {
|
||||
- (id)setupMockStoreWithVideoResolution:(NSString *)videoResolution {
|
||||
id storeMock = [OCMockObject mockForClass:[ARDSettingsStore class]];
|
||||
[([[storeMock stub] andReturn:constraintString]) videoResolutionConstraints];
|
||||
[([[storeMock stub] andReturn:videoResolution])videoResolution];
|
||||
|
||||
id partialMock = [OCMockObject partialMockForObject:_model];
|
||||
[[[partialMock stub] andReturn:storeMock] settingsStore];
|
||||
@ -40,45 +40,38 @@
|
||||
}
|
||||
|
||||
- (void)testDefaultMediaFromStore {
|
||||
id storeMock = [self setupMockStoreWithMediaConstraintString:nil];
|
||||
[[storeMock expect] setVideoResolutionConstraints:@"640x480"];
|
||||
id storeMock = [self setupMockStoreWithVideoResolution:nil];
|
||||
[[storeMock expect] setVideoResolution:@"640x480"];
|
||||
|
||||
NSString *string = [_model currentVideoResoultionConstraintFromStore];
|
||||
NSString *string = [_model currentVideoResolutionSettingFromStore];
|
||||
|
||||
XCTAssertEqualObjects(string, @"640x480");
|
||||
[storeMock verify];
|
||||
}
|
||||
|
||||
- (void)testStoringInvalidConstraintReturnsNo {
|
||||
__unused id storeMock = [self setupMockStoreWithMediaConstraintString:@"960x480"];
|
||||
XCTAssertFalse([_model storeVideoResoultionConstraint:@"960x480"]);
|
||||
__unused id storeMock = [self setupMockStoreWithVideoResolution:@"960x480"];
|
||||
XCTAssertFalse([_model storeVideoResolutionSetting:@"960x480"]);
|
||||
}
|
||||
|
||||
- (void)testWidthConstraintFromStore {
|
||||
[self setupMockStoreWithMediaConstraintString:@"1270x480"];
|
||||
NSString *width = [_model currentVideoResolutionWidthFromStore];
|
||||
[self setupMockStoreWithVideoResolution:@"1270x480"];
|
||||
int width = [_model currentVideoResolutionWidthFromStore];
|
||||
|
||||
XCTAssertEqualObjects(width, @"1270");
|
||||
XCTAssertEqual(width, 1270);
|
||||
}
|
||||
|
||||
- (void)testHeightConstraintFromStore {
|
||||
[self setupMockStoreWithMediaConstraintString:@"960x540"];
|
||||
NSString *height = [_model currentVideoResolutionHeightFromStore];
|
||||
[self setupMockStoreWithVideoResolution:@"960x540"];
|
||||
int height = [_model currentVideoResolutionHeightFromStore];
|
||||
|
||||
XCTAssertEqualObjects(height, @"540");
|
||||
XCTAssertEqual(height, 540);
|
||||
}
|
||||
|
||||
- (void)testConstraintComponentIsNilWhenInvalidConstraintString {
|
||||
[self setupMockStoreWithMediaConstraintString:@"invalid"];
|
||||
NSString *width = [_model currentVideoResolutionWidthFromStore];
|
||||
[self setupMockStoreWithVideoResolution:@"invalid"];
|
||||
int width = [_model currentVideoResolutionWidthFromStore];
|
||||
|
||||
XCTAssertNil(width);
|
||||
}
|
||||
|
||||
- (void)testConstraintsDictionaryIsNilWhenInvalidConstraintString {
|
||||
[self setupMockStoreWithMediaConstraintString:@"invalid"];
|
||||
NSDictionary *constraintsDictionary = [_model currentMediaConstraintFromStoreAsRTCDictionary];
|
||||
|
||||
XCTAssertNil(constraintsDictionary);
|
||||
XCTAssertEqual(width, 0);
|
||||
}
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user