Index: talk/examples/objc/AppRTCDemo/ARDAppClient.m |
diff --git a/talk/examples/objc/AppRTCDemo/ARDAppClient.m b/talk/examples/objc/AppRTCDemo/ARDAppClient.m |
deleted file mode 100644 |
index e043da23b55769eceb0ba4075b6b262ba2ddbc00..0000000000000000000000000000000000000000 |
--- a/talk/examples/objc/AppRTCDemo/ARDAppClient.m |
+++ /dev/null |
@@ -1,658 +0,0 @@ |
-/* |
- * libjingle |
- * Copyright 2014 Google Inc. |
- * |
- * Redistribution and use in source and binary forms, with or without |
- * modification, are permitted provided that the following conditions are met: |
- * |
- * 1. Redistributions of source code must retain the above copyright notice, |
- * this list of conditions and the following disclaimer. |
- * 2. Redistributions in binary form must reproduce the above copyright notice, |
- * this list of conditions and the following disclaimer in the documentation |
- * and/or other materials provided with the distribution. |
- * 3. The name of the author may not be used to endorse or promote products |
- * derived from this software without specific prior written permission. |
- * |
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
- */ |
- |
-#import "ARDAppClient+Internal.h" |
- |
-#if defined(WEBRTC_IOS) |
-#import "RTCAVFoundationVideoSource.h" |
-#endif |
-#import "RTCFileLogger.h" |
-#import "RTCICEServer.h" |
-#import "RTCLogging.h" |
-#import "RTCMediaConstraints.h" |
-#import "RTCMediaStream.h" |
-#import "RTCPair.h" |
-#import "RTCPeerConnectionInterface.h" |
-#import "RTCVideoCapturer.h" |
- |
-#import "ARDAppEngineClient.h" |
-#import "ARDCEODTURNClient.h" |
-#import "ARDJoinResponse.h" |
-#import "ARDMessageResponse.h" |
-#import "ARDSDPUtils.h" |
-#import "ARDSignalingMessage.h" |
-#import "ARDUtilities.h" |
-#import "ARDWebSocketChannel.h" |
-#import "RTCICECandidate+JSON.h" |
-#import "RTCSessionDescription+JSON.h" |
- |
- |
-static NSString * const kARDDefaultSTUNServerUrl = |
- @"stun:stun.l.google.com:19302"; |
-// TODO(tkchin): figure out a better username for CEOD statistics. |
-static NSString * const kARDTurnRequestUrl = |
- @"https://computeengineondemand.appspot.com" |
- @"/turn?username=iapprtc&key=4080218913"; |
- |
-static NSString * const kARDAppClientErrorDomain = @"ARDAppClient"; |
-static NSInteger const kARDAppClientErrorUnknown = -1; |
-static NSInteger const kARDAppClientErrorRoomFull = -2; |
-static NSInteger const kARDAppClientErrorCreateSDP = -3; |
-static NSInteger const kARDAppClientErrorSetSDP = -4; |
-static NSInteger const kARDAppClientErrorInvalidClient = -5; |
-static NSInteger const kARDAppClientErrorInvalidRoom = -6; |
- |
-@implementation ARDAppClient { |
- RTCFileLogger *_fileLogger; |
-} |
- |
-@synthesize delegate = _delegate; |
-@synthesize state = _state; |
-@synthesize roomServerClient = _roomServerClient; |
-@synthesize channel = _channel; |
-@synthesize turnClient = _turnClient; |
-@synthesize peerConnection = _peerConnection; |
-@synthesize factory = _factory; |
-@synthesize messageQueue = _messageQueue; |
-@synthesize isTurnComplete = _isTurnComplete; |
-@synthesize hasReceivedSdp = _hasReceivedSdp; |
-@synthesize roomId = _roomId; |
-@synthesize clientId = _clientId; |
-@synthesize isInitiator = _isInitiator; |
-@synthesize iceServers = _iceServers; |
-@synthesize webSocketURL = _websocketURL; |
-@synthesize webSocketRestURL = _websocketRestURL; |
-@synthesize defaultPeerConnectionConstraints = |
- _defaultPeerConnectionConstraints; |
- |
-- (instancetype)init { |
- if (self = [super init]) { |
- _roomServerClient = [[ARDAppEngineClient alloc] init]; |
- NSURL *turnRequestURL = [NSURL URLWithString:kARDTurnRequestUrl]; |
- _turnClient = [[ARDCEODTURNClient alloc] initWithURL:turnRequestURL]; |
- [self configure]; |
- } |
- return self; |
-} |
- |
-- (instancetype)initWithDelegate:(id<ARDAppClientDelegate>)delegate { |
- if (self = [super init]) { |
- _roomServerClient = [[ARDAppEngineClient alloc] init]; |
- _delegate = delegate; |
- NSURL *turnRequestURL = [NSURL URLWithString:kARDTurnRequestUrl]; |
- _turnClient = [[ARDCEODTURNClient alloc] initWithURL:turnRequestURL]; |
- [self configure]; |
- } |
- return self; |
-} |
- |
-// TODO(tkchin): Provide signaling channel factory interface so we can recreate |
-// channel if we need to on network failure. Also, make this the default public |
-// constructor. |
-- (instancetype)initWithRoomServerClient:(id<ARDRoomServerClient>)rsClient |
- signalingChannel:(id<ARDSignalingChannel>)channel |
- turnClient:(id<ARDTURNClient>)turnClient |
- delegate:(id<ARDAppClientDelegate>)delegate { |
- NSParameterAssert(rsClient); |
- NSParameterAssert(channel); |
- NSParameterAssert(turnClient); |
- if (self = [super init]) { |
- _roomServerClient = rsClient; |
- _channel = channel; |
- _turnClient = turnClient; |
- _delegate = delegate; |
- [self configure]; |
- } |
- return self; |
-} |
- |
-- (void)configure { |
- _factory = [[RTCPeerConnectionFactory alloc] init]; |
- _messageQueue = [NSMutableArray array]; |
- _iceServers = [NSMutableArray arrayWithObject:[self defaultSTUNServer]]; |
- _fileLogger = [[RTCFileLogger alloc] init]; |
- [_fileLogger start]; |
-} |
- |
-- (void)dealloc { |
- [self disconnect]; |
-} |
- |
-- (void)setState:(ARDAppClientState)state { |
- if (_state == state) { |
- return; |
- } |
- _state = state; |
- [_delegate appClient:self didChangeState:_state]; |
-} |
- |
-- (void)connectToRoomWithId:(NSString *)roomId |
- options:(NSDictionary *)options { |
- NSParameterAssert(roomId.length); |
- NSParameterAssert(_state == kARDAppClientStateDisconnected); |
- self.state = kARDAppClientStateConnecting; |
- |
- // Request TURN. |
- __weak ARDAppClient *weakSelf = self; |
- [_turnClient requestServersWithCompletionHandler:^(NSArray *turnServers, |
- NSError *error) { |
- if (error) { |
- RTCLogError("Error retrieving TURN servers: %@", |
- error.localizedDescription); |
- } |
- ARDAppClient *strongSelf = weakSelf; |
- [strongSelf.iceServers addObjectsFromArray:turnServers]; |
- strongSelf.isTurnComplete = YES; |
- [strongSelf startSignalingIfReady]; |
- }]; |
- |
- // Join room on room server. |
- [_roomServerClient joinRoomWithRoomId:roomId |
- completionHandler:^(ARDJoinResponse *response, NSError *error) { |
- ARDAppClient *strongSelf = weakSelf; |
- if (error) { |
- [strongSelf.delegate appClient:strongSelf didError:error]; |
- return; |
- } |
- NSError *joinError = |
- [[strongSelf class] errorForJoinResultType:response.result]; |
- if (joinError) { |
- RTCLogError(@"Failed to join room:%@ on room server.", roomId); |
- [strongSelf disconnect]; |
- [strongSelf.delegate appClient:strongSelf didError:joinError]; |
- return; |
- } |
- RTCLog(@"Joined room:%@ on room server.", roomId); |
- strongSelf.roomId = response.roomId; |
- strongSelf.clientId = response.clientId; |
- strongSelf.isInitiator = response.isInitiator; |
- for (ARDSignalingMessage *message in response.messages) { |
- if (message.type == kARDSignalingMessageTypeOffer || |
- message.type == kARDSignalingMessageTypeAnswer) { |
- strongSelf.hasReceivedSdp = YES; |
- [strongSelf.messageQueue insertObject:message atIndex:0]; |
- } else { |
- [strongSelf.messageQueue addObject:message]; |
- } |
- } |
- strongSelf.webSocketURL = response.webSocketURL; |
- strongSelf.webSocketRestURL = response.webSocketRestURL; |
- [strongSelf registerWithColliderIfReady]; |
- [strongSelf startSignalingIfReady]; |
- }]; |
-} |
- |
-- (void)disconnect { |
- if (_state == kARDAppClientStateDisconnected) { |
- return; |
- } |
- if (self.hasJoinedRoomServerRoom) { |
- [_roomServerClient leaveRoomWithRoomId:_roomId |
- clientId:_clientId |
- completionHandler:nil]; |
- } |
- if (_channel) { |
- if (_channel.state == kARDSignalingChannelStateRegistered) { |
- // Tell the other client we're hanging up. |
- ARDByeMessage *byeMessage = [[ARDByeMessage alloc] init]; |
- [_channel sendMessage:byeMessage]; |
- } |
- // Disconnect from collider. |
- _channel = nil; |
- } |
- _clientId = nil; |
- _roomId = nil; |
- _isInitiator = NO; |
- _hasReceivedSdp = NO; |
- _messageQueue = [NSMutableArray array]; |
- _peerConnection = nil; |
- self.state = kARDAppClientStateDisconnected; |
-} |
- |
-#pragma mark - ARDSignalingChannelDelegate |
- |
-- (void)channel:(id<ARDSignalingChannel>)channel |
- didReceiveMessage:(ARDSignalingMessage *)message { |
- switch (message.type) { |
- case kARDSignalingMessageTypeOffer: |
- case kARDSignalingMessageTypeAnswer: |
- // Offers and answers must be processed before any other message, so we |
- // place them at the front of the queue. |
- _hasReceivedSdp = YES; |
- [_messageQueue insertObject:message atIndex:0]; |
- break; |
- case kARDSignalingMessageTypeCandidate: |
- [_messageQueue addObject:message]; |
- break; |
- case kARDSignalingMessageTypeBye: |
- // Disconnects can be processed immediately. |
- [self processSignalingMessage:message]; |
- return; |
- } |
- [self drainMessageQueueIfReady]; |
-} |
- |
-- (void)channel:(id<ARDSignalingChannel>)channel |
- didChangeState:(ARDSignalingChannelState)state { |
- switch (state) { |
- case kARDSignalingChannelStateOpen: |
- break; |
- case kARDSignalingChannelStateRegistered: |
- break; |
- case kARDSignalingChannelStateClosed: |
- case kARDSignalingChannelStateError: |
- // TODO(tkchin): reconnection scenarios. Right now we just disconnect |
- // completely if the websocket connection fails. |
- [self disconnect]; |
- break; |
- } |
-} |
- |
-#pragma mark - RTCPeerConnectionDelegate |
-// Callbacks for this delegate occur on non-main thread and need to be |
-// dispatched back to main queue as needed. |
- |
-- (void)peerConnection:(RTCPeerConnection *)peerConnection |
- signalingStateChanged:(RTCSignalingState)stateChanged { |
- RTCLog(@"Signaling state changed: %d", stateChanged); |
-} |
- |
-- (void)peerConnection:(RTCPeerConnection *)peerConnection |
- addedStream:(RTCMediaStream *)stream { |
- dispatch_async(dispatch_get_main_queue(), ^{ |
- RTCLog(@"Received %lu video tracks and %lu audio tracks", |
- (unsigned long)stream.videoTracks.count, |
- (unsigned long)stream.audioTracks.count); |
- if (stream.videoTracks.count) { |
- RTCVideoTrack *videoTrack = stream.videoTracks[0]; |
- [_delegate appClient:self didReceiveRemoteVideoTrack:videoTrack]; |
- } |
- }); |
-} |
- |
-- (void)peerConnection:(RTCPeerConnection *)peerConnection |
- removedStream:(RTCMediaStream *)stream { |
- RTCLog(@"Stream was removed."); |
-} |
- |
-- (void)peerConnectionOnRenegotiationNeeded: |
- (RTCPeerConnection *)peerConnection { |
- RTCLog(@"WARNING: Renegotiation needed but unimplemented."); |
-} |
- |
-- (void)peerConnection:(RTCPeerConnection *)peerConnection |
- iceConnectionChanged:(RTCICEConnectionState)newState { |
- RTCLog(@"ICE state changed: %d", newState); |
- dispatch_async(dispatch_get_main_queue(), ^{ |
- [_delegate appClient:self didChangeConnectionState:newState]; |
- }); |
-} |
- |
-- (void)peerConnection:(RTCPeerConnection *)peerConnection |
- iceGatheringChanged:(RTCICEGatheringState)newState { |
- RTCLog(@"ICE gathering state changed: %d", newState); |
-} |
- |
-- (void)peerConnection:(RTCPeerConnection *)peerConnection |
- gotICECandidate:(RTCICECandidate *)candidate { |
- dispatch_async(dispatch_get_main_queue(), ^{ |
- ARDICECandidateMessage *message = |
- [[ARDICECandidateMessage alloc] initWithCandidate:candidate]; |
- [self sendSignalingMessage:message]; |
- }); |
-} |
- |
-- (void)peerConnection:(RTCPeerConnection*)peerConnection |
- didOpenDataChannel:(RTCDataChannel*)dataChannel { |
-} |
- |
-#pragma mark - RTCSessionDescriptionDelegate |
-// Callbacks for this delegate occur on non-main thread and need to be |
-// dispatched back to main queue as needed. |
- |
-- (void)peerConnection:(RTCPeerConnection *)peerConnection |
- didCreateSessionDescription:(RTCSessionDescription *)sdp |
- error:(NSError *)error { |
- dispatch_async(dispatch_get_main_queue(), ^{ |
- if (error) { |
- RTCLogError(@"Failed to create session description. Error: %@", error); |
- [self disconnect]; |
- NSDictionary *userInfo = @{ |
- NSLocalizedDescriptionKey: @"Failed to create session description.", |
- }; |
- NSError *sdpError = |
- [[NSError alloc] initWithDomain:kARDAppClientErrorDomain |
- code:kARDAppClientErrorCreateSDP |
- userInfo:userInfo]; |
- [_delegate appClient:self didError:sdpError]; |
- return; |
- } |
- // Prefer H264 if available. |
- RTCSessionDescription *sdpPreferringH264 = |
- [ARDSDPUtils descriptionForDescription:sdp |
- preferredVideoCodec:@"H264"]; |
- [_peerConnection setLocalDescriptionWithDelegate:self |
- sessionDescription:sdpPreferringH264]; |
- ARDSessionDescriptionMessage *message = |
- [[ARDSessionDescriptionMessage alloc] |
- initWithDescription:sdpPreferringH264]; |
- [self sendSignalingMessage:message]; |
- }); |
-} |
- |
-- (void)peerConnection:(RTCPeerConnection *)peerConnection |
- didSetSessionDescriptionWithError:(NSError *)error { |
- dispatch_async(dispatch_get_main_queue(), ^{ |
- if (error) { |
- RTCLogError(@"Failed to set session description. Error: %@", error); |
- [self disconnect]; |
- NSDictionary *userInfo = @{ |
- NSLocalizedDescriptionKey: @"Failed to set session description.", |
- }; |
- NSError *sdpError = |
- [[NSError alloc] initWithDomain:kARDAppClientErrorDomain |
- code:kARDAppClientErrorSetSDP |
- userInfo:userInfo]; |
- [_delegate appClient:self didError:sdpError]; |
- return; |
- } |
- // If we're answering and we've just set the remote offer we need to create |
- // an answer and set the local description. |
- if (!_isInitiator && !_peerConnection.localDescription) { |
- RTCMediaConstraints *constraints = [self defaultAnswerConstraints]; |
- [_peerConnection createAnswerWithDelegate:self |
- constraints:constraints]; |
- |
- } |
- }); |
-} |
- |
-#pragma mark - Private |
- |
-- (BOOL)hasJoinedRoomServerRoom { |
- return _clientId.length; |
-} |
- |
-// Begins the peer connection connection process if we have both joined a room |
-// on the room server and tried to obtain a TURN server. Otherwise does nothing. |
-// A peer connection object will be created with a stream that contains local |
-// audio and video capture. If this client is the caller, an offer is created as |
-// well, otherwise the client will wait for an offer to arrive. |
-- (void)startSignalingIfReady { |
- if (!_isTurnComplete || !self.hasJoinedRoomServerRoom) { |
- return; |
- } |
- self.state = kARDAppClientStateConnected; |
- |
- // Create peer connection. |
- RTCMediaConstraints *constraints = [self defaultPeerConnectionConstraints]; |
- RTCConfiguration *config = [[RTCConfiguration alloc] init]; |
- config.iceServers = _iceServers; |
- _peerConnection = [_factory peerConnectionWithConfiguration:config |
- constraints:constraints |
- delegate:self]; |
- // Create AV media stream and add it to the peer connection. |
- RTCMediaStream *localStream = [self createLocalMediaStream]; |
- [_peerConnection addStream:localStream]; |
- if (_isInitiator) { |
- // Send offer. |
- [_peerConnection createOfferWithDelegate:self |
- constraints:[self defaultOfferConstraints]]; |
- } else { |
- // Check if we've received an offer. |
- [self drainMessageQueueIfReady]; |
- } |
-} |
- |
-// Processes the messages that we've received from the room server and the |
-// signaling channel. The offer or answer message must be processed before other |
-// signaling messages, however they can arrive out of order. Hence, this method |
-// only processes pending messages if there is a peer connection object and |
-// if we have received either an offer or answer. |
-- (void)drainMessageQueueIfReady { |
- if (!_peerConnection || !_hasReceivedSdp) { |
- return; |
- } |
- for (ARDSignalingMessage *message in _messageQueue) { |
- [self processSignalingMessage:message]; |
- } |
- [_messageQueue removeAllObjects]; |
-} |
- |
-// Processes the given signaling message based on its type. |
-- (void)processSignalingMessage:(ARDSignalingMessage *)message { |
- NSParameterAssert(_peerConnection || |
- message.type == kARDSignalingMessageTypeBye); |
- switch (message.type) { |
- case kARDSignalingMessageTypeOffer: |
- case kARDSignalingMessageTypeAnswer: { |
- ARDSessionDescriptionMessage *sdpMessage = |
- (ARDSessionDescriptionMessage *)message; |
- RTCSessionDescription *description = sdpMessage.sessionDescription; |
- // Prefer H264 if available. |
- RTCSessionDescription *sdpPreferringH264 = |
- [ARDSDPUtils descriptionForDescription:description |
- preferredVideoCodec:@"H264"]; |
- [_peerConnection setRemoteDescriptionWithDelegate:self |
- sessionDescription:sdpPreferringH264]; |
- break; |
- } |
- case kARDSignalingMessageTypeCandidate: { |
- ARDICECandidateMessage *candidateMessage = |
- (ARDICECandidateMessage *)message; |
- [_peerConnection addICECandidate:candidateMessage.candidate]; |
- break; |
- } |
- case kARDSignalingMessageTypeBye: |
- // Other client disconnected. |
- // TODO(tkchin): support waiting in room for next client. For now just |
- // disconnect. |
- [self disconnect]; |
- break; |
- } |
-} |
- |
-// Sends a signaling message to the other client. The caller will send messages |
-// through the room server, whereas the callee will send messages over the |
-// signaling channel. |
-- (void)sendSignalingMessage:(ARDSignalingMessage *)message { |
- if (_isInitiator) { |
- __weak ARDAppClient *weakSelf = self; |
- [_roomServerClient sendMessage:message |
- forRoomId:_roomId |
- clientId:_clientId |
- completionHandler:^(ARDMessageResponse *response, |
- NSError *error) { |
- ARDAppClient *strongSelf = weakSelf; |
- if (error) { |
- [strongSelf.delegate appClient:strongSelf didError:error]; |
- return; |
- } |
- NSError *messageError = |
- [[strongSelf class] errorForMessageResultType:response.result]; |
- if (messageError) { |
- [strongSelf.delegate appClient:strongSelf didError:messageError]; |
- return; |
- } |
- }]; |
- } else { |
- [_channel sendMessage:message]; |
- } |
-} |
- |
-- (RTCMediaStream *)createLocalMediaStream { |
- RTCMediaStream* localStream = [_factory mediaStreamWithLabel:@"ARDAMS"]; |
- RTCVideoTrack* localVideoTrack = [self createLocalVideoTrack]; |
- if (localVideoTrack) { |
- [localStream addVideoTrack:localVideoTrack]; |
- [_delegate appClient:self didReceiveLocalVideoTrack:localVideoTrack]; |
- } |
- [localStream addAudioTrack:[_factory audioTrackWithID:@"ARDAMSa0"]]; |
- return localStream; |
-} |
- |
-- (RTCVideoTrack *)createLocalVideoTrack { |
- RTCVideoTrack* localVideoTrack = nil; |
- // The iOS simulator doesn't provide any sort of camera capture |
- // support or emulation (http://goo.gl/rHAnC1) so don't bother |
- // trying to open a local stream. |
- // TODO(tkchin): local video capture for OSX. See |
- // https://code.google.com/p/webrtc/issues/detail?id=3417. |
-#if !TARGET_IPHONE_SIMULATOR && TARGET_OS_IPHONE |
- RTCMediaConstraints *mediaConstraints = [self defaultMediaStreamConstraints]; |
- RTCAVFoundationVideoSource *source = |
- [[RTCAVFoundationVideoSource alloc] initWithFactory:_factory |
- constraints:mediaConstraints]; |
- localVideoTrack = |
- [[RTCVideoTrack alloc] initWithFactory:_factory |
- source:source |
- trackId:@"ARDAMSv0"]; |
-#endif |
- return localVideoTrack; |
-} |
- |
-#pragma mark - Collider methods |
- |
-- (void)registerWithColliderIfReady { |
- if (!self.hasJoinedRoomServerRoom) { |
- return; |
- } |
- // Open WebSocket connection. |
- if (!_channel) { |
- _channel = |
- [[ARDWebSocketChannel alloc] initWithURL:_websocketURL |
- restURL:_websocketRestURL |
- delegate:self]; |
- } |
- [_channel registerForRoomId:_roomId clientId:_clientId]; |
-} |
- |
-#pragma mark - Defaults |
- |
-- (RTCMediaConstraints *)defaultMediaStreamConstraints { |
- RTCMediaConstraints* constraints = |
- [[RTCMediaConstraints alloc] |
- initWithMandatoryConstraints:nil |
- optionalConstraints:nil]; |
- return constraints; |
-} |
- |
-- (RTCMediaConstraints *)defaultAnswerConstraints { |
- return [self defaultOfferConstraints]; |
-} |
- |
-- (RTCMediaConstraints *)defaultOfferConstraints { |
- NSArray *mandatoryConstraints = @[ |
- [[RTCPair alloc] initWithKey:@"OfferToReceiveAudio" value:@"true"], |
- [[RTCPair alloc] initWithKey:@"OfferToReceiveVideo" value:@"true"] |
- ]; |
- RTCMediaConstraints* constraints = |
- [[RTCMediaConstraints alloc] |
- initWithMandatoryConstraints:mandatoryConstraints |
- optionalConstraints:nil]; |
- return constraints; |
-} |
- |
-- (RTCMediaConstraints *)defaultPeerConnectionConstraints { |
- if (_defaultPeerConnectionConstraints) { |
- return _defaultPeerConnectionConstraints; |
- } |
- NSArray *optionalConstraints = @[ |
- [[RTCPair alloc] initWithKey:@"DtlsSrtpKeyAgreement" value:@"true"] |
- ]; |
- RTCMediaConstraints* constraints = |
- [[RTCMediaConstraints alloc] |
- initWithMandatoryConstraints:nil |
- optionalConstraints:optionalConstraints]; |
- return constraints; |
-} |
- |
-- (RTCICEServer *)defaultSTUNServer { |
- NSURL *defaultSTUNServerURL = [NSURL URLWithString:kARDDefaultSTUNServerUrl]; |
- return [[RTCICEServer alloc] initWithURI:defaultSTUNServerURL |
- username:@"" |
- password:@""]; |
-} |
- |
-#pragma mark - Errors |
- |
-+ (NSError *)errorForJoinResultType:(ARDJoinResultType)resultType { |
- NSError *error = nil; |
- switch (resultType) { |
- case kARDJoinResultTypeSuccess: |
- break; |
- case kARDJoinResultTypeUnknown: { |
- error = [[NSError alloc] initWithDomain:kARDAppClientErrorDomain |
- code:kARDAppClientErrorUnknown |
- userInfo:@{ |
- NSLocalizedDescriptionKey: @"Unknown error.", |
- }]; |
- break; |
- } |
- case kARDJoinResultTypeFull: { |
- error = [[NSError alloc] initWithDomain:kARDAppClientErrorDomain |
- code:kARDAppClientErrorRoomFull |
- userInfo:@{ |
- NSLocalizedDescriptionKey: @"Room is full.", |
- }]; |
- break; |
- } |
- } |
- return error; |
-} |
- |
-+ (NSError *)errorForMessageResultType:(ARDMessageResultType)resultType { |
- NSError *error = nil; |
- switch (resultType) { |
- case kARDMessageResultTypeSuccess: |
- break; |
- case kARDMessageResultTypeUnknown: |
- error = [[NSError alloc] initWithDomain:kARDAppClientErrorDomain |
- code:kARDAppClientErrorUnknown |
- userInfo:@{ |
- NSLocalizedDescriptionKey: @"Unknown error.", |
- }]; |
- break; |
- case kARDMessageResultTypeInvalidClient: |
- error = [[NSError alloc] initWithDomain:kARDAppClientErrorDomain |
- code:kARDAppClientErrorInvalidClient |
- userInfo:@{ |
- NSLocalizedDescriptionKey: @"Invalid client.", |
- }]; |
- break; |
- case kARDMessageResultTypeInvalidRoom: |
- error = [[NSError alloc] initWithDomain:kARDAppClientErrorDomain |
- code:kARDAppClientErrorInvalidRoom |
- userInfo:@{ |
- NSLocalizedDescriptionKey: @"Invalid room.", |
- }]; |
- break; |
- } |
- return error; |
-} |
- |
-@end |