...
Поддерживаемые платформы и браузеры
Chrome | Firefox | Safari 11 | Chromium Edge | ||
---|---|---|---|---|---|
Windows | + | + | + | ||
Mac OS | + | + | + | ||
Android | + | + | + | ||
iOS | - | -+ (iOS 14.6+) | + (iOS 14.6+) | + |
Поддерживаемые кодеки
- Видео: H.264, VP8
- Аудио: Opus, G.711
...
Ниже описана последовательность вызовов при использовании примера Conference
1. Установка участником 1 соединения с сервером.
FlashphonerRoomApi.roomApi.connect(); code
Code Block | ||||
---|---|---|---|---|
| ||||
connection = FlashphonerRoomApi.roomApi.connect({urlServer: url, username: username}).on(SESSION_STATUS.FAILED, function(session){ setStatus('#status', session.status()); onLeft(); }).on(SESSION_STATUS.DISCONNECTED, function(session) { setStatus('#status', session.status()); onLeft(); }).on(SESSION_STATUS.ESTABLISHED, function(session) { setStatus('#status', session.status()); joinRoom(); }); |
...
ConnectionStatusEvent ESTABLISHED code
Code Block | ||||
---|---|---|---|---|
| ||||
connection = FlashphonerRoomApi.roomApi.connect({urlServer: url, username: username}).on(SESSION_STATUS.FAILED, function(session){ ... }).on(SESSION_STATUS.DISCONNECTED, function(session) { ... }).on(SESSION_STATUS.ESTABLISHED, function(session) { setStatus('#status', session.status()); joinRoom(); }); |
...
3. Вход в чат-комнату участника 1.
connection.join(); code
Code Block | ||||
---|---|---|---|---|
| ||||
connection.join({name: getRoomName()}).on(ROOM_EVENT.STATE, function(room){ ... }); |
...
4. Получение участником 1 от сервера события, описывающего состояние комнаты.
RoomStatusEvent STATE STATE code
Code Block | ||||
---|---|---|---|---|
| ||||
connection.join({name: getRoomName()}).on(ROOM_EVENT.STATE, function(room){ var participants = room.getParticipants(); console.log("Current number of participants in the room: " + participants.length); if (participants.length >= _participants) { console.warn("Current room is full"); $("#failedInfo").text("Current room is full."); room.leave().then(onLeft, onLeft); return false; } setInviteAddress(room.name()); if (participants.length > 0) { var chatState = "participants: "; for (var i = 0; i < participants.length; i++) { installParticipant(participants[i]); chatState += participants[i].name(); if (i != participants.length - 1) { chatState += ","; } } addMessage("chat", chatState); } else { addMessage("chat", " room is empty"); } publishLocalMedia(room); onJoined(room); ... }); |
...
5. Публикация медиапотока участником 1.
room.publish(); code
Code Block | ||||
---|---|---|---|---|
| ||||
room.publish({ display: display, constraints: constraints, record: false, receiveVideo: false, receiveAudio: false ... }); |
...
StreamStatusEvent PUBLISHING code
Code Block | ||||
---|---|---|---|---|
| ||||
room.publish({ display: display, constraints: constraints, record: false, receiveVideo: false, receiveAudio: false }).on(STREAM_STATUS.FAILED, function (stream) { ... }).on(STREAM_STATUS.PUBLISHING, function (stream) { setStatus("#localStatus", stream.status()); onMediaPublished(stream); }).on(STREAM_STATUS.UNPUBLISHED, function(stream) { ... }); |
...
12. Получение участником 1 от сервера события о присоединении участника 2.
RoomStatusEvent JOINED code
Code Block | ||||
---|---|---|---|---|
| ||||
connection.join({name: getRoomName()}).on(ROOM_EVENT.STATE, function(room){ ... }).on(ROOM_EVENT.JOINED, function(participant){ installParticipant(participant); addMessage(participant.name(), "joined"); }).on(ROOM_EVENT.LEFT, function(participant){ ... }).on(ROOM_EVENT.PUBLISHED, function(participant){ ... }).on(ROOM_EVENT.FAILED, function(room, info){ ... }).on(ROOM_EVENT.MESSAGE, function(message){ ... }); |
...
15. Получение участником 2 от сервера события, подтверждающегог подтверждающего успешную публикацию потока.
...
17. Выход участника 1 из чат-комнаты.
room.leave(); code
Code Block | ||||
---|---|---|---|---|
| ||||
function onJoined(room) { $("#joinBtn").text("Leave").off('click').click(function(){ $(this).prop('disabled', true); room.leave().then(onLeft, onLeft); }).prop('disabled', false); ... } |
...
18. Получение участниками комнаты от сервера события о выходе участника 1.
RoomStatusEvent LEFT code
Code Block | ||||
---|---|---|---|---|
| ||||
connection.join({name: getRoomName()}).on(ROOM_EVENT.STATE, function(room){ ... }).on(ROOM_EVENT.JOINED, function(participant){ ... }).on(ROOM_EVENT.LEFT, function(participant){ //remove participant removeParticipant(participant); addMessage(participant.name(), "left"); }).on(ROOM_EVENT.PUBLISHED, function(participant){ ... }).on(ROOM_EVENT.FAILED, function(room, info){ ... }).on(ROOM_EVENT.MESSAGE, function(message){ ... }); |
...
В этом случае все потоки в комнате будут записаны в один файл. При выходе последнего участника из завершении комнаты запись также будет завершена, и автоматически запустится скрипт, указанный в настройке
...
8. Микширование может занять продолжительное время. в зависимости от длительности записи, производительности процессора и жесткого диска сервера. По его окончании, загрузите файл из каталога /usr/local/FlashphonerWebCallServer/records или откройте в браузере по ссылке
Известные проблемы
...
Завершение комнаты
Комната существует на сервере до тех пор, пока в ней есть хотя бы один участник. Когда последний участник вызывает функцию room.leave(), комната завершается.
Если последний участник обновляет страницу или теряет соединение с сервером без вызова функции room.leave(), комната остается активной в течение времени, заданного настройкой в миллисекундах
Code Block | ||
---|---|---|
| ||
room_idle_timeout=60000 |
По умолчанию, время составляет 60 секунд. По истечении этого времени, комната завершается.
Известные проблемы
1. При обмене текстовыми сообщениями необходимо кодирование не-латинских символов
...
Code Block | ||||
---|---|---|---|---|
| ||||
addMessage(participant.name(), var participants = room.getParticipants(); for (var i = 0; i < participants.length; i++) { participants[i].sendMessage(encodeURIComponent(message)); } |
и decodeURIComponent() при его получении
Code Block | ||||
---|---|---|---|---|
| ||||
.... }).on(ROOM_EVENT.MESSAGE, function(message){ }).on(ROOM_EVENT.MESSAGE, function(message){addMessage(message.from.name(), decodeURIComponent(message.text)); }); addMessage(message.from.name(), decodeURIComponent(message.text)); }); ...... |
2. При быстром вызове connection.join() и затем room.leave() возможна отправка серверу команды join, в то время как сервер еще не обработал предыдущую команду leave для этого пользователя
Симптомы: при вызове connection.join() сразу после room.leave() клиент получает сообщение
Code Block | ||
---|---|---|
| ||
Room already has user with such login |
Решение: использовать интервал не менее 1 секунды между последовательными вызовами room.leave() и connection.join()