Refactor iOS AppRTC parsing code.
Moved parsing code to JSON categories for the relevant objects. No longer prefer ISAC as audio codec. BUG= R=glaznev@webrtc.org Review URL: https://webrtc-codereview.appspot.com/31989005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@7755 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
79b9eba3ab
commit
3e9ad26112
@ -27,6 +27,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "ARDSignalingParams.h"
|
||||
#import "GAEChannelClient.h"
|
||||
|
||||
@class APPRTCAppClient;
|
||||
@ -50,14 +51,13 @@
|
||||
// for the registered handler to be called with received messages.
|
||||
@interface APPRTCAppClient : NSObject
|
||||
|
||||
@property(nonatomic) BOOL initiator;
|
||||
@property(nonatomic, copy, readonly) RTCMediaConstraints* videoConstraints;
|
||||
@property(nonatomic, readonly) ARDSignalingParams *params;
|
||||
@property(nonatomic, weak) id<APPRTCAppClientDelegate> delegate;
|
||||
|
||||
- (instancetype)initWithDelegate:(id<APPRTCAppClientDelegate>)delegate
|
||||
messageHandler:(id<GAEMessageHandler>)handler;
|
||||
- (void)connectToRoom:(NSURL*)room;
|
||||
- (void)sendData:(NSData*)data;
|
||||
- (void)connectToRoom:(NSURL *)room;
|
||||
- (void)sendData:(NSData *)data;
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
// Disallow init and don't add to documentation
|
||||
|
@ -33,8 +33,11 @@
|
||||
|
||||
#import <dispatch/dispatch.h>
|
||||
|
||||
#import "ARDSignalingParams.h"
|
||||
#import "ARDUtilities.h"
|
||||
#import "GAEChannelClient.h"
|
||||
#import "RTCICEServer.h"
|
||||
#import "RTCICEServer+JSON.h"
|
||||
#import "RTCMediaConstraints.h"
|
||||
#import "RTCPair.h"
|
||||
|
||||
@ -60,14 +63,15 @@
|
||||
}
|
||||
|
||||
- (void)connectToRoom:(NSURL*)url {
|
||||
NSString* urlString =
|
||||
NSString *urlString =
|
||||
[[url absoluteString] stringByAppendingString:@"&t=json"];
|
||||
NSURL* requestURL = [NSURL URLWithString:urlString];
|
||||
NSURLRequest* request = [NSURLRequest requestWithURL:requestURL];
|
||||
[self sendURLRequest:request
|
||||
completionHandler:^(NSError* error,
|
||||
NSHTTPURLResponse* httpResponse,
|
||||
NSData* responseData) {
|
||||
NSURL *requestURL = [NSURL URLWithString:urlString];
|
||||
NSURLRequest *request = [NSURLRequest requestWithURL:requestURL];
|
||||
[NSURLConnection sendAsynchronousRequest:request
|
||||
completionHandler:^(NSURLResponse *response,
|
||||
NSData *data,
|
||||
NSError *error) {
|
||||
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
|
||||
int statusCode = [httpResponse statusCode];
|
||||
[self logVerbose:[NSString stringWithFormat:
|
||||
@"Response received\nURL\n%@\nStatus [%d]\nHeaders\n%@",
|
||||
@ -81,116 +85,74 @@
|
||||
if (statusCode != 200) {
|
||||
return;
|
||||
}
|
||||
[self handleResponseData:responseData
|
||||
forRoomRequest:request];
|
||||
[self handleResponseData:data forRoomRequest:request];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)sendData:(NSData*)data {
|
||||
NSParameterAssert([data length] > 0);
|
||||
NSString* message = [NSString stringWithUTF8String:[data bytes]];
|
||||
NSString *message = [NSString stringWithUTF8String:[data bytes]];
|
||||
[self logVerbose:[NSString stringWithFormat:@"Send message:\n%@", message]];
|
||||
if (!_postMessageURL) {
|
||||
return;
|
||||
}
|
||||
NSMutableURLRequest* request =
|
||||
NSMutableURLRequest *request =
|
||||
[NSMutableURLRequest requestWithURL:_postMessageURL];
|
||||
request.HTTPMethod = @"POST";
|
||||
[request setHTTPBody:data];
|
||||
[self sendURLRequest:request
|
||||
completionHandler:^(NSError* error,
|
||||
NSHTTPURLResponse* httpResponse,
|
||||
NSData* responseData) {
|
||||
[NSURLConnection sendAsynchronousRequest:request
|
||||
completionHandler:^(NSURLResponse *response,
|
||||
NSData *data,
|
||||
NSError *error) {
|
||||
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
|
||||
int status = [httpResponse statusCode];
|
||||
NSString* response = [responseData length] > 0 ?
|
||||
[NSString stringWithUTF8String:[responseData bytes]] :
|
||||
NSString *responseString = [data length] > 0 ?
|
||||
[NSString stringWithUTF8String:[data bytes]] :
|
||||
nil;
|
||||
NSAssert(status == 200,
|
||||
@"Bad response [%d] to message: %@\n\n%@",
|
||||
status,
|
||||
message,
|
||||
response);
|
||||
responseString);
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)logVerbose:(NSString*)message {
|
||||
- (void)logVerbose:(NSString *)message {
|
||||
if (_verboseLogging) {
|
||||
NSLog(@"%@", message);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleResponseData:(NSData*)responseData
|
||||
forRoomRequest:(NSURLRequest*)request {
|
||||
NSDictionary* roomJSON = [self parseJSONData:responseData];
|
||||
[self logVerbose:[NSString stringWithFormat:@"Room JSON:\n%@", roomJSON]];
|
||||
NSParameterAssert(roomJSON);
|
||||
if (roomJSON[@"error"]) {
|
||||
NSArray* errorMessages = roomJSON[@"error_messages"];
|
||||
NSMutableString* message = [NSMutableString string];
|
||||
for (NSString* errorMessage in errorMessages) {
|
||||
- (void)handleResponseData:(NSData *)responseData
|
||||
forRoomRequest:(NSURLRequest *)request {
|
||||
ARDSignalingParams *params =
|
||||
[ARDSignalingParams paramsFromJSONData:responseData];
|
||||
if (params.errorMessages.count > 0) {
|
||||
NSMutableString *message = [NSMutableString string];
|
||||
for (NSString *errorMessage in params.errorMessages) {
|
||||
[message appendFormat:@"%@\n", errorMessage];
|
||||
}
|
||||
[self.delegate appClient:self didErrorWithMessage:message];
|
||||
return;
|
||||
}
|
||||
NSString* pcConfig = roomJSON[@"pc_config"];
|
||||
NSData* pcConfigData = [pcConfig dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSDictionary* pcConfigJSON = [self parseJSONData:pcConfigData];
|
||||
[self logVerbose:[NSString stringWithFormat:@"PCConfig JSON:\n%@",
|
||||
pcConfigJSON]];
|
||||
NSParameterAssert(pcConfigJSON);
|
||||
|
||||
NSArray* iceServers = [self parseICEServersForPCConfigJSON:pcConfigJSON];
|
||||
[self requestTURNServerForICEServers:iceServers
|
||||
turnServerUrl:roomJSON[@"turn_url"]];
|
||||
|
||||
_initiator = [roomJSON[@"initiator"] boolValue];
|
||||
[self logVerbose:[NSString stringWithFormat:@"Initiator: %d", _initiator]];
|
||||
_postMessageURL = [self parsePostMessageURLForRoomJSON:roomJSON
|
||||
request:request];
|
||||
[self logVerbose:[NSString stringWithFormat:@"POST message URL:\n%@",
|
||||
_postMessageURL]];
|
||||
_videoConstraints = [self parseVideoConstraintsForRoomJSON:roomJSON];
|
||||
[self logVerbose:[NSString stringWithFormat:@"Media constraints:\n%@",
|
||||
_videoConstraints]];
|
||||
NSString* token = roomJSON[@"token"];
|
||||
[self requestTURNServerForICEServers:params.iceServers
|
||||
turnServerUrl:[params.turnRequestURL absoluteString]];
|
||||
NSString *token = params.channelToken;
|
||||
[self logVerbose:
|
||||
[NSString stringWithFormat:@"About to open GAE with token: %@",
|
||||
token]];
|
||||
_gaeChannel =
|
||||
[[GAEChannelClient alloc] initWithToken:token
|
||||
delegate:_messageHandler];
|
||||
}
|
||||
|
||||
- (NSDictionary*)parseJSONData:(NSData*)data {
|
||||
NSError* error = nil;
|
||||
NSDictionary* json =
|
||||
[NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
|
||||
NSAssert(!error, @"Unable to parse. %@", error.localizedDescription);
|
||||
return json;
|
||||
}
|
||||
|
||||
- (NSArray*)parseICEServersForPCConfigJSON:(NSDictionary*)pcConfigJSON {
|
||||
NSMutableArray* result = [NSMutableArray array];
|
||||
NSArray* iceServers = pcConfigJSON[@"iceServers"];
|
||||
for (NSDictionary* iceServer in iceServers) {
|
||||
NSString* url = iceServer[@"urls"];
|
||||
NSString* username = pcConfigJSON[@"username"];
|
||||
NSString* credential = iceServer[@"credential"];
|
||||
username = username ? username : @"";
|
||||
credential = credential ? credential : @"";
|
||||
[self logVerbose:[NSString stringWithFormat:@"url [%@] - credential [%@]",
|
||||
url,
|
||||
credential]];
|
||||
RTCICEServer* server =
|
||||
[[RTCICEServer alloc] initWithURI:[NSURL URLWithString:url]
|
||||
username:username
|
||||
password:credential];
|
||||
[result addObject:server];
|
||||
}
|
||||
return result;
|
||||
_params = params;
|
||||
// Generate URL for posting data.
|
||||
NSDictionary *roomJSON = [NSDictionary dictionaryWithJSONData:responseData];
|
||||
_postMessageURL = [self parsePostMessageURLForRoomJSON:roomJSON
|
||||
request:request];
|
||||
[self logVerbose:[NSString stringWithFormat:@"POST message URL:\n%@",
|
||||
_postMessageURL]];
|
||||
}
|
||||
|
||||
- (NSURL*)parsePostMessageURLForRoomJSON:(NSDictionary*)roomJSON
|
||||
@ -207,63 +169,26 @@
|
||||
return [NSURL URLWithString:postMessageUrl];
|
||||
}
|
||||
|
||||
- (RTCMediaConstraints*)parseVideoConstraintsForRoomJSON:
|
||||
(NSDictionary*)roomJSON {
|
||||
NSString* mediaConstraints = roomJSON[@"media_constraints"];
|
||||
RTCMediaConstraints* constraints = nil;
|
||||
if ([mediaConstraints length] > 0) {
|
||||
NSData* constraintsData =
|
||||
[mediaConstraints dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSDictionary* constraintsJSON = [self parseJSONData:constraintsData];
|
||||
id video = constraintsJSON[@"video"];
|
||||
if ([video isKindOfClass:[NSDictionary class]]) {
|
||||
NSDictionary* mandatory = video[@"mandatory"];
|
||||
NSMutableArray* mandatoryContraints =
|
||||
[NSMutableArray arrayWithCapacity:[mandatory count]];
|
||||
[mandatory enumerateKeysAndObjectsUsingBlock:^(
|
||||
id key, id obj, BOOL* stop) {
|
||||
[mandatoryContraints addObject:[[RTCPair alloc] initWithKey:key
|
||||
value:obj]];
|
||||
}];
|
||||
// TODO(tkchin): figure out json formats for optional constraints.
|
||||
constraints =
|
||||
[[RTCMediaConstraints alloc]
|
||||
initWithMandatoryConstraints:mandatoryContraints
|
||||
optionalConstraints:nil];
|
||||
} else if ([video isKindOfClass:[NSNumber class]] && [video boolValue]) {
|
||||
constraints = [[RTCMediaConstraints alloc] init];
|
||||
}
|
||||
}
|
||||
return constraints;
|
||||
}
|
||||
|
||||
- (void)requestTURNServerWithUrl:(NSString*)turnServerUrl
|
||||
- (void)requestTURNServerWithUrl:(NSString *)turnServerUrl
|
||||
completionHandler:
|
||||
(void (^)(RTCICEServer* turnServer))completionHandler {
|
||||
NSURL* turnServerURL = [NSURL URLWithString:turnServerUrl];
|
||||
NSMutableURLRequest* request =
|
||||
(void (^)(RTCICEServer *turnServer))completionHandler {
|
||||
NSURL *turnServerURL = [NSURL URLWithString:turnServerUrl];
|
||||
NSMutableURLRequest *request =
|
||||
[NSMutableURLRequest requestWithURL:turnServerURL];
|
||||
[request addValue:@"Mozilla/5.0" forHTTPHeaderField:@"user-agent"];
|
||||
[request addValue:@"https://apprtc.appspot.com"
|
||||
forHTTPHeaderField:@"origin"];
|
||||
[self sendURLRequest:request
|
||||
completionHandler:^(NSError* error,
|
||||
NSHTTPURLResponse* response,
|
||||
NSData* responseData) {
|
||||
[NSURLConnection sendAsynchronousRequest:request
|
||||
completionHandler:^(NSURLResponse *response,
|
||||
NSData *data,
|
||||
NSError *error) {
|
||||
if (error) {
|
||||
NSLog(@"Unable to get TURN server.");
|
||||
completionHandler(nil);
|
||||
return;
|
||||
}
|
||||
NSDictionary* json = [self parseJSONData:responseData];
|
||||
NSString* username = json[@"username"];
|
||||
NSString* password = json[@"password"];
|
||||
NSArray* uris = json[@"uris"];
|
||||
NSParameterAssert([uris count] > 0);
|
||||
RTCICEServer* turnServer =
|
||||
[[RTCICEServer alloc] initWithURI:[NSURL URLWithString:uris[0]]
|
||||
username:username
|
||||
password:password];
|
||||
NSDictionary *json = [NSDictionary dictionaryWithJSONData:data];
|
||||
RTCICEServer *turnServer = [RTCICEServer serverFromCEODJSONDictionary:json];
|
||||
completionHandler(turnServer);
|
||||
}];
|
||||
}
|
||||
@ -295,26 +220,4 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)sendURLRequest:(NSURLRequest*)request
|
||||
completionHandler:(void (^)(NSError* error,
|
||||
NSHTTPURLResponse* httpResponse,
|
||||
NSData* responseData))completionHandler {
|
||||
dispatch_async(_backgroundQueue, ^{
|
||||
NSError* error = nil;
|
||||
NSURLResponse* response = nil;
|
||||
NSData* responseData = [NSURLConnection sendSynchronousRequest:request
|
||||
returningResponse:&response
|
||||
error:&error];
|
||||
NSParameterAssert(!response ||
|
||||
[response isKindOfClass:[NSHTTPURLResponse class]]);
|
||||
if (error) {
|
||||
NSLog(@"Failed URL request for:%@\nError:%@", request, error);
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
|
||||
completionHandler(error, httpResponse, responseData);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -31,6 +31,7 @@
|
||||
#import "APPRTCAppClient.h"
|
||||
#import "GAEChannelClient.h"
|
||||
#import "RTCICECandidate.h"
|
||||
#import "RTCICECandidate+JSON.h"
|
||||
#import "RTCMediaConstraints.h"
|
||||
#import "RTCMediaStream.h"
|
||||
#import "RTCPair.h"
|
||||
@ -38,6 +39,7 @@
|
||||
#import "RTCPeerConnectionDelegate.h"
|
||||
#import "RTCPeerConnectionFactory.h"
|
||||
#import "RTCSessionDescription.h"
|
||||
#import "RTCSessionDescription+JSON.h"
|
||||
#import "RTCSessionDescriptionDelegate.h"
|
||||
#import "RTCStatsDelegate.h"
|
||||
#import "RTCVideoCapturer.h"
|
||||
@ -158,7 +160,7 @@
|
||||
[RTCVideoCapturer capturerWithDeviceName:cameraID];
|
||||
self.videoSource = [self.peerConnectionFactory
|
||||
videoSourceWithCapturer:capturer
|
||||
constraints:self.client.videoConstraints];
|
||||
constraints:self.client.params.mediaConstraints];
|
||||
localVideoTrack =
|
||||
[self.peerConnectionFactory videoTrackWithID:@"ARDAMSv0"
|
||||
source:self.videoSource];
|
||||
@ -177,7 +179,7 @@
|
||||
#pragma mark - GAEMessageHandler methods
|
||||
|
||||
- (void)onOpen {
|
||||
if (!self.client.initiator) {
|
||||
if (!self.client.params.isInitiator) {
|
||||
[self.logger logMessage:@"Callee; waiting for remote offer"];
|
||||
return;
|
||||
}
|
||||
@ -200,13 +202,8 @@
|
||||
[self.logger logMessage:[NSString stringWithFormat:@"GAE onMessage type - %@",
|
||||
type]];
|
||||
if ([type isEqualToString:@"candidate"]) {
|
||||
NSString* mid = messageData[@"id"];
|
||||
NSNumber* sdpLineIndex = messageData[@"label"];
|
||||
NSString* sdp = messageData[@"candidate"];
|
||||
RTCICECandidate* candidate =
|
||||
[[RTCICECandidate alloc] initWithMid:mid
|
||||
index:sdpLineIndex.intValue
|
||||
sdp:sdp];
|
||||
[RTCICECandidate candidateFromJSONDictionary:messageData];
|
||||
if (self.queuedRemoteCandidates) {
|
||||
[self.queuedRemoteCandidates addObject:candidate];
|
||||
} else {
|
||||
@ -214,10 +211,8 @@
|
||||
}
|
||||
} else if ([type isEqualToString:@"offer"] ||
|
||||
[type isEqualToString:@"answer"]) {
|
||||
NSString* sdpString = messageData[@"sdp"];
|
||||
RTCSessionDescription* sdp = [[RTCSessionDescription alloc]
|
||||
initWithType:type
|
||||
sdp:[[self class] preferISAC:sdpString]];
|
||||
RTCSessionDescription* sdp =
|
||||
[RTCSessionDescription descriptionFromJSONDictionary:messageData];
|
||||
[self.peerConnection setRemoteDescriptionWithDelegate:self
|
||||
sessionDescription:sdp];
|
||||
[self.logger logMessage:@"PC - setRemoteDescription."];
|
||||
@ -283,26 +278,8 @@
|
||||
- (void)peerConnection:(RTCPeerConnection*)peerConnection
|
||||
gotICECandidate:(RTCICECandidate*)candidate {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSLog(@"PCO onICECandidate.\n Mid[%@] Index[%li] Sdp[%@]",
|
||||
candidate.sdpMid,
|
||||
(long)candidate.sdpMLineIndex,
|
||||
candidate.sdp);
|
||||
NSDictionary* json = @{
|
||||
@"type" : @"candidate",
|
||||
@"label" : @(candidate.sdpMLineIndex),
|
||||
@"id" : candidate.sdpMid,
|
||||
@"candidate" : candidate.sdp
|
||||
};
|
||||
NSError* error;
|
||||
NSData* data =
|
||||
[NSJSONSerialization dataWithJSONObject:json options:0 error:&error];
|
||||
if (!error) {
|
||||
[self.client sendData:data];
|
||||
} else {
|
||||
NSAssert(NO,
|
||||
@"Unable to serialize JSON object with error: %@",
|
||||
error.localizedDescription);
|
||||
}
|
||||
NSLog(@"PCO onICECandidate.\n%@", candidate);
|
||||
[self.client sendData:[candidate JSONData]];
|
||||
});
|
||||
}
|
||||
|
||||
@ -330,7 +307,7 @@
|
||||
#pragma mark - RTCSessionDescriptionDelegate
|
||||
|
||||
- (void)peerConnection:(RTCPeerConnection*)peerConnection
|
||||
didCreateSessionDescription:(RTCSessionDescription*)origSdp
|
||||
didCreateSessionDescription:(RTCSessionDescription*)sdp
|
||||
error:(NSError*)error {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (error) {
|
||||
@ -339,19 +316,10 @@
|
||||
return;
|
||||
}
|
||||
[self.logger logMessage:@"SDP onSuccess(SDP) - set local description."];
|
||||
RTCSessionDescription* sdp = [[RTCSessionDescription alloc]
|
||||
initWithType:origSdp.type
|
||||
sdp:[[self class] preferISAC:origSdp.description]];
|
||||
[self.peerConnection setLocalDescriptionWithDelegate:self
|
||||
sessionDescription:sdp];
|
||||
[self.logger logMessage:@"PC setLocalDescription."];
|
||||
NSDictionary* json = @{@"type" : sdp.type, @"sdp" : sdp.description};
|
||||
NSError* jsonError;
|
||||
NSData* data = [NSJSONSerialization dataWithJSONObject:json
|
||||
options:0
|
||||
error:&jsonError];
|
||||
NSAssert(!jsonError, @"Error: %@", jsonError.description);
|
||||
[self.client sendData:data];
|
||||
[self.client sendData:[sdp JSONData]];
|
||||
});
|
||||
}
|
||||
|
||||
@ -364,7 +332,7 @@
|
||||
return;
|
||||
}
|
||||
[self.logger logMessage:@"SDP onSuccess() - possibly drain candidates"];
|
||||
if (!self.client.initiator) {
|
||||
if (!self.client.params.isInitiator) {
|
||||
if (self.peerConnection.remoteDescription &&
|
||||
!self.peerConnection.localDescription) {
|
||||
[self.logger logMessage:@"Callee, setRemoteDescription succeeded"];
|
||||
@ -404,69 +372,6 @@
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
// Match |pattern| to |string| and return the first group of the first
|
||||
// match, or nil if no match was found.
|
||||
+ (NSString*)firstMatch:(NSRegularExpression*)pattern
|
||||
withString:(NSString*)string {
|
||||
NSTextCheckingResult* result =
|
||||
[pattern firstMatchInString:string
|
||||
options:0
|
||||
range:NSMakeRange(0, [string length])];
|
||||
if (!result)
|
||||
return nil;
|
||||
return [string substringWithRange:[result rangeAtIndex:1]];
|
||||
}
|
||||
|
||||
// Mangle |origSDP| to prefer the ISAC/16k audio codec.
|
||||
+ (NSString*)preferISAC:(NSString*)origSDP {
|
||||
int mLineIndex = -1;
|
||||
NSString* isac16kRtpMap = nil;
|
||||
NSArray* lines = [origSDP componentsSeparatedByString:@"\n"];
|
||||
NSRegularExpression* isac16kRegex = [NSRegularExpression
|
||||
regularExpressionWithPattern:@"^a=rtpmap:(\\d+) ISAC/16000[\r]?$"
|
||||
options:0
|
||||
error:nil];
|
||||
for (int i = 0;
|
||||
(i < [lines count]) && (mLineIndex == -1 || isac16kRtpMap == nil);
|
||||
++i) {
|
||||
NSString* line = [lines objectAtIndex:i];
|
||||
if ([line hasPrefix:@"m=audio "]) {
|
||||
mLineIndex = i;
|
||||
continue;
|
||||
}
|
||||
isac16kRtpMap = [self firstMatch:isac16kRegex withString:line];
|
||||
}
|
||||
if (mLineIndex == -1) {
|
||||
NSLog(@"No m=audio line, so can't prefer iSAC");
|
||||
return origSDP;
|
||||
}
|
||||
if (isac16kRtpMap == nil) {
|
||||
NSLog(@"No ISAC/16000 line, so can't prefer iSAC");
|
||||
return origSDP;
|
||||
}
|
||||
NSArray* origMLineParts =
|
||||
[[lines objectAtIndex:mLineIndex] componentsSeparatedByString:@" "];
|
||||
NSMutableArray* newMLine =
|
||||
[NSMutableArray arrayWithCapacity:[origMLineParts count]];
|
||||
int origPartIndex = 0;
|
||||
// Format is: m=<media> <port> <proto> <fmt> ...
|
||||
[newMLine addObject:[origMLineParts objectAtIndex:origPartIndex++]];
|
||||
[newMLine addObject:[origMLineParts objectAtIndex:origPartIndex++]];
|
||||
[newMLine addObject:[origMLineParts objectAtIndex:origPartIndex++]];
|
||||
[newMLine addObject:isac16kRtpMap];
|
||||
for (; origPartIndex < [origMLineParts count]; ++origPartIndex) {
|
||||
if (![isac16kRtpMap
|
||||
isEqualToString:[origMLineParts objectAtIndex:origPartIndex]]) {
|
||||
[newMLine addObject:[origMLineParts objectAtIndex:origPartIndex]];
|
||||
}
|
||||
}
|
||||
NSMutableArray* newLines = [NSMutableArray arrayWithCapacity:[lines count]];
|
||||
[newLines addObjectsFromArray:lines];
|
||||
[newLines replaceObjectAtIndex:mLineIndex
|
||||
withObject:[newMLine componentsJoinedByString:@" "]];
|
||||
return [newLines componentsJoinedByString:@"\n"];
|
||||
}
|
||||
|
||||
- (void)drainRemoteCandidates {
|
||||
for (RTCICECandidate* candidate in self.queuedRemoteCandidates) {
|
||||
[self.peerConnection addICECandidate:candidate];
|
||||
|
46
talk/examples/objc/AppRTCDemo/ARDSignalingParams.h
Normal file
46
talk/examples/objc/AppRTCDemo/ARDSignalingParams.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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 <Foundation/Foundation.h>
|
||||
|
||||
#import "RTCMediaConstraints.h"
|
||||
|
||||
// Struct for holding the signaling parameters of an AppRTC room.
|
||||
@interface ARDSignalingParams : NSObject
|
||||
|
||||
@property(nonatomic, assign) BOOL isInitiator;
|
||||
@property(nonatomic, readonly) NSArray *errorMessages;
|
||||
@property(nonatomic, readonly) RTCMediaConstraints *offerConstraints;
|
||||
@property(nonatomic, readonly) RTCMediaConstraints *mediaConstraints;
|
||||
@property(nonatomic, readonly) NSMutableArray *iceServers;
|
||||
@property(nonatomic, readonly) NSURL *signalingServerURL;
|
||||
@property(nonatomic, readonly) NSURL *turnRequestURL;
|
||||
@property(nonatomic, readonly) NSString *channelToken;
|
||||
|
||||
+ (ARDSignalingParams *)paramsFromJSONData:(NSData *)data;
|
||||
|
||||
@end
|
130
talk/examples/objc/AppRTCDemo/ARDSignalingParams.m
Normal file
130
talk/examples/objc/AppRTCDemo/ARDSignalingParams.m
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* 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 "ARDSignalingParams.h"
|
||||
|
||||
#import "ARDUtilities.h"
|
||||
#import "RTCICEServer+JSON.h"
|
||||
#import "RTCMediaConstraints+JSON.h"
|
||||
|
||||
static NSString const *kARDSignalingParamsErrorKey = @"error";
|
||||
static NSString const *kARDSignalingParamsErrorMessagesKey = @"error_messages";
|
||||
static NSString const *kARDSignalingParamsInitiatorKey = @"initiator";
|
||||
static NSString const *kARDSignalingParamsPeerConnectionConfigKey =
|
||||
@"pc_config";
|
||||
static NSString const *kARDSignalingParamsICEServersKey = @"iceServers";
|
||||
static NSString const *kARDSignalingParamsMediaConstraintsKey =
|
||||
@"media_constraints";
|
||||
static NSString const *kARDSignalingParamsMediaConstraintsVideoKey =
|
||||
@"video";
|
||||
static NSString const *kARDSignalingParamsTokenKey = @"token";
|
||||
static NSString const *kARDSignalingParamsTurnRequestUrlKey = @"turn_url";
|
||||
|
||||
@interface ARDSignalingParams ()
|
||||
|
||||
@property(nonatomic, strong) NSArray *errorMessages;
|
||||
@property(nonatomic, strong) RTCMediaConstraints *offerConstraints;
|
||||
@property(nonatomic, strong) RTCMediaConstraints *mediaConstraints;
|
||||
@property(nonatomic, strong) NSMutableArray *iceServers;
|
||||
@property(nonatomic, strong) NSURL *signalingServerURL;
|
||||
@property(nonatomic, strong) NSURL *turnRequestURL;
|
||||
@property(nonatomic, strong) NSString *channelToken;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ARDSignalingParams
|
||||
|
||||
@synthesize errorMessages = _errorMessages;
|
||||
@synthesize isInitiator = _isInitiator;
|
||||
@synthesize offerConstraints = _offerConstraints;
|
||||
@synthesize mediaConstraints = _mediaConstraints;
|
||||
@synthesize iceServers = _iceServers;
|
||||
@synthesize signalingServerURL = _signalingServerURL;
|
||||
|
||||
+ (ARDSignalingParams *)paramsFromJSONData:(NSData *)data {
|
||||
NSDictionary *paramsJSON = [NSDictionary dictionaryWithJSONData:data];
|
||||
if (!paramsJSON) {
|
||||
return nil;
|
||||
}
|
||||
ARDSignalingParams *params = [[ARDSignalingParams alloc] init];
|
||||
|
||||
// Parse errors.
|
||||
BOOL hasError = NO;
|
||||
NSArray *errorMessages = paramsJSON[kARDSignalingParamsErrorMessagesKey];
|
||||
if (errorMessages.count > 0) {
|
||||
params.errorMessages = errorMessages;
|
||||
return params;
|
||||
}
|
||||
|
||||
// Parse ICE servers.
|
||||
NSString *peerConnectionConfigString =
|
||||
paramsJSON[kARDSignalingParamsPeerConnectionConfigKey];
|
||||
NSDictionary *peerConnectionConfig =
|
||||
[NSDictionary dictionaryWithJSONString:peerConnectionConfigString];
|
||||
NSArray *iceServerJSONArray =
|
||||
peerConnectionConfig[kARDSignalingParamsICEServersKey];
|
||||
NSMutableArray *iceServers = [NSMutableArray array];
|
||||
for (NSDictionary *iceServerJSON in iceServerJSONArray) {
|
||||
RTCICEServer *iceServer =
|
||||
[RTCICEServer serverFromJSONDictionary:iceServerJSON];
|
||||
[iceServers addObject:iceServer];
|
||||
}
|
||||
params.iceServers = iceServers;
|
||||
|
||||
// Parse initiator.
|
||||
BOOL isInitiator = [paramsJSON[kARDSignalingParamsInitiatorKey] boolValue];
|
||||
params.isInitiator = isInitiator;
|
||||
|
||||
// Parse video constraints.
|
||||
RTCMediaConstraints *videoConstraints = nil;
|
||||
NSString *mediaConstraintsJSONString =
|
||||
paramsJSON[kARDSignalingParamsMediaConstraintsKey];
|
||||
NSDictionary *mediaConstraintsJSON =
|
||||
[NSDictionary dictionaryWithJSONString:mediaConstraintsJSONString];
|
||||
id videoJSON =
|
||||
mediaConstraintsJSON[kARDSignalingParamsMediaConstraintsVideoKey];
|
||||
if ([videoJSON isKindOfClass:[NSDictionary class]]) {
|
||||
videoConstraints =
|
||||
[RTCMediaConstraints constraintsFromJSONDictionary:videoJSON];
|
||||
} else if ([videoJSON isKindOfClass:[NSNumber class]] &&
|
||||
[videoJSON boolValue]) {
|
||||
videoConstraints = [[RTCMediaConstraints alloc] init];
|
||||
}
|
||||
params.mediaConstraints = videoConstraints;
|
||||
|
||||
// Parse channel token.
|
||||
NSString *token = paramsJSON[kARDSignalingParamsTokenKey];
|
||||
params.channelToken = token;
|
||||
|
||||
// Parse turn request url.
|
||||
params.turnRequestURL =
|
||||
[NSURL URLWithString:paramsJSON[kARDSignalingParamsTurnRequestUrlKey]];
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
@end
|
46
talk/examples/objc/AppRTCDemo/ARDUtilities.h
Normal file
46
talk/examples/objc/AppRTCDemo/ARDUtilities.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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 <Foundation/Foundation.h>
|
||||
|
||||
@interface NSDictionary (ARDUtilites)
|
||||
|
||||
// Creates a dictionary with the keys and values in the JSON object.
|
||||
+ (NSDictionary *)dictionaryWithJSONString:(NSString *)jsonString;
|
||||
+ (NSDictionary *)dictionaryWithJSONData:(NSData *)jsonData;
|
||||
|
||||
@end
|
||||
|
||||
@interface NSURLConnection (ARDUtilities)
|
||||
|
||||
// Issues an asynchronous request that calls back on main queue.
|
||||
+ (void)sendAsynchronousRequest:(NSURLRequest *)request
|
||||
completionHandler:(void (^)(NSURLResponse *response,
|
||||
NSData *data,
|
||||
NSError *error))completionHandler;
|
||||
|
||||
@end
|
72
talk/examples/objc/AppRTCDemo/ARDUtilities.m
Normal file
72
talk/examples/objc/AppRTCDemo/ARDUtilities.m
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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 "ARDUtilities.h"
|
||||
|
||||
@implementation NSDictionary (ARDUtilites)
|
||||
|
||||
+ (NSDictionary *)dictionaryWithJSONString:(NSString *)jsonString {
|
||||
NSParameterAssert(jsonString.length > 0);
|
||||
NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSError *error = nil;
|
||||
NSDictionary *dict =
|
||||
[NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error parsing JSON: %@", error.localizedDescription);
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)dictionaryWithJSONData:(NSData *)jsonData {
|
||||
NSError *error = nil;
|
||||
NSDictionary *dict =
|
||||
[NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error parsing JSON: %@", error.localizedDescription);
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSURLConnection (ARDUtilities)
|
||||
|
||||
+ (void)sendAsynchronousRequest:(NSURLRequest *)request
|
||||
completionHandler:(void (^)(NSURLResponse *response,
|
||||
NSData *data,
|
||||
NSError *error))completionHandler {
|
||||
// Kick off an async request which will call back on main thread.
|
||||
[NSURLConnection sendAsynchronousRequest:request
|
||||
queue:[NSOperationQueue mainQueue]
|
||||
completionHandler:^(NSURLResponse *response,
|
||||
NSData *data,
|
||||
NSError *error) {
|
||||
completionHandler(response, data, error);
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
35
talk/examples/objc/AppRTCDemo/RTCICECandidate+JSON.h
Normal file
35
talk/examples/objc/AppRTCDemo/RTCICECandidate+JSON.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 "RTCICECandidate.h"
|
||||
|
||||
@interface RTCICECandidate (JSON)
|
||||
|
||||
+ (RTCICECandidate *)candidateFromJSONDictionary:(NSDictionary *)dictionary;
|
||||
- (NSData *)JSONData;
|
||||
|
||||
@end
|
56
talk/examples/objc/AppRTCDemo/RTCICECandidate+JSON.m
Normal file
56
talk/examples/objc/AppRTCDemo/RTCICECandidate+JSON.m
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 "RTCICECandidate+JSON.h"
|
||||
|
||||
static NSString const *kRTCICECandidateTypeKey = @"type";
|
||||
static NSString const *kRTCICECandidateTypeValue = @"candidate";
|
||||
static NSString const *kRTCICECandidateMidKey = @"id";
|
||||
static NSString const *kRTCICECandidateMLineIndexKey = @"label";
|
||||
static NSString const *kRTCICECandidateSdpKey = @"candidate";
|
||||
|
||||
@implementation RTCICECandidate (JSON)
|
||||
|
||||
+ (RTCICECandidate *)candidateFromJSONDictionary:(NSDictionary *)dictionary {
|
||||
NSString *mid = dictionary[kRTCICECandidateMidKey];
|
||||
NSString *sdp = dictionary[kRTCICECandidateSdpKey];
|
||||
NSNumber *num = dictionary[kRTCICECandidateMLineIndexKey];
|
||||
NSInteger mLineIndex = [num integerValue];
|
||||
return [[RTCICECandidate alloc] initWithMid:mid index:mLineIndex sdp:sdp];
|
||||
}
|
||||
|
||||
- (NSData *)JSONData {
|
||||
NSDictionary *json = @{
|
||||
kRTCICECandidateTypeKey : kRTCICECandidateTypeValue,
|
||||
kRTCICECandidateMLineIndexKey : @(self.sdpMLineIndex),
|
||||
kRTCICECandidateMidKey : self.sdpMid,
|
||||
kRTCICECandidateSdpKey : self.sdp
|
||||
};
|
||||
return [NSJSONSerialization dataWithJSONObject:json options:0 error:nil];
|
||||
}
|
||||
|
||||
@end
|
36
talk/examples/objc/AppRTCDemo/RTCICEServer+JSON.h
Normal file
36
talk/examples/objc/AppRTCDemo/RTCICEServer+JSON.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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 "RTCICEServer.h"
|
||||
|
||||
@interface RTCICEServer (JSON)
|
||||
|
||||
+ (RTCICEServer *)serverFromJSONDictionary:(NSDictionary *)dictionary;
|
||||
// CEOD provides different JSON, and this parses that.
|
||||
+ (RTCICEServer *)serverFromCEODJSONDictionary:(NSDictionary *)dictionary;
|
||||
|
||||
@end
|
59
talk/examples/objc/AppRTCDemo/RTCICEServer+JSON.m
Normal file
59
talk/examples/objc/AppRTCDemo/RTCICEServer+JSON.m
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 "RTCICEServer+JSON.h"
|
||||
|
||||
static NSString const *kRTCICEServerUsernameKey = @"username";
|
||||
static NSString const *kRTCICEServerPasswordKey = @"password";
|
||||
static NSString const *kRTCICEServerUrisKey = @"uris";
|
||||
static NSString const *kRTCICEServerUrlKey = @"urls";
|
||||
static NSString const *kRTCICEServerCredentialKey = @"credential";
|
||||
|
||||
@implementation RTCICEServer (JSON)
|
||||
|
||||
+ (RTCICEServer *)serverFromJSONDictionary:(NSDictionary *)dictionary {
|
||||
NSString *url = dictionary[kRTCICEServerUrlKey];
|
||||
NSString *username = dictionary[kRTCICEServerUsernameKey];
|
||||
NSString *credential = dictionary[kRTCICEServerCredentialKey];
|
||||
username = username ? username : @"";
|
||||
credential = credential ? credential : @"";
|
||||
return [[RTCICEServer alloc] initWithURI:[NSURL URLWithString:url]
|
||||
username:username
|
||||
password:credential];
|
||||
}
|
||||
|
||||
+ (RTCICEServer *)serverFromCEODJSONDictionary:(NSDictionary *)dictionary {
|
||||
NSString *username = dictionary[kRTCICEServerUsernameKey];
|
||||
NSString *password = dictionary[kRTCICEServerPasswordKey];
|
||||
NSArray *uris = dictionary[kRTCICEServerUrisKey];
|
||||
NSParameterAssert(uris.count > 0);
|
||||
return [[RTCICEServer alloc] initWithURI:[NSURL URLWithString:uris[0]]
|
||||
username:username
|
||||
password:password];
|
||||
}
|
||||
|
||||
@end
|
36
talk/examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.h
Normal file
36
talk/examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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 "RTCMediaConstraints.h"
|
||||
|
||||
@interface RTCMediaConstraints (JSON)
|
||||
|
||||
+ (RTCMediaConstraints *)constraintsFromJSONDictionary:
|
||||
(NSDictionary *)dictionary;
|
||||
|
||||
@end
|
||||
|
54
talk/examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.m
Normal file
54
talk/examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.m
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 "RTCMediaConstraints+JSON.h"
|
||||
|
||||
#import "RTCPair.h"
|
||||
|
||||
static NSString const *kRTCMediaConstraintsMandatoryKey = @"mandatory";
|
||||
|
||||
@implementation RTCMediaConstraints (JSON)
|
||||
|
||||
+ (RTCMediaConstraints *)constraintsFromJSONDictionary:
|
||||
(NSDictionary *)dictionary {
|
||||
NSDictionary *mandatory = dictionary[kRTCMediaConstraintsMandatoryKey];
|
||||
NSMutableArray *mandatoryContraints =
|
||||
[NSMutableArray arrayWithCapacity:[mandatory count]];
|
||||
[mandatory enumerateKeysAndObjectsUsingBlock:^(
|
||||
id key, id obj, BOOL *stop) {
|
||||
[mandatoryContraints addObject:[[RTCPair alloc] initWithKey:key
|
||||
value:obj]];
|
||||
}];
|
||||
// TODO(tkchin): figure out json formats for optional constraints.
|
||||
RTCMediaConstraints *constraints =
|
||||
[[RTCMediaConstraints alloc]
|
||||
initWithMandatoryConstraints:mandatoryContraints
|
||||
optionalConstraints:nil];
|
||||
return constraints;
|
||||
}
|
||||
|
||||
@end
|
36
talk/examples/objc/AppRTCDemo/RTCSessionDescription+JSON.h
Normal file
36
talk/examples/objc/AppRTCDemo/RTCSessionDescription+JSON.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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 "RTCSessionDescription.h"
|
||||
|
||||
@interface RTCSessionDescription (JSON)
|
||||
|
||||
+ (RTCSessionDescription *)descriptionFromJSONDictionary:
|
||||
(NSDictionary *)dictionary;
|
||||
- (NSData *)JSONData;
|
||||
|
||||
@end
|
50
talk/examples/objc/AppRTCDemo/RTCSessionDescription+JSON.m
Normal file
50
talk/examples/objc/AppRTCDemo/RTCSessionDescription+JSON.m
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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 "RTCSessionDescription+JSON.h"
|
||||
|
||||
static NSString const *kRTCSessionDescriptionTypeKey = @"type";
|
||||
static NSString const *kRTCSessionDescriptionSdpKey = @"sdp";
|
||||
|
||||
@implementation RTCSessionDescription (JSON)
|
||||
|
||||
+ (RTCSessionDescription *)descriptionFromJSONDictionary:
|
||||
(NSDictionary *)dictionary {
|
||||
NSString *type = dictionary[kRTCSessionDescriptionTypeKey];
|
||||
NSString *sdp = dictionary[kRTCSessionDescriptionSdpKey];
|
||||
return [[RTCSessionDescription alloc] initWithType:type sdp:sdp];
|
||||
}
|
||||
|
||||
- (NSData *)JSONData {
|
||||
NSDictionary *json = @{
|
||||
kRTCSessionDescriptionTypeKey : self.type,
|
||||
kRTCSessionDescriptionSdpKey : self.description
|
||||
};
|
||||
return [NSJSONSerialization dataWithJSONObject:json options:0 error:nil];
|
||||
}
|
||||
|
||||
@end
|
@ -283,8 +283,20 @@
|
||||
'examples/objc/AppRTCDemo/APPRTCAppClient.m',
|
||||
'examples/objc/AppRTCDemo/APPRTCConnectionManager.h',
|
||||
'examples/objc/AppRTCDemo/APPRTCConnectionManager.m',
|
||||
'examples/objc/AppRTCDemo/ARDSignalingParams.h',
|
||||
'examples/objc/AppRTCDemo/ARDSignalingParams.m',
|
||||
'examples/objc/AppRTCDemo/ARDUtilities.h',
|
||||
'examples/objc/AppRTCDemo/ARDUtilities.m',
|
||||
'examples/objc/AppRTCDemo/GAEChannelClient.h',
|
||||
'examples/objc/AppRTCDemo/GAEChannelClient.m',
|
||||
'examples/objc/AppRTCDemo/RTCICECandidate+JSON.h',
|
||||
'examples/objc/AppRTCDemo/RTCICECandidate+JSON.m',
|
||||
'examples/objc/AppRTCDemo/RTCICEServer+JSON.h',
|
||||
'examples/objc/AppRTCDemo/RTCICEServer+JSON.m',
|
||||
'examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.h',
|
||||
'examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.m',
|
||||
'examples/objc/AppRTCDemo/RTCSessionDescription+JSON.h',
|
||||
'examples/objc/AppRTCDemo/RTCSessionDescription+JSON.m',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'CLANG_ENABLE_OBJC_ARC': 'YES',
|
||||
|
Loading…
Reference in New Issue
Block a user