Скриншаринг (screen sharing — демонстрация экрана при видеозвонке) — уже практически базовая функция платформ для видеозвонков. Skype, WhatsApp, Telegram, Teams, Google Meet — внутри всех этих систем есть эта фича.
Мы уже рассказывали, как реализовать скриншаринг в мобильном iOS-приложении. В этой статье объясним, как сделать это на Android. С примерами кода.
Также в других статьях нашего Android-цикла узнаете, как сделать кастомное уведомление о звонке и в целом, как мы разрабатываем WebRTC-системы для звонков.
Реализация скриншаринга
Скриншаринг можно включить сразу же при создании нового видеозвонка — заранее, фактически до того, как он начался.
Однако мы рассмотрим наиболее часто встречающуюся ситуацию — включение скриншаринга во время видеозвонка — через N секунд после его начала.
Для упрощения описания реализации скриншаринга допустим, что у нас уже есть готовое приложение с WebRTC звонками. Читайте про реализацию видеозвонка WebRTC подробнее.
Шаги реализации:
- Получение доступа к содержимому экрана
- Создание видеотрека с изображением с экрана
- Замена видеотрека с камеры видеотреком с экрана
- Отображение уведомления о происходящем скриншаринге
Теперь каждый в деталях:
Получение доступа к содержимому экрана
Сначала получим возможность захватывать содержимое экрана и звук устройства с помощью Media Projection API:
При вызове screenSharingPermission Launcher.launch(intent) отобразится диалог, который расскажет пользователю о том, что media projection получит доступ ко всей отображаемой на экране информации.
В результате успешного получения доступа к содержимому экрана мы получим screenSharingIntent.
Создание видеотрека с изображением с экрана
Создадим videoCapturer, который будет захватывать изображение с экрана:
Далее создадим localVideoTrack:
Замена видеотрека с камеры видеотреком с экрана
Для корректной замены видеотрека реализуем логику renegotiation у обоих участников звонка. При изменении локальных медиа треков WebRTC вызывает метод onRenegotiationNeeded. В нем повторяем процесс обмена sdp:
Приступим к замене видеотрека. Удалим из локального медиа потока видеотрек с камеры:
Остановим захват видео с камеры:
Добавим видеотрек скриншаринга:
Отображение уведомления о происходящем скриншаринге
При старте скриншаринга необходимо запускать Foreground Service c уведомлением о скриншаринге.
Создадим ScreencastService и добавим его в AndroidManifest.xml. Также укажем параметр foregroundServiceType:
Перед заменой видеотрека с камеры на видеотрек скриншаринга запустим ScreencastService:
Далее в ScreencastService, например в onStartCommand(), нужно вызвать метод startForeground:
Частые проблемы во время реализации
Приложение крашится на устройствах с Android 10+ с ошибкой “Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION”
Эта ошибка возникает, когда скриншаринг запускается без Foreground Service. Начиная с Android 10 система требует, чтобы во время скриншаринга был запущен Foreground Service c “android:foregroundServiceType="mediaProjection”.
Foreground Service гарантирует, что система не “убьет” приложение во время скриншаринга. Уведомление Foreground Service будет сообщать пользователю о текущем скриншаринге и даст возможность быстро вернуться в приложение.
Как решить: не забыть отобразить уведомление о начатом скриншаринге :)
Не происходит замена видеотрека с камеры видеотреком с экрана
Проблема замены видеотрека может быть связана с тем, что на стороне одного (или обоих) участников видеозвонка не реализована (или реализована некорректно) логика renegotiation.
Как решить: переопределить метод onRenegotiationNeeded в PeerConnection.Observer (название метода на других платформах может отличаться). При вызове onRenegotiationNeeded должен запускаться процесс обмена sdp.
Заключение
В этой статье мы рассмотрели реализацию скриншаринга в видеозвонке:
- Получили доступ к содержимому экрана с помощью MediaProjection API
- Захватили содержимое экрана с помощью ScreenCapturerAndroid
- Создали локальный видеотрек с изображением с экрана
- Заменили видеотрек с камеры на видеотрек скриншаринга
- Реализовали Foreground Service для отображения уведомления о скриншаринге
Посмотреть на готовую реализацию скриншаринга можно в нашем приложении.
Комментарии