Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Пример iOS-приложения для видеочата

Работа с кодом примера

Для разбора кода возьмем версию примера Video Chat, которая доступена доступна для скачивания в сборке 2.5.2.

...

1. Импорт API. код

Code Block
languagebashcpp
themeRDark
#import <FPWCSApi2/FPWCSApi2.h>

...

  • URL WCS-сервера
  • имя пользователя чат-комнаты
Code Block
languagebashcpp
themeRDark
- (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];
                                   }];
        
        [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. Присоединение к конференции.

FPWCSApi2RoomManager join код

Методу передаются параметры:

  • имя чат-комнаты
Code Block
languagebash
themeRDark
FPWCSApi2RoomOptions * options = [[FPWCSApi2RoomOptions alloc] init];
options.name = _joinRoomName.input.text;
room = [roomManager join:options];

...

FPWCSApi2Room onStateCallback код

При получении данного события количество и состав других участников определяется с помощью метода FPWCSApi2Room getParticipants. Если количество участников более 2, текущий участник выходит из комнаты.

Если текущий участник остается в комнате, запускается проигрывание потока от других участников при помощи метода FPWCSApi2RoomParticipant play

Code Block
languagebash
themeRDark
[room onStateCallback:^(FPWCSApi2Room *room) {
    NSDictionary *participants = [room getParticipants];
    if ([participants count] >= 2) {
        [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. Публикация видеопотока.

FPWCSApi2Room publish код

Методу передаются параметры:

  • вид для локального отображения публикуемого потока
  • record определяет, необходимо ли записывать виедопоток при публикации
Code Block
languagebash
themeRDark
- (void)publishButton:(UIButton *)button {
    [self changeViewState:button enabled:NO];
    if ([button.titleLabel.text isEqualToString:@"STOP"]) {
        [room unpublish];
    } 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];
            [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){
    ...
}


3. Присоединение к конференции.

FPWCSApi2RoomManager join код

Методу передаются параметры:

  • имя чат-комнаты
Code Block
languagecpp
themeRDark
FPWCSApi2RoomOptions * options = [[FPWCSApi2RoomOptions alloc] init];
options.name = _joinRoomName.input.text;
room = [roomManager join:options];



4. Получение от сервера события, подтверждающего успешное присоединение к конференции

FPWCSApi2Room onStateCallback код

При получении данного события количество и состав других участников определяется с помощью метода FPWCSApi2Room getParticipants. Если количество участников более 2, текущий участник выходит из комнаты.

Если текущий участник остается в комнате, запускается проигрывание потока от других участников при помощи метода FPWCSApi2RoomParticipant play

Code Block
languagecpp
themeRDark
[room onStateCallback:^(FPWCSApi2Room *room) {
    NSDictionary *participants = [room getParticipants];
    if ([participants count] >= 2) {
        [selfroom onUnpublishedleave:nil];
        _joinStatus.text =   [self changeLocalStatus:rStream]@"Room is full";
    
    [self    }];

    }
}

6. Получение от сервера события, сигнализирующего о присоединении к конференции другого участника

FPWCSApi2Room kFPWCSRoomParticipantEventJoined participantCallback код

Code Block
languagebash
themeRDark
[room on:kFPWCSRoomParticipantEventJoined participantCallback:^(FPWCSApi2Room *room, FPWCSApi2RoomParticipant *participant) {
changeViewState:_joinButton enabled:YES];
        return;
      ParticipantView *pv = [freeViews pop];
    if (pv) {
    }
    NSString *chatState  pv.login.text = [participant getName]= @"participants: ";
    for (NSString* key  _messageHistory.text = [NSString stringWithFormat:@"%@\n%@ - %@", _messageHistory.text, participant.getName, @"joined"in participants) {
        FPWCSApi2RoomParticipant *participant = [participants valueForKey:key];
        [busyViewsParticipantView setValue:*pv = forKey:[participantfreeViews getNamepop]];
    }
}];

7. Получение от сервера события, сигнализирующего о публикации видеопотока другим участником, и воспроизведение видеопотока.

FPWCSApi2Room kFPWCSRoomParticipantEventPublished participantCallback, FPWCSApi2RoomParticipant play код

Code Block
languagebash
themeRDark
[room on:kFPWCSRoomParticipantEventPublished participantCallback:^(FPWCSApi2Room *room, FPWCSApi2RoomParticipant *participant) {
    ParticipantView *pv = [busyViews valueForKey:[participant getName]
        [busyViews setValue:pv forKey:[participant getName]];
        [participant play:pv.display];
        pv.login.text = [participant getName];
    if (pv) {
  chatState = [NSString stringWithFormat:@"%@%@, ", chatState, [participant play:pv.displaygetName]];
    }
    ...
}];

...

;



5. Публикация видеопотока.

FPWCSApi2Room onMessageCallback publish код

Методу передаются параметры:

  • вид для локального отображения публикуемого потока
  • record определяет, необходимо ли записывать виедопоток при публикации
Code Block
languagebashcpp
themeRDark
[room onMessageCallback:^(FPWCSApi2Room *room, FPWCSApi2RoomMessage *message)- (void)publishButton:(UIButton *)button {
    _messageHistory.text = [NSString stringWithFormat:@"%@\n%@ - %@", _messageHistory.text, message.from, message.text];
}];

9. Отправка текстового сообщения.

FPWCSApi2RoomParticipant sendMessage код

Методу передается текст сообщения.

Code Block
languagebash
themeRDark
- (void)sendButton:(UIButton *)button {
    for (NSString *name in [room getParticipants]) {[self changeViewState:button enabled:NO];
    if ([button.titleLabel.text isEqualToString:@"STOP"]) {
        [room unpublish];
    } else {
        FPWCSApi2StreamOptions * options = [[FPWCSApi2StreamOptions alloc] init];
        FPWCSApi2RoomParticipant *participantoptions.record = [room getParticipants][name_record.control isOn];
        publishStream = [participantroom sendMessagepublish:_messageBody.textlocalDisplay withOptions:options];
    }
    _messageHistory.text = [NSString stringWithFormat:@"%@\n%@ - %@", _messageHistory.text, _connectLogin.input.text, _messageBody.text];
    _messageBody.text = @"";}
}

10. Включение/выключение аудио и видео для публикуемого потока.


FPWCSApi2Stream unmuteAudio, muteAudio, unmuteVideo, muteVideo 6. Получение от сервера события, сигнализирующего о присоединении к конференции другого участника

FPWCSApi2Room kFPWCSRoomParticipantEventJoined participantCallback код

Code Block
languagebashcpp
themeRDark
- (void)muteAudioChanged:(id)sender[room on:kFPWCSRoomParticipantEventJoined participantCallback:^(FPWCSApi2Room *room, FPWCSApi2RoomParticipant *participant) {
    if (publishStream) {
    ParticipantView *pv = [freeViews pop];
    if (_muteAudio.control.isOnpv) {
        pv.login.text  =  [publishStreamparticipant muteAudiogetName];
        } else {
            [publishStream unmuteAudio_messageHistory.text = [NSString stringWithFormat:@"%@\n%@ - %@", _messageHistory.text, participant.getName, @"joined"];
        }
    }
}

- (void)muteVideoChanged:(id)sender {[busyViews setValue:pv forKey:[participant getName]];
    if (publishStream) {
        if (_muteVideo.control.isOn}
}];


7. Получение от сервера события, сигнализирующего о публикации видеопотока другим участником, и воспроизведение видеопотока.

FPWCSApi2Room kFPWCSRoomParticipantEventPublished participantCallback, FPWCSApi2RoomParticipant play код

Code Block
languagecpp
themeRDark
[room on:kFPWCSRoomParticipantEventPublished participantCallback:^(FPWCSApi2Room *room, FPWCSApi2RoomParticipant *participant) {
    ParticipantView *pv =      [publishStream muteVideo[busyViews valueForKey:[participant getName]];
    if (pv) {
   } else {
   [participant play:pv.display];
    }
}];


8. Получение от сервера события, сигнализирующего о получении сообщения от другого участника.

FPWCSApi2Room onMessageCallback код

Code Block
languagecpp
themeRDark
[room onMessageCallback:^(FPWCSApi2Room *room, FPWCSApi2RoomMessage [publishStream unmuteVideo];*message) {
    _messageHistory.text = [NSString  }
    }
}

11. Остановка публикации видеопотока. (код)

...

stringWithFormat:@"%@\n%@ - %@", _messageHistory.text, message.from, message.text];
}];


9. Отправка текстового сообщения.

FPWCSApi2RoomParticipant sendMessage код

Методу передается текст сообщения.

Code Block
languagebashcpp
themeRDark
- (void)publishButtonsendButton:(UIButton *)button {
    [self changeViewState:button enabled:NO];
    if ([button.titleLabel.text isEqualToString:@"STOP"]))button {
    for (NSString *name in [room unpublishgetParticipants];
    } else ) {
        FPWCSApi2StreamOptionsFPWCSApi2RoomParticipant * optionsparticipant = [[FPWCSApi2StreamOptions alloc] init];
        options.record = [_record.control isOnroom getParticipants][name];
        publishStream = [roomparticipant publishsendMessage:_localDisplay withOptions:optionsmessageBody.text];
    }
    _messageHistory.text = [publishStreamNSString on:kFPWCSStreamStatusPublishing callback:^(FPWCSApi2Stream *rStream){stringWithFormat:@"%@\n%@ - %@", _messageHistory.text, _connectLogin.input.text, _messageBody.text];
    _messageBody.text        [self changeViewState:_publishButton enabled:YES];= @"";
}


10. Включение/выключение аудио и видео для публикуемого потока.

FPWCSApi2Stream unmuteAudio, muteAudio, unmuteVideo, muteVideo код

Code Block
languagecpp
themeRDark
- (void)muteAudioChanged:(id)sender {
    if        [self changeLocalStatus:rStream];(publishStream) {
        if    [_publishButton setTitle:@"STOP" forState:UIControlStateNormal];(_muteAudio.control.isOn) {
            [selfpublishStream changeViewState:_muteAudio enabled:YES];
        }    [self changeViewState:_muteVideo enabled:YES];else {
            [self changeViewState:_record enabled:NOpublishStream unmuteAudio];
        }
    }
}];

- (void)muteVideoChanged:(id)sender {
    if (publishStream) {
        [publishStream on:kFPWCSStreamStatusUnpublished callback:^(FPWCSApi2Stream *rStream)if (_muteVideo.control.isOn) {
            [selfpublishStream onUnpublishedmuteVideo];
        }    [self changeLocalStatus:rStream];else {
        }];
    [publishStream unmuteVideo];
   
     }
   [publishStream on:kFPWCSStreamStatusFailed callback:^(FPWCSApi2Stream *rStream) }
}


11. Остановка публикации видеопотока. (код)

FPWCSApi2Room unpublish

Code Block
languagecpp
themeRDark
- (void)publishButton:(UIButton *)button {
    [self changeViewState:button enabled:NO];
    if  [self onUnpublished];
    ([button.titleLabel.text isEqualToString:@"STOP"]) {
        [selfroom changeLocalStatus:rStreamunpublish];
    } else {
        }];

...
    }
}


12. Выход из комнаты конференции.

...

Методу передается хэндлер для обработки ответа REST-приложения WCS-сервера.

Code Block
languagebashcpp
themeRDark
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;
    }
}

...

FPWCSApi2RoomManager disconnect код

Code Block
languagebashcpp
themeRDark
- (void)connectButton:(UIButton *)button {
    [self changeViewState:button enabled:NO];
    if ([button.titleLabel.text isEqualToString:@"DISCONNECT"]) {
        if (roomManager) {
            [roomManager disconnect];
        }
    } else]) {
         //todo check url is not empty
if (roomManager) {
            [self changeViewState:_connectUrl enabled:NOroomManager disconnect];
        [self changeViewState:_connectLogin.input enabled:NO];}
        [self connect];...
    }
}