Реализация переключения webcam <-> screen sharing - web sdk

Здравствуйте!

Есть потребность в реализации стриминга с функцией переключения туда-сюда с демонстрации экрана на показ потока вебкамеры и обратно(вебинарная комната). Нет необходимости одновременно транслировать и экран и камеру(т.е. только по очереди).

Как вы рекомендовали бы решить эту задачу используя web sdk?

Наши текущие варианты и проблемы

С Микшером:

Реализация:

1. Запускается стриминг(камера или экран) по publishing переходим к п.2.
2. Создаётся микшер
3. Добавляется стрим из п.1 к микшеру
4. При необходимости переключить источник(экран-вебкамера) останавливается стрим из п.1. и по unpublish запускается новый стрим с новым источником
5. Добавляется этот новый стрим из п.4 по событию publishing к микшеру.

У нас этот вариант столкнулся со следующими препятствиями

1. Значительное потребление ресурсов процессора при реализации с помощью микшера(фактически один стрим одно ядро на 100% забирает).
2. Большое время когда первый стрим уже выключен, а второй ещё не транслируется. Т.е. клиент видит несколько секунд черный экран и звука соответственно тоже нет

Реализация без микшера:
1. Запускается стриминг(камера или экран).
2. При необходимости переключить источник(экран-вебкамера) останавливается стрим из п.1. по unpublish запускается новый стрим с новым источником

У нас этот вариант столкнулся со следующими препятствиями:
1. Обрыв трансляции у клиента и необходимость либо совершать действие вручную смотрящим(на safari IO нельзя использовать autoplay(описывал эту проблему раньше)) либо каким-то образом модифицировать плеер(описано ниже)
2. Так же как и в случае с микшером большие задержки между концом прошлого потока и воспроизведением нового

Действия на клиенте(плеер)
Модифицировали embed_player(используем с autoplay=true), добавив возможность автоматического переподключения: запуск
функции start() при событиях
STREAM_STATUS.STOPPED и STREAM_STATUS.FAILED(приводит кстати к тому, что на сервере появляются много соединений типа pending от одного и того же клиента)
Сначала пробовал как можно быстрее коннектится при этих событиях обратно, однако браузер набирал очень быстро порядка нескольких сот попыток и блокировал дальнейшие попытки коннектится с ошибкой типа слишком много соединений...

Пришлось ограничить кол-во попыток и распределить их по времени, т.е. делать запуск start() раз в несколько секунд с всё возрастающим интервалом при очередном FAILED.

--------------------------

Нам бы хотелось реализовать возможность бесшовного переключения видеоисточников(экран-вебкамера) хотябы в плане звука, т.е. чтобы звук не пропадал

Либо максимально уменьшить этот промежуток для смотрящего

По возможности без использования мишкера(требует много ресурсов)

Подскажите варианты

----------------------

Спасибо!
 

Max

Administrator
Staff member
Добрый день.
Вы можете воспользоваться RoomApi:
1. Создать комнату
2. Опубликовать поток с веб камеры и поток с экрана
3. Пользователи подключаются к данной комнате и смотрят трансляцию.
Основной недостаток этого способа - каждому пользователю от публикатора уходит по два потока. Если пользователю в Вашем сценарии нужно что-то публиковать, то добавляется еще как минимум один поток. Это приводит к большой нагрузке на канал и, соответственно, повышает требования к каналу, а также требует оптимизаций, которые при большом количестве зрителей могут и не дать эффекта.
Но при этом оба потока - с веб камеры и с экрана - могут присутствовать на экране пользователя как одновременно, так и по отдельности.
 

Max

Administrator
Staff member
Уточнение.
Чтобы нормально реализовать такую функцию нужна доработка Web SDK.
Добавили внутреннюю задачу WCS-1477. Сообщим когда по ней будут продвижения.

Все остальные решения так или иначе будут занимать время на переключении. В том числе Room API.

Можно было бы использовать два отдельных стрима: 1) десктоп 2) камера, далее делать stream.mute() для десктопа и вещать только камеру, а при переключении наоборот. Mute позволил бы сэкономить трафик. Однако в этом случае скорее всего будет проблема с отображением двух стримов в iOS Safari, т.к. в наших тестах два стрима с видео не могли одновременно играть в iOS Safari. Это ограничение самого браузера и системы iOS.

Поэтому варианты следующие:
С поддержкой iOS Safari
1. Микшер
2. Доработка Web SDK.
Без поддержки iOS Safari
1. Публикация двух стримов и mute / unmute
 
Last edited:
Спасибо большое.
Поддержка iOS Safari важна. Поэтому это вариант для нас отпадает.
Микшер на данном этапе чрезмерно проворен по ресурсам и обеспечить его железом будет дорого для планового кол-ва трансляций.

Поэтому доработка web sdk будет самым лучшим решением в нашей задаче.

Кроме переключения скрин-вебкамера так же есть потребность в переключении вебкамера1-вебкамера2, которая будет использоваться при трансляции с мобильных устройства с фронтальной и задней камерой.

Есть ли ориентировочные сроки по реализации задачи WCS-1477?

Руководство у меня стремится понять куда бежать и по факту для уже грядущего старта сервиса оч. важна эта функция с переключением. Ожидаем порядка 1500 пользователей системы в первый год и заинтересованы в сотрудничестве.
 

Max

Administrator
Staff member
Добрый день.
Переключение между камерами уже реализовано.
Документация здесь.
Переключение с скрина на камеру проверим, возможно доработка SDK и не понадобится. По результатам отпишем.
По каким-либо срокам сориентировать не можем, т.к. не знаем когда именно эта задача получит приоритет над другими.
Если важны сроки для конкретных задач, можете обратиться на sales@flashphoner.com за расширенной техподдержкой, в рамках которой возможна работа по функциям в более высоком приоритете с обозначением конкретных сроков.
 

Max

Administrator
Staff member
Добрый день.
В данной сборке WebSDK появилась возможность переключения между потоками с экрана и веб-камеры во время трансляции. Документация здесь. пример Media Devices в архиве сборки или на GitHub.
Ограничения:
1. Работает только в Chrome или Firefox
2. Если переключились на трансляцию экрана, переключение на другую камеру в потоке с камеры будет недоступно.
 
Начали тестирование со своего сайта следуя упомянутой вами инструкции. Спасибо за модификацию.

Переключение работает как ожидалось(бесшовно в обоих направлениях)

Но обнаружилась проблема на chrome(win10. Версия 69.0.3497.100 (Официальная сборка), (64 бит)): перестала запускаться трансляция в варианте, когда весь поток начинается с трансляции экрана. Т.е. когда при начальном запуске стрима мы стремимся первыми кадрами показать экран, но не камеру - выпадают в консоль следующие предупреждения и трансляция экрана не идёт:


Code:
21:06:46 INFO webrtc -  {video: {…}, audio: {…}, sourceId: "DDfwVqEsdpsl6Rb08C87oA=="}audio: {deviceId: "default"}sourceId: "DDfwVqEsdpsl6Rb08C87oA=="video: {mandatory: {…}}mandatory: {maxWidth: 1304, maxHeight: 768, maxFrameRate: undefined, chromeMediaSource: "desktop", chromeMediaSourceId: "DDfwVqEsdpsl6Rb08C87oA=="}__proto__: Object__proto__: Object
flashphoner.js:10486 

21:06:46 WARN core -  DOMException: Error starting screen capture
warn @ flashphoner.js:10486
(anonymous) @ flashphoner.js:8981
Promise.catch (async)
publish @ flashphoner.js:8980
startStreaming @ flashphoner.module.js:429
(anonymous) @ flashphoner.module.js:171
onSessionStatusChange @ flashphoner.js:7987
wsConnection.onmessage @ flashphoner.js:7869
flashphoner.module.js:422 

FAILED stream status
Стремился воспроизвести проблему на ваших примерах, но там проблема с расширением и нашим доменом. В коде вероятно прописано ваше расширение, а домен, с которого я пытаюсь делать тестирование наш. Поэтому чистоты эксперимента нет.

При чём эта проблема проявляется только с новой сборкой web sdk, когда откатываюсь на старую, то и проблема перестаёт воспроизводится.
constraints для скриншаринга:
Code:
audio:
deviceId: "default"
video:
frameRate: 30
height: 768
type: "screen"
width: 1304
На firefox ошибка не воспроизводится, т.е. работает с успехом как старый вариант sdk, так и новый.

В чём может быть дело?
 

Max

Administrator
Staff member
Добрый день.
На последней сборке сервера 5.1.3575 (включает более свежую сборку WebSDK с диагностикой отключения транскодинга и другими фиксами) нам пока не удается воспроизвести проблему. Что делали:
1. В исходном тексте примера Media Devices, в обработчике события STREAM_STATUS.PUBLISHING прописали вызов функции switchToScreen()
Code:
   }).on(STREAM_STATUS.PUBLISHING, function (publishStream) {
        publishStream.switchToScreen($('#mediaSource').val());
        ...
   });
2. Выставили FPS 30, разрешение 1304 на 768, камера и микрофон по умолчанию.
3. При публикации потока появляется диалоговое окно расширения для скриншаринга, выбираем окно, разрешаем шаринг. Публикуется поток с выбранного окна.
При этом в начале, до момента, когда мы подтвердили скриншаринг, будет идти поток с камеры, но зрители не успевают к нему подключиться.
Если пытаться переключиться на поток с экрана в обработчике события STREAM_STATUS.PENDING, переключение не сработает, т.к. поток еще не опубликован.
Также не будет работать вызов stream.switchToCam(), если ранее не была вызвана функция stream.switchToStream().
В коде вероятно прописано ваше расширение, а домен, с которого я пытаюсь делать тестирование наш.
В коде прммеров нигде не прописан наш домен. Домен прописывается только в расширении, соответственно, если в Вашем браузере установлено расширение, адаптированное под Ваш домен, то все примеры будут работать с Вашим доменом. Идентификатор расширения необходимо указать в коде примера, передав его в функцию Flashphoner.init()
Code:
        Flashphoner.init({
            screenSharingExtensionId: extensionId,
            flashMediaProviderSwfLocation: '../../../../media-provider.swf',
            ...
       })
Попробуйте обновиться до последней сборки и повторить опыт с учетом вышеописанных нюансов.
 

Max

Administrator
Staff member
Если ошибка продолжает появляться, просим модифицировать код какого-либо из наших примеров (Media Devices или Screen Sharing) так, чтобы ошибка воспроизводилась, и прислать на support@flashphoner.com, наши специалисты будут разбираться.
 
Обновился.

До поста с описанием использования события (on(STREAM_STATUS.PUBLISHING)Я использовал другой метод - пытался запустить сначала screensharing, а потом переключаться используя switchCam. Но, как вы описали выше - так не будет работать и не работало.

Сделал по вашей инструкции - получается начать трансляцию с экрана, хоть пользователи и не успевают его увидеть, но в запись всё равно это время до выбора экрана попадает с изображением из камеры. Но на данном этапе для нас это не сильно принципиально.

Спасибо!
 
Есть ли возможность менять разрешение(ширина, высота) трансляции при таком бесшовном переключении с камеры на экран? Т.е. указывать явно какое разрешение использовать для экрана, а какое для камеры? Или получается оно может быть только одним, которое указано при запуске потока для камеры?
 

Max

Administrator
Staff member
Добрый день.
Разрешение задается для потока. Когда происходит переключение с камеры на экран, поток остается прежним, меняется только источник медиаданных. Поэтому да, разрешение может быть только одним.
 
Top