...
1. Импорт API. код
Code Block | ||||
---|---|---|---|---|
| ||||
#import <FPWCSApi2/FPWCSApi2.h> |
...
- URL WCS-сервера
- имя пользователя чат-комнаты
Code Block | ||||
---|---|---|---|---|
| ||||
- (void)connect { FPWCSApi2RoomManagerOptions *options = [[FPWCSApi2RoomManagerOptions alloc] init]; options.urlServer = _connectUrl.text; options.username = _connectLogin.input.text; NSError *error; roomManager = [FPWCSApi2 createRoomManager:options error:&error]; if (!roomManager) { UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"Failed to connect" message:error.localizedDescription preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction* okButton = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { [self onDisconnected]; }]; alertControllerWithTitle:@"Failed to connect" message:error.localizedDescription preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction* okButton = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { [self onDisconnected]; }]; [alert addAction:okButton]; [self presentViewController:alert animated:YES completion:nil]; } [roomManager on:kFPWCSRoomManagerEventConnected callback:^(FPWCSApi2RoomManager *rManager){ [self changeConnectionStatus:kFPWCSRoomManagerEventConnected]; ]; [self onConnected:rManager]; }]; [roomManager on:kFPWCSRoomManagerEventFailed callback:^(FPWCSApi2RoomManager *rManager){ [self changeConnectionStatus:kFPWCSRoomManagerEventDisconnected]; [self onUnpublished]; [self onLeaved]; [self onDisconnected]; }]; [roomManager on:kFPWCSRoomManagerEventDisconnected callback:^(FPWCSApi2RoomManager *rManager){ [self changeConnectionStatus:kFPWCSRoomManagerEventDisconnected]; [self onUnpublished]; [self onLeaved]; [self onDisconnected]; }]; } |
3. Присоединение к конференции.
...
- имя чат-комнаты
Code Block | ||||
---|---|---|---|---|
| ||||
FPWCSApi2RoomOptions * options = [[FPWCSApi2RoomOptions alloc] init]; options.name = _joinRoomName.input.text; room = [roomManager join:options]; |
...
Если текущий участник остается в комнате, запускается проигрывание потока от других участников при помощи метода FPWCSApi2RoomParticipant play
Code Block | ||||
---|---|---|---|---|
| ||||
[room onStateCallback:^(FPWCSApi2Room *room) { NSDictionary *participants = [room getParticipants]; if ([participants count] >= 3) { [room leave:nil]; _joinStatus.text = @"Room is full"; [self changeViewState:_joinButton enabled:YES]; return; } } NSString *chatState = @"participants: "; for (NSString* key in participants) { FPWCSApi2RoomParticipant *participant = [participants valueForKey:key]; ParticipantView *pv = [freeViews pop]; [busyViews setValue:pv forKey:[participant getName]]; [participant play:pv.display]; pv.login.text = [participant getName]; chatState = [NSString stringWithFormat:@"%@%@, ", chatState, [participant getName]]; } _joinStatus.text = @"JOINED"; [self changeViewState:_joinButton enabled:YES]; [_joinButton setTitle:@"LEAVE" forState:UIControlStateNormal]; [self changeViewState:_publishButton enabled:YES]; [self changeViewState:_sendButton enabled:YES]; if ([participants count] == 0) { _messageHistory.text = [NSString stringWithFormat:@"%@\n%@ - %@", _messageHistory.text, @"chat", @"room is empty"]; } else { _messageHistory.text = [NSString stringWithFormat:@"%@\n%@ - %@", _messageHistory.text, @"chat", [chatState substringToIndex:MAX((int)[chatState length]-2, 0)]]; } }]; |
5. Публикация видеопотока.
...
- вид для локального отображения публикуемого потока
Code Block | ||||
---|---|---|---|---|
| ||||
- (void)publishButton:(UIButton *)button { [self changeViewState:button enabled:NO]; if ([button.titleLabel.text isEqualToString:@"STOP"]) { [room unpublish]; } else { publishStream = [room publish:_localDisplay]; [publishStream on:kFPWCSStreamStatusPublishing callback:^(FPWCSApi2Stream *rStream){ [self changeViewState:_publishButton enabled:YES]; ]; [self changeLocalStatus:rStream]; [_publishButton setTitle:@"STOP" forState:UIControlStateNormal]; [self changeViewState:_muteAudio enabled:YES]; [self changeViewState:_muteVideo enabled:YES]; }]; [publishStream on:kFPWCSStreamStatusUnpublished callback:^(FPWCSApi2Stream *rStream){ [self onUnpublished]; [self changeLocalStatus:rStream]; }]; }]; [publishStream on:kFPWCSStreamStatusFailed callback:^(FPWCSApi2Stream *rStream){ [self onUnpublished]; [self changeLocalStatus:rStream]; }]; } } |
6. Получение от сервера события, сигнализирующего о присоединении к конференции другого участника
FPWCSApi2Room kFPWCSRoomParticipantEventJoined participantCallback код
Code Block | ||||
---|---|---|---|---|
| ||||
[room on:kFPWCSRoomParticipantEventJoined participantCallback:^(FPWCSApi2Room *room, FPWCSApi2RoomParticipant *participant) { ParticipantView *pv = [freeViews pop]; ; if (pv) { pv.login.text = [participant getName]; _messageHistory.text = [NSString stringWithFormat:@"%@\n%@ - %@", _messageHistory.text, participant.getName, @"joined"]; [busyViews setValue:pv forKey:[participant getName]]; } }]; |
7. Получение от сервера события, сигнализирующего о публикации видеопотока другим участником, и воспроизведение видеопотока.
FPWCSApi2Room kFPWCSRoomParticipantEventPublished participantCallback, FPWCSApi2RoomParticipant play код
Code Block | ||||
---|---|---|---|---|
| ||||
FPWCSApi2Room kFPWCSRoomParticipantEventPublished participantCallback, FPWCSApi2RoomParticipant play код [room on:kFPWCSRoomParticipantEventPublished participantCallback:^(FPWCSApi2Room *room, FPWCSApi2RoomParticipant *participant) { ParticipantView *pv = [busyViews valueForKey:[participant getName]]; if (pv) { [participant play:pv.display]; } }]; |
8. Получение от сервера события, сигнализирующего о получении сообщения от другого участника.
FPWCSApi2Room onMessageCallback код
Code Block | ||||
---|---|---|---|---|
| ||||
[room onMessageCallback:^(FPWCSApi2Room *room, FPWCSApi2RoomMessage *message) {
_messageHistory.text = [NSString stringWithFormat:@"%@\n%@ - %@", _messageHistory.text, message.from, message.text];
}]; |
...
Методу передается текст сообщения.
Code Block | ||||
---|---|---|---|---|
| ||||
- (void)sendButton:(UIButton *)button { for (NSString *name in [room getParticipants]) { FPWCSApi2RoomParticipant *participant = [room getParticipants][name]; [participant sendMessage:_messageBody.text]; } _messageHistory.text = [NSString stringWithFormat:@"%@\n%@ - %@", _messageHistory.text, _connectLogin.input.text, _messageBody.text]; _messageBody.text = @""; } |
...
FPWCSApi2Stream unmuteAudio, muteAudio, unmuteVideo, muteVideo код
Code Block | ||||
---|---|---|---|---|
| ||||
- (void)muteAudioChanged:(id)sender { if (publishStream) { if (_muteAudio.control.isOn) { [publishStream muteAudio]; } else { [publishStream unmuteAudio]; } } } - (void)muteVideoChanged:(id)sender { if (publishStream) { if (_muteVideo.control.isOn) { [publishStream { [publishStream muteVideo]; } else { muteVideo]; } else { [publishStream unmuteVideo]; } } } |
11. Остановка публикации видеопотока. (код)
FPWCSApi2Room unpublish
Code Block | ||||
---|---|---|---|---|
| ||||
- (void)publishButton:(UIButton *)button { [self changeViewState:button enabled:NO]; if ([button.titleLabel.text isEqualToString:@"STOP"]) { [room unpublish]; } else { else { FPWCSApi2StreamOptions * options = [[FPWCSApi2StreamOptions alloc] init]; options.record = [_record.control isOn]; publishStream = [room publish:_localDisplay withOptions:options]; [publishStream on:kFPWCSStreamStatusPublishing callback:^(FPWCSApi2Stream *rStream){ [self changeViewState:_publishButton enabled:YES]; _publishButton enabled:YES]; [self changeLocalStatus:rStream]; [_publishButton setTitle:@"STOP" forState:UIControlStateNormal]; [self changeViewState:_muteAudio enabled:YES]; [self changeViewState:_muteVideo enabled:YES]; [self changeViewState:_record enabled:NO]; }]; [publishStream on:kFPWCSStreamStatusUnpublished callback:^(FPWCSApi2Stream *rStream){ [self onUnpublished]; [self changeLocalStatus:rStream]; ]; }]; [publishStream on:kFPWCSStreamStatusFailed callback:^(FPWCSApi2Stream *rStream){ [self onUnpublished]; [self changeLocalStatus:rStream]; ; }]; } } |
12. Выход из комнаты конференции.
...
Методу передается хэндлер для обработки ответа REST-приложения WCS-сервера.
Code Block | ||||
---|---|---|---|---|
| ||||
if ([button.titleLabel.text isEqualToString:@"LEAVE"]) { if (room) { FPWCSApi2DataHandler *handler = [[FPWCSApi2DataHandler alloc] init]; handler.onAccepted = ^(FPWCSApi2Session *session, FPWCSApi2Data *data){ [self onUnpublished]; [self onLeaved]; }; handler.onRejected = ^(FPWCSApi2Session *session, FPWCSApi2Data *data){ [self onUnpublished]; [self onLeaved]; }; }; [room leave:handler]; room = nil; } } |
13. Закрытие соединения.
FPWCSApi2RoomManager disconnect код
Code Block | ||||
---|---|---|---|---|
| ||||
- (void)connectButton:(UIButton *)button { [self changeViewState:button enabled:NO]; if ([button.titleLabel.text isEqualToString:@"DISCONNECT"]) { if (roomManager) { ) { if (roomManager) { [roomManager disconnect]; } } else { //todo check url is not empty [self changeViewState:_connectUrl enabled:NO]; [self changeViewState:_connectLogin.input enabled:NO]; [self connect]; } } |