| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #import "ARDAppClient+Internal.h" | 11 #import "ARDAppClient+Internal.h" |
| 12 | 12 |
| 13 #if defined(WEBRTC_IOS) | 13 #if defined(WEBRTC_IOS) |
| 14 #import "webrtc/base/objc/RTCTracing.h" | 14 #import "webrtc/base/objc/RTCTracing.h" |
| 15 #import "RTCAVFoundationVideoSource.h" | 15 #import "webrtc/api/objc/RTCAVFoundationVideoSource.h" |
| 16 #endif | 16 #endif |
| 17 #import "RTCFileLogger.h" | 17 #import "webrtc/api/objc/RTCAudioTrack.h" |
| 18 #import "RTCICEServer.h" | 18 #import "webrtc/api/objc/RTCConfiguration.h" |
| 19 #import "RTCLogging.h" | 19 #import "webrtc/api/objc/RTCIceServer.h" |
| 20 #import "RTCMediaConstraints.h" | 20 #import "webrtc/api/objc/RTCMediaConstraints.h" |
| 21 #import "RTCMediaStream.h" | 21 #import "webrtc/api/objc/RTCMediaStream.h" |
| 22 #import "RTCPair.h" | 22 #import "webrtc/api/objc/RTCPeerConnectionFactory.h" |
| 23 #import "RTCPeerConnectionInterface.h" | 23 #import "webrtc/base/objc/RTCFileLogger.h" |
| 24 #import "RTCVideoCapturer.h" | 24 #import "webrtc/base/objc/RTCLogging.h" |
| 25 | 25 |
| 26 #import "ARDAppEngineClient.h" | 26 #import "ARDAppEngineClient.h" |
| 27 #import "ARDCEODTURNClient.h" | 27 #import "ARDCEODTURNClient.h" |
| 28 #import "ARDJoinResponse.h" | 28 #import "ARDJoinResponse.h" |
| 29 #import "ARDMessageResponse.h" | 29 #import "ARDMessageResponse.h" |
| 30 #import "ARDSDPUtils.h" | 30 #import "ARDSDPUtils.h" |
| 31 #import "ARDSignalingMessage.h" | 31 #import "ARDSignalingMessage.h" |
| 32 #import "ARDUtilities.h" | 32 #import "ARDUtilities.h" |
| 33 #import "ARDWebSocketChannel.h" | 33 #import "ARDWebSocketChannel.h" |
| 34 #import "RTCICECandidate+JSON.h" | 34 #import "RTCIceCandidate+JSON.h" |
| 35 #import "RTCSessionDescription+JSON.h" | 35 #import "RTCSessionDescription+JSON.h" |
| 36 | 36 |
| 37 static NSString * const kARDDefaultSTUNServerUrl = | 37 static NSString * const kARDDefaultSTUNServerUrl = |
| 38 @"stun:stun.l.google.com:19302"; | 38 @"stun:stun.l.google.com:19302"; |
| 39 // TODO(tkchin): figure out a better username for CEOD statistics. | 39 // TODO(tkchin): figure out a better username for CEOD statistics. |
| 40 static NSString * const kARDTurnRequestUrl = | 40 static NSString * const kARDTurnRequestUrl = |
| 41 @"https://computeengineondemand.appspot.com" | 41 @"https://computeengineondemand.appspot.com" |
| 42 @"/turn?username=iapprtc&key=4080218913"; | 42 @"/turn?username=iapprtc&key=4080218913"; |
| 43 | 43 |
| 44 static NSString * const kARDAppClientErrorDomain = @"ARDAppClient"; | 44 static NSString * const kARDAppClientErrorDomain = @"ARDAppClient"; |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 - (void)setShouldGetStats:(BOOL)shouldGetStats { | 181 - (void)setShouldGetStats:(BOOL)shouldGetStats { |
| 182 if (_shouldGetStats == shouldGetStats) { | 182 if (_shouldGetStats == shouldGetStats) { |
| 183 return; | 183 return; |
| 184 } | 184 } |
| 185 if (shouldGetStats) { | 185 if (shouldGetStats) { |
| 186 __weak ARDAppClient *weakSelf = self; | 186 __weak ARDAppClient *weakSelf = self; |
| 187 _statsTimer = [[ARDTimerProxy alloc] initWithInterval:1 | 187 _statsTimer = [[ARDTimerProxy alloc] initWithInterval:1 |
| 188 repeats:YES | 188 repeats:YES |
| 189 timerHandler:^{ | 189 timerHandler:^{ |
| 190 ARDAppClient *strongSelf = weakSelf; | 190 ARDAppClient *strongSelf = weakSelf; |
| 191 [strongSelf.peerConnection getStatsWithDelegate:strongSelf | 191 [strongSelf.peerConnection statsForTrack:nil |
| 192 mediaStreamTrack:nil | 192 statsOutputLevel:RTCStatsOutputLevelDebug |
| 193 statsOutputLevel:RTCStatsOutputLevelDebug]; | 193 completionHandler:^(NSArray *stats) { |
| 194 dispatch_async(dispatch_get_main_queue(), ^{ |
| 195 ARDAppClient *strongSelf = weakSelf; |
| 196 [strongSelf.delegate appClient:strongSelf didGetStats:stats]; |
| 197 }); |
| 198 }]; |
| 194 }]; | 199 }]; |
| 195 } else { | 200 } else { |
| 196 [_statsTimer invalidate]; | 201 [_statsTimer invalidate]; |
| 197 _statsTimer = nil; | 202 _statsTimer = nil; |
| 198 } | 203 } |
| 199 _shouldGetStats = shouldGetStats; | 204 _shouldGetStats = shouldGetStats; |
| 200 } | 205 } |
| 201 | 206 |
| 202 - (void)setState:(ARDAppClientState)state { | 207 - (void)setState:(ARDAppClientState)state { |
| 203 if (_state == state) { | 208 if (_state == state) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 [self disconnect]; | 350 [self disconnect]; |
| 346 break; | 351 break; |
| 347 } | 352 } |
| 348 } | 353 } |
| 349 | 354 |
| 350 #pragma mark - RTCPeerConnectionDelegate | 355 #pragma mark - RTCPeerConnectionDelegate |
| 351 // Callbacks for this delegate occur on non-main thread and need to be | 356 // Callbacks for this delegate occur on non-main thread and need to be |
| 352 // dispatched back to main queue as needed. | 357 // dispatched back to main queue as needed. |
| 353 | 358 |
| 354 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 359 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 355 signalingStateChanged:(RTCSignalingState)stateChanged { | 360 didChangeSignalingState:(RTCSignalingState)stateChanged { |
| 356 RTCLog(@"Signaling state changed: %d", stateChanged); | 361 RTCLog(@"Signaling state changed: %ld", (long)stateChanged); |
| 357 } | 362 } |
| 358 | 363 |
| 359 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 364 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 360 addedStream:(RTCMediaStream *)stream { | 365 didAddStream:(RTCMediaStream *)stream { |
| 361 dispatch_async(dispatch_get_main_queue(), ^{ | 366 dispatch_async(dispatch_get_main_queue(), ^{ |
| 362 RTCLog(@"Received %lu video tracks and %lu audio tracks", | 367 RTCLog(@"Received %lu video tracks and %lu audio tracks", |
| 363 (unsigned long)stream.videoTracks.count, | 368 (unsigned long)stream.videoTracks.count, |
| 364 (unsigned long)stream.audioTracks.count); | 369 (unsigned long)stream.audioTracks.count); |
| 365 if (stream.videoTracks.count) { | 370 if (stream.videoTracks.count) { |
| 366 RTCVideoTrack *videoTrack = stream.videoTracks[0]; | 371 RTCVideoTrack *videoTrack = stream.videoTracks[0]; |
| 367 [_delegate appClient:self didReceiveRemoteVideoTrack:videoTrack]; | 372 [_delegate appClient:self didReceiveRemoteVideoTrack:videoTrack]; |
| 368 } | 373 } |
| 369 }); | 374 }); |
| 370 } | 375 } |
| 371 | 376 |
| 372 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 377 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 373 removedStream:(RTCMediaStream *)stream { | 378 didRemoveStream:(RTCMediaStream *)stream { |
| 374 RTCLog(@"Stream was removed."); | 379 RTCLog(@"Stream was removed."); |
| 375 } | 380 } |
| 376 | 381 |
| 377 - (void)peerConnectionOnRenegotiationNeeded: | 382 - (void)peerConnectionShouldNegotiate:(RTCPeerConnection *)peerConnection { |
| 378 (RTCPeerConnection *)peerConnection { | |
| 379 RTCLog(@"WARNING: Renegotiation needed but unimplemented."); | 383 RTCLog(@"WARNING: Renegotiation needed but unimplemented."); |
| 380 } | 384 } |
| 381 | 385 |
| 382 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 386 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 383 iceConnectionChanged:(RTCICEConnectionState)newState { | 387 didChangeIceConnectionState:(RTCIceConnectionState)newState { |
| 384 RTCLog(@"ICE state changed: %d", newState); | 388 RTCLog(@"ICE state changed: %ld", (long)newState); |
| 385 dispatch_async(dispatch_get_main_queue(), ^{ | 389 dispatch_async(dispatch_get_main_queue(), ^{ |
| 386 [_delegate appClient:self didChangeConnectionState:newState]; | 390 [_delegate appClient:self didChangeConnectionState:newState]; |
| 387 }); | 391 }); |
| 388 } | 392 } |
| 389 | 393 |
| 390 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 394 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 391 iceGatheringChanged:(RTCICEGatheringState)newState { | 395 didChangeIceGatheringState:(RTCIceGatheringState)newState { |
| 392 RTCLog(@"ICE gathering state changed: %d", newState); | 396 RTCLog(@"ICE gathering state changed: %ld", (long)newState); |
| 393 } | 397 } |
| 394 | 398 |
| 395 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 399 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 396 gotICECandidate:(RTCICECandidate *)candidate { | 400 didGenerateIceCandidate:(RTCIceCandidate *)candidate { |
| 397 dispatch_async(dispatch_get_main_queue(), ^{ | 401 dispatch_async(dispatch_get_main_queue(), ^{ |
| 398 ARDICECandidateMessage *message = | 402 ARDICECandidateMessage *message = |
| 399 [[ARDICECandidateMessage alloc] initWithCandidate:candidate]; | 403 [[ARDICECandidateMessage alloc] initWithCandidate:candidate]; |
| 400 [self sendSignalingMessage:message]; | 404 [self sendSignalingMessage:message]; |
| 401 }); | 405 }); |
| 402 } | 406 } |
| 403 | 407 |
| 404 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 408 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 405 didOpenDataChannel:(RTCDataChannel *)dataChannel { | 409 didOpenDataChannel:(RTCDataChannel *)dataChannel { |
| 406 } | 410 } |
| 407 | 411 |
| 408 #pragma mark - RTCStatsDelegate | |
| 409 | |
| 410 - (void)peerConnection:(RTCPeerConnection *)peerConnection | |
| 411 didGetStats:(NSArray *)stats { | |
| 412 dispatch_async(dispatch_get_main_queue(), ^{ | |
| 413 [_delegate appClient:self didGetStats:stats]; | |
| 414 }); | |
| 415 } | |
| 416 | |
| 417 #pragma mark - RTCSessionDescriptionDelegate | 412 #pragma mark - RTCSessionDescriptionDelegate |
| 418 // Callbacks for this delegate occur on non-main thread and need to be | 413 // Callbacks for this delegate occur on non-main thread and need to be |
| 419 // dispatched back to main queue as needed. | 414 // dispatched back to main queue as needed. |
| 420 | 415 |
| 421 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 416 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 422 didCreateSessionDescription:(RTCSessionDescription *)sdp | 417 didCreateSessionDescription:(RTCSessionDescription *)sdp |
| 423 error:(NSError *)error { | 418 error:(NSError *)error { |
| 424 dispatch_async(dispatch_get_main_queue(), ^{ | 419 dispatch_async(dispatch_get_main_queue(), ^{ |
| 425 if (error) { | 420 if (error) { |
| 426 RTCLogError(@"Failed to create session description. Error: %@", error); | 421 RTCLogError(@"Failed to create session description. Error: %@", error); |
| 427 [self disconnect]; | 422 [self disconnect]; |
| 428 NSDictionary *userInfo = @{ | 423 NSDictionary *userInfo = @{ |
| 429 NSLocalizedDescriptionKey: @"Failed to create session description.", | 424 NSLocalizedDescriptionKey: @"Failed to create session description.", |
| 430 }; | 425 }; |
| 431 NSError *sdpError = | 426 NSError *sdpError = |
| 432 [[NSError alloc] initWithDomain:kARDAppClientErrorDomain | 427 [[NSError alloc] initWithDomain:kARDAppClientErrorDomain |
| 433 code:kARDAppClientErrorCreateSDP | 428 code:kARDAppClientErrorCreateSDP |
| 434 userInfo:userInfo]; | 429 userInfo:userInfo]; |
| 435 [_delegate appClient:self didError:sdpError]; | 430 [_delegate appClient:self didError:sdpError]; |
| 436 return; | 431 return; |
| 437 } | 432 } |
| 438 // Prefer H264 if available. | 433 // Prefer H264 if available. |
| 439 RTCSessionDescription *sdpPreferringH264 = | 434 RTCSessionDescription *sdpPreferringH264 = |
| 440 [ARDSDPUtils descriptionForDescription:sdp | 435 [ARDSDPUtils descriptionForDescription:sdp |
| 441 preferredVideoCodec:@"H264"]; | 436 preferredVideoCodec:@"H264"]; |
| 442 [_peerConnection setLocalDescriptionWithDelegate:self | 437 __weak ARDAppClient *weakSelf = self; |
| 443 sessionDescription:sdpPreferringH264]; | 438 [_peerConnection setLocalDescription:sdpPreferringH264 |
| 439 completionHandler:^(NSError *error) { |
| 440 ARDAppClient *strongSelf = weakSelf; |
| 441 [strongSelf peerConnection:strongSelf.peerConnection |
| 442 didSetSessionDescriptionWithError:error]; |
| 443 }]; |
| 444 ARDSessionDescriptionMessage *message = | 444 ARDSessionDescriptionMessage *message = |
| 445 [[ARDSessionDescriptionMessage alloc] | 445 [[ARDSessionDescriptionMessage alloc] |
| 446 initWithDescription:sdpPreferringH264]; | 446 initWithDescription:sdpPreferringH264]; |
| 447 [self sendSignalingMessage:message]; | 447 [self sendSignalingMessage:message]; |
| 448 }); | 448 }); |
| 449 } | 449 } |
| 450 | 450 |
| 451 - (void)peerConnection:(RTCPeerConnection *)peerConnection | 451 - (void)peerConnection:(RTCPeerConnection *)peerConnection |
| 452 didSetSessionDescriptionWithError:(NSError *)error { | 452 didSetSessionDescriptionWithError:(NSError *)error { |
| 453 dispatch_async(dispatch_get_main_queue(), ^{ | 453 dispatch_async(dispatch_get_main_queue(), ^{ |
| 454 if (error) { | 454 if (error) { |
| 455 RTCLogError(@"Failed to set session description. Error: %@", error); | 455 RTCLogError(@"Failed to set session description. Error: %@", error); |
| 456 [self disconnect]; | 456 [self disconnect]; |
| 457 NSDictionary *userInfo = @{ | 457 NSDictionary *userInfo = @{ |
| 458 NSLocalizedDescriptionKey: @"Failed to set session description.", | 458 NSLocalizedDescriptionKey: @"Failed to set session description.", |
| 459 }; | 459 }; |
| 460 NSError *sdpError = | 460 NSError *sdpError = |
| 461 [[NSError alloc] initWithDomain:kARDAppClientErrorDomain | 461 [[NSError alloc] initWithDomain:kARDAppClientErrorDomain |
| 462 code:kARDAppClientErrorSetSDP | 462 code:kARDAppClientErrorSetSDP |
| 463 userInfo:userInfo]; | 463 userInfo:userInfo]; |
| 464 [_delegate appClient:self didError:sdpError]; | 464 [_delegate appClient:self didError:sdpError]; |
| 465 return; | 465 return; |
| 466 } | 466 } |
| 467 // If we're answering and we've just set the remote offer we need to create | 467 // If we're answering and we've just set the remote offer we need to create |
| 468 // an answer and set the local description. | 468 // an answer and set the local description. |
| 469 if (!_isInitiator && !_peerConnection.localDescription) { | 469 if (!_isInitiator && !_peerConnection.localDescription) { |
| 470 RTCMediaConstraints *constraints = [self defaultAnswerConstraints]; | 470 RTCMediaConstraints *constraints = [self defaultAnswerConstraints]; |
| 471 [_peerConnection createAnswerWithDelegate:self | 471 __weak ARDAppClient *weakSelf = self; |
| 472 constraints:constraints]; | 472 [_peerConnection answerForConstraints:constraints |
| 473 | 473 completionHandler:^(RTCSessionDescription *sdp, |
| 474 NSError *error) { |
| 475 ARDAppClient *strongSelf = weakSelf; |
| 476 [strongSelf peerConnection:strongSelf.peerConnection |
| 477 didCreateSessionDescription:sdp |
| 478 error:error]; |
| 479 }]; |
| 474 } | 480 } |
| 475 }); | 481 }); |
| 476 } | 482 } |
| 477 | 483 |
| 478 #pragma mark - Private | 484 #pragma mark - Private |
| 479 | 485 |
| 480 - (BOOL)hasJoinedRoomServerRoom { | 486 - (BOOL)hasJoinedRoomServerRoom { |
| 481 return _clientId.length; | 487 return _clientId.length; |
| 482 } | 488 } |
| 483 | 489 |
| 484 // Begins the peer connection connection process if we have both joined a room | 490 // Begins the peer connection connection process if we have both joined a room |
| 485 // on the room server and tried to obtain a TURN server. Otherwise does nothing. | 491 // on the room server and tried to obtain a TURN server. Otherwise does nothing. |
| 486 // A peer connection object will be created with a stream that contains local | 492 // A peer connection object will be created with a stream that contains local |
| 487 // audio and video capture. If this client is the caller, an offer is created as | 493 // audio and video capture. If this client is the caller, an offer is created as |
| 488 // well, otherwise the client will wait for an offer to arrive. | 494 // well, otherwise the client will wait for an offer to arrive. |
| 489 - (void)startSignalingIfReady { | 495 - (void)startSignalingIfReady { |
| 490 if (!_isTurnComplete || !self.hasJoinedRoomServerRoom) { | 496 if (!_isTurnComplete || !self.hasJoinedRoomServerRoom) { |
| 491 return; | 497 return; |
| 492 } | 498 } |
| 493 self.state = kARDAppClientStateConnected; | 499 self.state = kARDAppClientStateConnected; |
| 494 | 500 |
| 495 // Create peer connection. | 501 // Create peer connection. |
| 496 RTCMediaConstraints *constraints = [self defaultPeerConnectionConstraints]; | 502 RTCMediaConstraints *constraints = [self defaultPeerConnectionConstraints]; |
| 497 RTCConfiguration *config = [[RTCConfiguration alloc] init]; | 503 RTCConfiguration *config = [[RTCConfiguration alloc] init]; |
| 498 config.iceServers = _iceServers; | 504 config.iceServers = _iceServers; |
| 499 _peerConnection = [_factory peerConnectionWithConfiguration:config | 505 _peerConnection = [[RTCPeerConnection alloc] initWithFactory:_factory |
| 500 constraints:constraints | 506 configuration:config |
| 501 delegate:self]; | 507 constraints:constraints |
| 508 delegate:self]; |
| 502 // Create AV media stream and add it to the peer connection. | 509 // Create AV media stream and add it to the peer connection. |
| 503 RTCMediaStream *localStream = [self createLocalMediaStream]; | 510 RTCMediaStream *localStream = [self createLocalMediaStream]; |
| 504 [_peerConnection addStream:localStream]; | 511 [_peerConnection addStream:localStream]; |
| 505 if (_isInitiator) { | 512 if (_isInitiator) { |
| 506 // Send offer. | 513 // Send offer. |
| 507 [_peerConnection createOfferWithDelegate:self | 514 __weak ARDAppClient *weakSelf = self; |
| 508 constraints:[self defaultOfferConstraints]]; | 515 [_peerConnection offerForConstraints:[self defaultOfferConstraints] |
| 516 completionHandler:^(RTCSessionDescription *sdp, |
| 517 NSError *error) { |
| 518 ARDAppClient *strongSelf = weakSelf; |
| 519 [strongSelf peerConnection:strongSelf.peerConnection |
| 520 didCreateSessionDescription:sdp |
| 521 error:error]; |
| 522 }]; |
| 509 } else { | 523 } else { |
| 510 // Check if we've received an offer. | 524 // Check if we've received an offer. |
| 511 [self drainMessageQueueIfReady]; | 525 [self drainMessageQueueIfReady]; |
| 512 } | 526 } |
| 513 } | 527 } |
| 514 | 528 |
| 515 // Processes the messages that we've received from the room server and the | 529 // Processes the messages that we've received from the room server and the |
| 516 // signaling channel. The offer or answer message must be processed before other | 530 // signaling channel. The offer or answer message must be processed before other |
| 517 // signaling messages, however they can arrive out of order. Hence, this method | 531 // signaling messages, however they can arrive out of order. Hence, this method |
| 518 // only processes pending messages if there is a peer connection object and | 532 // only processes pending messages if there is a peer connection object and |
| (...skipping 15 matching lines...) Expand all Loading... |
| 534 switch (message.type) { | 548 switch (message.type) { |
| 535 case kARDSignalingMessageTypeOffer: | 549 case kARDSignalingMessageTypeOffer: |
| 536 case kARDSignalingMessageTypeAnswer: { | 550 case kARDSignalingMessageTypeAnswer: { |
| 537 ARDSessionDescriptionMessage *sdpMessage = | 551 ARDSessionDescriptionMessage *sdpMessage = |
| 538 (ARDSessionDescriptionMessage *)message; | 552 (ARDSessionDescriptionMessage *)message; |
| 539 RTCSessionDescription *description = sdpMessage.sessionDescription; | 553 RTCSessionDescription *description = sdpMessage.sessionDescription; |
| 540 // Prefer H264 if available. | 554 // Prefer H264 if available. |
| 541 RTCSessionDescription *sdpPreferringH264 = | 555 RTCSessionDescription *sdpPreferringH264 = |
| 542 [ARDSDPUtils descriptionForDescription:description | 556 [ARDSDPUtils descriptionForDescription:description |
| 543 preferredVideoCodec:@"H264"]; | 557 preferredVideoCodec:@"H264"]; |
| 544 [_peerConnection setRemoteDescriptionWithDelegate:self | 558 __weak ARDAppClient *weakSelf = self; |
| 545 sessionDescription:sdpPreferringH264]; | 559 [_peerConnection setRemoteDescription:sdpPreferringH264 |
| 560 completionHandler:^(NSError *error) { |
| 561 ARDAppClient *strongSelf = weakSelf; |
| 562 [strongSelf peerConnection:strongSelf.peerConnection |
| 563 didSetSessionDescriptionWithError:error]; |
| 564 }]; |
| 546 break; | 565 break; |
| 547 } | 566 } |
| 548 case kARDSignalingMessageTypeCandidate: { | 567 case kARDSignalingMessageTypeCandidate: { |
| 549 ARDICECandidateMessage *candidateMessage = | 568 ARDICECandidateMessage *candidateMessage = |
| 550 (ARDICECandidateMessage *)message; | 569 (ARDICECandidateMessage *)message; |
| 551 [_peerConnection addICECandidate:candidateMessage.candidate]; | 570 [_peerConnection addIceCandidate:candidateMessage.candidate]; |
| 552 break; | 571 break; |
| 553 } | 572 } |
| 554 case kARDSignalingMessageTypeBye: | 573 case kARDSignalingMessageTypeBye: |
| 555 // Other client disconnected. | 574 // Other client disconnected. |
| 556 // TODO(tkchin): support waiting in room for next client. For now just | 575 // TODO(tkchin): support waiting in room for next client. For now just |
| 557 // disconnect. | 576 // disconnect. |
| 558 [self disconnect]; | 577 [self disconnect]; |
| 559 break; | 578 break; |
| 560 } | 579 } |
| 561 } | 580 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 582 [strongSelf.delegate appClient:strongSelf didError:messageError]; | 601 [strongSelf.delegate appClient:strongSelf didError:messageError]; |
| 583 return; | 602 return; |
| 584 } | 603 } |
| 585 }]; | 604 }]; |
| 586 } else { | 605 } else { |
| 587 [_channel sendMessage:message]; | 606 [_channel sendMessage:message]; |
| 588 } | 607 } |
| 589 } | 608 } |
| 590 | 609 |
| 591 - (RTCMediaStream *)createLocalMediaStream { | 610 - (RTCMediaStream *)createLocalMediaStream { |
| 592 RTCMediaStream* localStream = [_factory mediaStreamWithLabel:@"ARDAMS"]; | 611 RTCMediaStream *localStream = |
| 593 RTCVideoTrack* localVideoTrack = [self createLocalVideoTrack]; | 612 [[RTCMediaStream alloc] initWithFactory:_factory streamId:@"ARDAMS"]; |
| 613 RTCVideoTrack *localVideoTrack = [self createLocalVideoTrack]; |
| 594 if (localVideoTrack) { | 614 if (localVideoTrack) { |
| 595 [localStream addVideoTrack:localVideoTrack]; | 615 [localStream addVideoTrack:localVideoTrack]; |
| 596 [_delegate appClient:self didReceiveLocalVideoTrack:localVideoTrack]; | 616 [_delegate appClient:self didReceiveLocalVideoTrack:localVideoTrack]; |
| 597 } | 617 } |
| 598 [localStream addAudioTrack:[_factory audioTrackWithID:@"ARDAMSa0"]]; | 618 RTCAudioTrack *localAudioTrack = |
| 619 [[RTCAudioTrack alloc] initWithFactory:_factory |
| 620 trackId:@"ARDAMSa0"]; |
| 621 [localStream addAudioTrack:localAudioTrack]; |
| 599 return localStream; | 622 return localStream; |
| 600 } | 623 } |
| 601 | 624 |
| 602 - (RTCVideoTrack *)createLocalVideoTrack { | 625 - (RTCVideoTrack *)createLocalVideoTrack { |
| 603 RTCVideoTrack* localVideoTrack = nil; | 626 RTCVideoTrack* localVideoTrack = nil; |
| 604 // The iOS simulator doesn't provide any sort of camera capture | 627 // The iOS simulator doesn't provide any sort of camera capture |
| 605 // support or emulation (http://goo.gl/rHAnC1) so don't bother | 628 // support or emulation (http://goo.gl/rHAnC1) so don't bother |
| 606 // trying to open a local stream. | 629 // trying to open a local stream. |
| 607 // TODO(tkchin): local video capture for OSX. See | 630 // TODO(tkchin): local video capture for OSX. See |
| 608 // https://code.google.com/p/webrtc/issues/detail?id=3417. | 631 // https://code.google.com/p/webrtc/issues/detail?id=3417. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 initWithMandatoryConstraints:nil | 677 initWithMandatoryConstraints:nil |
| 655 optionalConstraints:nil]; | 678 optionalConstraints:nil]; |
| 656 return constraints; | 679 return constraints; |
| 657 } | 680 } |
| 658 | 681 |
| 659 - (RTCMediaConstraints *)defaultAnswerConstraints { | 682 - (RTCMediaConstraints *)defaultAnswerConstraints { |
| 660 return [self defaultOfferConstraints]; | 683 return [self defaultOfferConstraints]; |
| 661 } | 684 } |
| 662 | 685 |
| 663 - (RTCMediaConstraints *)defaultOfferConstraints { | 686 - (RTCMediaConstraints *)defaultOfferConstraints { |
| 664 NSArray *mandatoryConstraints = @[ | 687 NSDictionary *mandatoryConstraints = @{ |
| 665 [[RTCPair alloc] initWithKey:@"OfferToReceiveAudio" value:@"true"], | 688 @"OfferToReceiveAudio" : @"true", |
| 666 [[RTCPair alloc] initWithKey:@"OfferToReceiveVideo" value:@"true"] | 689 @"OfferToReceiveVideo" : @"true" |
| 667 ]; | 690 }; |
| 668 RTCMediaConstraints* constraints = | 691 RTCMediaConstraints* constraints = |
| 669 [[RTCMediaConstraints alloc] | 692 [[RTCMediaConstraints alloc] |
| 670 initWithMandatoryConstraints:mandatoryConstraints | 693 initWithMandatoryConstraints:mandatoryConstraints |
| 671 optionalConstraints:nil]; | 694 optionalConstraints:nil]; |
| 672 return constraints; | 695 return constraints; |
| 673 } | 696 } |
| 674 | 697 |
| 675 - (RTCMediaConstraints *)defaultPeerConnectionConstraints { | 698 - (RTCMediaConstraints *)defaultPeerConnectionConstraints { |
| 676 if (_defaultPeerConnectionConstraints) { | 699 if (_defaultPeerConnectionConstraints) { |
| 677 return _defaultPeerConnectionConstraints; | 700 return _defaultPeerConnectionConstraints; |
| 678 } | 701 } |
| 679 NSString *value = _isLoopback ? @"false" : @"true"; | 702 NSString *value = _isLoopback ? @"false" : @"true"; |
| 680 NSArray *optionalConstraints = @[ | 703 NSDictionary *optionalConstraints = @{ @"DtlsSrtpKeyAgreement" : value }; |
| 681 [[RTCPair alloc] initWithKey:@"DtlsSrtpKeyAgreement" value:value] | |
| 682 ]; | |
| 683 RTCMediaConstraints* constraints = | 704 RTCMediaConstraints* constraints = |
| 684 [[RTCMediaConstraints alloc] | 705 [[RTCMediaConstraints alloc] |
| 685 initWithMandatoryConstraints:nil | 706 initWithMandatoryConstraints:nil |
| 686 optionalConstraints:optionalConstraints]; | 707 optionalConstraints:optionalConstraints]; |
| 687 return constraints; | 708 return constraints; |
| 688 } | 709 } |
| 689 | 710 |
| 690 - (RTCICEServer *)defaultSTUNServer { | 711 - (RTCIceServer *)defaultSTUNServer { |
| 691 NSURL *defaultSTUNServerURL = [NSURL URLWithString:kARDDefaultSTUNServerUrl]; | 712 return [[RTCIceServer alloc] initWithURLStrings:@[kARDDefaultSTUNServerUrl] |
| 692 return [[RTCICEServer alloc] initWithURI:defaultSTUNServerURL | 713 username:@"" |
| 693 username:@"" | 714 credential:@""]; |
| 694 password:@""]; | |
| 695 } | 715 } |
| 696 | 716 |
| 697 #pragma mark - Errors | 717 #pragma mark - Errors |
| 698 | 718 |
| 699 + (NSError *)errorForJoinResultType:(ARDJoinResultType)resultType { | 719 + (NSError *)errorForJoinResultType:(ARDJoinResultType)resultType { |
| 700 NSError *error = nil; | 720 NSError *error = nil; |
| 701 switch (resultType) { | 721 switch (resultType) { |
| 702 case kARDJoinResultTypeSuccess: | 722 case kARDJoinResultTypeSuccess: |
| 703 break; | 723 break; |
| 704 case kARDJoinResultTypeUnknown: { | 724 case kARDJoinResultTypeUnknown: { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 code:kARDAppClientErrorInvalidRoom | 765 code:kARDAppClientErrorInvalidRoom |
| 746 userInfo:@{ | 766 userInfo:@{ |
| 747 NSLocalizedDescriptionKey: @"Invalid room.", | 767 NSLocalizedDescriptionKey: @"Invalid room.", |
| 748 }]; | 768 }]; |
| 749 break; | 769 break; |
| 750 } | 770 } |
| 751 return error; | 771 return error; |
| 752 } | 772 } |
| 753 | 773 |
| 754 @end | 774 @end |
| OLD | NEW |