iOS的licode分析
viewDidLoad
//创建本地视频流
initLocalStream
initWithLocalStreamWithMediaConstraints:nil
_peerFactory = [[RTCPeerConnectionFactory alloc] init];
_mediaConstraints = mediaConstraints; //这里是nil
createLocalStream
_mediaStream = [_peerFactory mediaStreamWithLabel:@"LCMS"];
//将视频和音频添加到流轨迹中
generateVideoTracks
[_mediaStream removeVideoTrack:localVideoTrack];
RTCVideoTrack *localVideoTrack = [self createLocalVideoTrack];
[_mediaStream addVideoTrack:localVideoTrack];
[_mediaStream addAudioTrack:[_peerFactory audioTrackWithID:@"LCMSa0"]];
//添加渲染
RTCVideoTrack *videoTrack = [localStream.mediaStream.videoTracks objectAtIndex:0];
[videoTrack addRenderer:_localView];
remoteRoom = [[ECRoom alloc] initWithDelegate:self andPeerFactory:localStream.peerFactory];
//connect按钮
obtainMultiVideoConferenceToken
[self buildRequest:kLicodeServerURLString method:@"POST" postData:postData];
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue]
—>completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
token = [self parseResponse:data];
completion(TRUE, token);
obtainMultiVideoConferenceToken
—>completion:^(BOOL result, NSString *token)
[remoteRoom createSignalingChannelWithEncodedToken:token];
signalingChannel = [[ECSignalingChannel alloc] initWithEncodedToken:encodedToken roomDelegate:self];
[signalingChannel connect];
socketIO = [[SocketIO alloc] initWithDelegate:self];
socketIO.useSecure = [decodedToken objectForKey:@"secure"]==@"1"?YES:NO;
socketIO.returnAllDataFromAck = TRUE;
NSString *hostURLString = decodedToken[@"host"];
hostURLString = [NSString stringWithFormat:@"http://%@", hostURLString];
NSURL *url = [NSURL URLWithString:hostURLString];
[socketIO connectToHost:[url host] onPort:[[url port] intValue]];
socketIODidConnect
[socketIO sendEvent:@"token" withData:decodedToken
andAcknowledge:[self onSendTokenCallback]];
onSendTokenCallback
if ([status isEqualToString:@"success"])
[_roomDelegate signalingChannel:self didConnectToRoom:roomMetadata];
[_delegate room:self didConnect:roomMeta];
[remoteRoom publish:localStream withOptions:…];
NSMutableDictionary *opts = [options mutableCopy];
opts[@"video"] = videoCount > 0 ? @"true" : @"false";
opts[@"audio"] = audioCount > 0 ? @"true" : @"false”;
if (!opts[@"data"]) {
opts[@"data"] = @{};
}
if (!opts[@"attributes"]) {
opts[@"attributes"] = @"false";
}
[signalingChannel publish:opts signalingChannelDelegate:publishClient];
attributes[@"state"] = @"erizo";
[socketIO sendEvent:@"publish" withData:dataToSend
andAcknowledge:[self onPublishCallback:delegate]];
[_delegate room:self didReceiveStreamsList:streamIds];
for (id item in list) {
[remoteRoom subscribe:[item valueForKey:@"id"]];
[signalingChannel subscribe:streamId signalingChannelDelegate:subscribeClient];
streamId = [NSString stringWithFormat:@"%@", streamId];
NSDictionary *attributes = @{
@"streamId": streamId,
};
NSArray *dataToSend = [[NSArray alloc] initWithObjects: attributes, @"null", nil];
[socketIO sendEvent:@"subscribe" withData:dataToSend
andAcknowledge:[self onSubscribeCallback:streamId signalingChannelDelegate:delegate]];
}
onPublishCallback:delegate
NSString *streamId = [(NSNumber*)[argsData objectAtIndex:0] stringValue];
[self setSignalingDelegateForStreamId:signalingDelegate streamId:streamId];
[signalingDelegate signalingChannelDidOpenChannel:self];
[signalingDelegate signalingChannel:self didReceiveServerConfiguration:roomMetadata];
for (NSDictionary *dict in [_serverConfiguration objectForKey:@"iceServers"]) {
NSString *username = [dict objectForKey:@"username"] ? [dict objectForKey:@"username"] : @"";
NSString *password = [dict objectForKey:@"credential"] ? [dict objectForKey:@"credential"] : @"";
RTCICEServer *iceServer = [[RTCICEServer alloc]
initWithURI:[NSURL URLWithString:[dict objectForKey:@"url"]]
username:username
password:password];
[_iceServers addObject:iceServer];
}
[signalingDelegate signalingChannel:self readyToPublishStreamId:streamId];
[self startPublishSignaling];
RTCMediaConstraints *constraints = [self defaultPeerConnectionConstraints];
RTCConfiguration *config = [[RTCConfiguration alloc] init];
config.iceServers = _iceServers;
_peerConnection = [_factory peerConnectionWithConfiguration:config
constraints:constraints
delegate:self];
_localStream = [self.delegate streamToPublishByAppClient:self];
[_peerConnection addStream:_localStream];
[_peerConnection createOfferWithDelegate:self
constraints:[self defaultOfferConstraints]];
[_roomDelegate signalingChannel:self didReceiveStreamIdReadyToPublish:streamId];
(void)socketIO:(SocketIO *)socket didReceiveEvent:(SocketIOPacket *)packet
if ([packet.name isEqualToString:kEventOnAddStream])
if ([packet.name isEqualToString:kEventOnRemoveStream])
if ([packet.name isEqualToString:kEventSignalingMessage])
if ([packet.name isEqualToString:kEventPublishMe])
if ([packet.name isEqualToString:kEventSignalingMsgPeer])
didCreateSessionDescription
[_peerConnection setLocalDescriptionWithDelegate:self
sessionDescription:newSDP];
[_signalingChannel sendSignalingMessage:message];
gotICECandidate
ECICECandidateMessage *message =
[[ECICECandidateMessage alloc] initWithCandidate:candidate andStreamId:currentStreamId];
[_signalingChannel enqueueSignalingMessage:message];
if (message.type == kECSignalingMessageTypeAnswer ||
message.type == kECSignalingMessageTypeOffer) {
[[outMessagesQueues objectForKey:message.streamId] insertObject:message atIndex:0];
} else {
[[outMessagesQueues objectForKey:message.streamId] addObject:message];
}
iceGatheringChanged
if (newState == RTCICEGatheringComplete) {
[_signalingChannel drainMessageQueueForStreamId:currentStreamId];
for (ECSignalingMessage *message in [outMessagesQueues objectForKey:streamId]) {
[self sendSignalingMessage:message];
}
[[outMessagesQueues objectForKey:streamId] removeAllObjects];
}
peerConnection:(RTCPeerConnection *)peerConnection addedStream:(RTCMediaStream *)stream
[self.delegate appClient:self didReceiveRemoteStream:stream withStreamId:currentStreamId];
ECStream *erizoStream = [[ECStream alloc] initWithRTCMediaStream:stream
withStreamId:streamId];
[_delegate room:self didSubscribeStream:erizoStream];
[self showCallConnectViews:NO updateStatusMessage:[NSString stringWithFormat:@"Subscribed: %@", stream.streamId]];
[self watchStream:stream];
CGRect frame = CGRectMake(0, 0, vWidth, vHeight);
ECPlayerView *playerView = [[ECPlayerView alloc] initWithLiveStream:stream frame:frame];
[playerViews addObject:playerView];
[self.view addSubview:playerView];
================================================================================
================================================================================
================================================================================
@protocol ECClientDelegate <NSObject> //ECRoom
…
@end
@interface ECClient : NSObject
@property (strong, nonatomic) id<ECClientDelegate> delegate;//ECClient -> ECRoom
…
@end
@interface ECClient () <ECSignalingChannelDelegate, RTCPeerConnectionDelegate, RTCSessionDescriptionDelegate>
//RTCPeerConnectionDelegate and RTCSessionDescriptionDelegate => webrtc interface
…
@end
---------------------------------------------------
@protocol ECSignalingChannelDelegate //ECClient
…
@end
++++++++++++++++++++++++++++++++++++++++++++++++
//ECClient
- (instancetype)initWithDelegate:(id<ECClientDelegate>)delegate
andPeerFactory:(RTCPeerConnectionFactory *)peerFactory {
if (self = [self init]) {
_delegate = delegate;
_factory = peerFactory;
}
return self;
}
//ECRoom
ECClient *publishClient = [[ECClient alloc] initWithDelegate:self
andPeerFactory:stream.peerFactory];
…
[signalingChannel publish:opts signalingChannelDelegate:publishClient];
…
[streamSignalingDelegates setValue:delegate forKey:streamId];
++++++++++++++++++++++++++++++++++++++++++++++++
@protocol ECSignalingChannelRoomDelegate //ECRoom
…
@end
@interface ECSignalingChannel : NSObject
@property (weak, nonatomic) id<ECSignalingChannelRoomDelegate> roomDelegate; //ECSignalingChannel -> ECRoom
…
@end
@interface ECSignalingChannel () <SocketIODelegate>
@end
---------------------------------------------------
@interface ECSignalingMessage : NSObject
…
@end
---------------------------------------------------
@protocol ECRoomDelegate <NSObject> //MultiConferenceViewController
…
@end
@interface ECRoom : NSObject <ECSignalingChannelRoomDelegate, ECClientDelegate>
@property (weak, nonatomic, readonly) id <ECRoomDelegate> delegate; //ECRoom -> MultiConferenceViewController
…
@end
---------------------------------------------------
@interface MultiConferenceViewController : UIViewController <ECRoomDelegate>
…
@end
#########################################################################
streamSignalingDelegates // streamId -> ECRoom
ECRoom{
ECSignalingChannel *signalingChannel;
ECClient *publishClient;
ECClient *subscribeClient;
}
ECClient {
ECClientState state;
NSString *currentStreamId;
NSString *peerSocketValue;
Boolean setRemoteDesc;
}
ECSignalingChannel {
SocketIO *socketIO;
BOOL isConnected;
NSString *encodedToken;
NSDictionary *decodedToken;
NSMutableDictionary *outMessagesQueues; // for candidate
NSMutableDictionary *streamSignalingDelegates; // streamid -> ECRoom
NSMutableDictionary *peerSignalingDelegates; // peerSock -> ECRoom
NSDictionary *roomMetadata;
NSString *localStreamId;
ECStream *localStreamMe;
}
iOS的licode_APP简单分析
最新推荐文章于 2024-06-24 09:38:07 发布