OpenTok iOS SDK 2.18.1 проблема с качеством общего доступа к экрану

#ios #opentok #screensharing

#iOS #opentok #скриншот

Вопрос:

Мы используем ReplayKit для получения CMSSampleBuffers и пересылки их в OTVideoCaptureConsumer, и после изменения размера буферов ReplayKit в буфер размером 1280х720 или 1024х768 мы получаем ленту общего доступа к экрану, но она всегда становится размытой.

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

Мы проверили, что изображение, отправленное OpenTok OTVideoCaptureConsumer, является четким изображением, но результирующий поток всегда очень быстро становится размытым на стороне подписчика

Вопрос: Кто-нибудь нашел способ получить чистый канал общего доступа к экрану с помощью OpenTok iOS SDK, независимо от размера экрана устройства?

Попытки:

  • Другой способ отправки кадров:

Я пытался отправлять изображения с помощью CVPixelBuffer и OTVideoFrame. В примере, предложенном службой поддержки OpenTok, используются оба метода CVPixelBuffer для изображений с камеры и OTVideoFrame для черных изображений, когда с камеры не получено ни одного кадра. Но результирующий поток становится размытым в любом случае

  • Разные форматы и размеры:

Я не нашел никакой документации, в которой упоминались бы спецификации изображения, ожидаемого iOS SDK. Есть ли что-нибудь доступное где-нибудь, чтобы помочь нам понять, каковы поддерживаемые форматы изображений, ограничения на размер данных и поддерживаемые разрешения?

Я попытался отправить буфер ReplayKit как есть пользователю videoCaptureConsumer из нашего приложения и, например, на iPad 9.7 Pro. собственное разрешение экрана составляет 1920×1440, что, похоже, принимается iOS SDK (возвращает успех), но отображает только черный экран на стороне подписчика.

У меня просто нет другой идеи

  • Повторная передача последнего кадра, когда ReplayKit прекращает отправку кадров:

Я видел это поведение в примере Twilio ReplayKit, но должны ли мы повторно отправлять последний кадр, когда ReplayKit не отправляет ни одного кадра? Я не видел ни одного документа, если все в порядке или если медиа-маршрутизатор будет вести себя правильно, если мы это сделаем

PS: некоторые ссылки, которые я нашел на случай, если это может помочь кому-то другому

Все, что я видел в предлагаемом примере поддержки OpenTok, это:

  • поддерживаемые пресеты для iOS AVCaptureSession, которые затем пересылаются в OTVideoCapturer (Custom-Video-Driver / Lets-Build-OTPublisher / Single-Cam-Capturer/TBExampleVideoCapture.m # L255)
  • жестко заданный размер черных рамок (Custom-Video-Driver / Lets-Build-OTPublisher / Single-Cam-Capturer /TBExampleVideoCapture.m # L552)
  • необработанный CMSampleBuffer пересылается непосредственно пользователю videoCaptureConsumer (Custom-Video-Driver / Lets-Build-OTPublisher/ Single-Cam-Capturer/TBExampleVideoCapture.m # L711)

Из документа OpenTok и сообщений на форуме:

Я также нашел несколько других сообщений, которые помогли понять, в чем может быть проблема:

Комментарии:

1. Есть ли у вас какие-либо обновления по этому поводу? У меня такая же проблема с последним обновлением, и расширение широковещательной передачи постоянно превышает лимит памяти.

Ответ №1:

В итоге я использовал OTVideoFrame для отправки изображения и реализации логики повторной отправки последнего кадра с использованием DispatchWorkItem

     // We just received a frame, cancel any retransmit
    self.resetRetransmitTimer()

    let resized = cgImage
    self.checkPixelBufferSize(forImage: resized)
    let ref = self.fillPixelBuffer(withCGImage: resized)
    CVPixelBufferLockBaseAddress(ref, CVPixelBufferLockFlags.readOnly)
    
    self.videoFrame?.format?.pixelFormat = .ARGB
    self.videoFrame?.timestamp = timestamp
    self.videoFrame?.format?.estimatedCaptureDelay = 10
    self.videoFrame?.format?.estimatedFramesPerSecond = self.config.desiredFrameRate
    self.videoFrame?.orientation = .up
    
    self.videoFrame?.clearPlanes()
    self.videoFrame?.planes?.addPointer(CVPixelBufferGetBaseAddress(ref))
    
    self.videoCaptureConsumer?.consumeFrame(self.videoFrame!)
    
    self.lastReplayKitImage = cgImage
    self.lastReplayKitImageTimeStamp = timestamp
    
    CVPixelBufferUnlockBaseAddress(ref, CVPixelBufferLockFlags.readOnly)
    
    self.scheduleRetransmitTimer()
 

Комментарии:

1. Можете ли вы поделиться подробным кодом? Как работают таймеры передачи?