Android - демонстрация экрана с помощью Agora.io

Я пытаюсь реализовать Screen Share с помощью Agora.io на Android. Я попытался проследить за их демонстрацией, однако решение, использующее низкоуровневый графический API Android, кажется слишком сложным, поэтому я попытался использовать для этого ImageReader.

на основе своей деятельности я создаю службу (ShareScreenService, унаследованную от службы)

чтобы начать показ экрана, я делаю следующее

private void StartScreenShare(int resultCode, Intent resultData)
        {
            var mediaProjectionManager = (MediaProjectionManager)GetSystemService(MediaProjectionService);
            var mediaProjection = mediaProjectionManager.GetMediaProjection(resultCode, resultData);
            _shareScreenImageAvailableListener = new ShareScreenImageAvailableListener(this);
            var virtualDisplay = mediaProjection.CreateVirtualDisplay("sharescreen", Resources.DisplayMetrics.WidthPixels, Resources.DisplayMetrics.HeightPixels, (int)Resources.DisplayMetrics.DensityDpi, DisplayFlags.SupportsProtectedBuffers | DisplayFlags.Presentation, _shareScreenImageAvailableListener.Surface, null, _handler);
            var mediaProjectionCallback = new MediaProjectionCallback(virtualDisplay);
            mediaProjection.RegisterCallback(mediaProjectionCallback, _handler);

            AgoraVideoService.Instance.StartScreenShare();
        }

AgoraVideoService.Instance.StartScreenShare does following:

internal void StartScreenShare()
        {
            _agoraEngine.SetExternalVideoSource(true, false, true);
        }

мой ShareScreenImageAvailableListener выглядит так:

public class ShareScreenImageAvailableListener : Java.Lang.Object, ImageReader.IOnImageAvailableListener
    {
        private ScreenShareService _screenShareService;
        private ImageReader _imageReader;

        public Surface Surface
        {
            get
            {
                return _imageReader.Surface;
            }
        }

        public ShareScreenImageAvailableListener(ScreenShareService screenShareService)
        {
            _screenShareService = screenShareService;
            _imageReader = ImageReader.NewInstance(_screenShareService.Width, _screenShareService.Height, Android.Graphics.ImageFormatType.Jpeg, 1);
            _imageReader.SetOnImageAvailableListener(this, _screenShareService.Handler);
        }

        public void OnImageAvailable(ImageReader reader)
        {
            using (var image = reader.AcquireLatestImage())
            {
                using (var planes = image.GetPlanes()[0])
                {
                    using (var buffer = planes.Buffer)
                    {
                        byte[] bytes = new byte[buffer.Capacity()];
                        buffer.Get(bytes);

                        _screenShareService.ShareScreenImage(bytes, image.Height, image.Format, planes.PixelStride);
                    }
                }
                image.Close();
            }
        }
    }

затем при совместном использовании ShareScreenImage:

internal void ShareScreenImage(byte[] bytes, int height, ImageFormatType format, int pixelStride)
        {
            var agoraVideoFrame = new AgoraVideoFrame()
            {
                Buf = bytes,
                Height = height,
                Format = (int)format,
                Stride = pixelStride,
                TimeStamp = DateTime.UtcNow.Ticks,
               CropBottom = 0,
               CropLeft = 0,
               CropRight = 0,
               CropTop = 0
            };

            AgoraVideoService.Instance.ShareExternalVideoFrame(agoraVideoFrame);
        }

и, наконец, ShareExternalVideoFrame выглядит так:

_agoraEngine.PushExternalVideoFrame(agoraVideoFrame);

Наконец, мой вопрос: правильно ли я думаю о том, чтобы реализовать это? Могу ли я использовать ImageReader или мне нужно спуститься ниже, чтобы начать использовать EglCore и т. Д. Из демонстрационной реализации Agora?

Я могу проверить, что вызывается OnImageAvailable (несколько раз, пока я его не остановлю) PushExternalVideoFrame возвращает «true», что выглядит так, как будто кадры были успешно отправлены.

Однако это не дает никаких результатов, я не вижу, что экран используется совместно. Так что я бы хотя бы убедился, что это возможное решение.


person Jakub Holovsky    schedule 19.05.2020    source источник


Ответы (1)


Безопаснее использовать EglCore, потому что использование ImageReader еще не протестировано для работы с Agora. Вы можете использовать предварительные руководства и примеры приложений, чтобы получить представление о том, как использовать его с EglCore.

Вот ссылка на примеры приложений: https://github.com/AgoraIO/Advanced-Video

А вот ссылка на руководства: https://docs.agora.io/en/Video/custom_video_android?platform=Android

person Samyak    schedule 20.05.2020