Как реализовать загрузку в расширении загрузки вещания (iOS)?

Кто-нибудь знает, есть ли возможность загружать буферы кадров из расширения Broadcast Upload Extension в хост-приложение, или я должен загружать их непосредственно в серверную часть? Моя цель - перехватить буферы кадров из набора воспроизведения, отправить их в мое приложение и транслировать видео через мое приложение с помощью Webrtc. Буду признателен за любую помощь. Заранее спасибо.


person Seliver    schedule 22.09.2016    source источник
comment
Не могли бы вы поделиться решением, которое вы нашли. Это может быть текстовый алгоритм, который мы должны использовать, или исходный код (лучший способ). Заранее спасибо. P.S. Меня интересует по частям: как вы переносили данные из расширения в основное приложение и как вы кодируете образцы для передачи их в webRTC.   -  person Bws Sluk    schedule 31.05.2018


Ответы (3)


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

Но вы можете реализовать всю логику в расширении Broadcast Upload. Ваша RPBroadcastSampleHandler реализация питается видео CMSampleBuffers. Вся логика постобработки и загрузки зависит от реализации. Таким образом, вы можете распаковывать и обрабатывать кадры, а затем загружать их на свой сервер любым подходящим способом. Если вам нужны какие-либо сведения о конфигурации или авторизации, вы можете просто установить их в расширении широковещательного пользовательского интерфейса или даже в своем хост-приложении, а затем просто сохранить их в общем хранилище.

Информации об этом нет ни в Интернете, ни в документации Apple. Но вы все еще можете:

  • Посмотреть видео о WWDC 2016 Go Live with ReplayKit
  • Прочтите RPBroadcastSampleHandler документацию
  • Прочтите этот весьма полезный пост в блоге (на китайском языке): http://blog.lessfun.com/blog/2016/09/21/ios-10-replaykit-live-and-broadcast-extension/
  • Поиграйте с реализацией заглушки расширения загрузки (просто создайте цель в Xcode)
person Eugene    schedule 18.11.2016

Точно так же я пробовал с комбинацией Replay Kit и webRTC. Основная проблема webRTC на iOS заключается в том, что webRTC не может обрабатывать видеопоток, если он уходит в фоновый режим. Итак ... вы можете транслировать видеопоток с экрана вашего приложения в webRTC, пока ваше приложение для видеочата находится на переднем плане, но для потоковой передачи другого приложения, когда ваше приложение переходит в фоновый режим, вы не сможете обрабатывать видеопоток, а только голосовую связь через webRTC.

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

person user3806731    schedule 08.06.2018
comment
Прикомандированный. Просто потратил две недели на тот же подход. Работал отлично, пока приложение не вошло в фоновый режим. Мне кажется, что это может работать, если вы заставите webrtc использовать программную кодировку vp8, но я не могу сохранить настройку. - person nevyn; 01.08.2018
comment
Вы пытались реализовать для этого широковещательное расширение или просто транслировали из самого приложения? - person Milan Nosáľ; 24.10.2018
comment
Между тем, можно транслировать через WebRTC даже в фоновом режиме. Используйте функции ReplayKit 2 для захвата всего экрана - person decades; 02.05.2019
comment
Я хотел бы знать, пытались ли вы реализовать широковещательное расширение или просто транслировать из самого приложения? широковещательное расширение кажется, что оно должно работать даже в фоновом режиме, хотя - person Maryam Fekri; 11.12.2019

У меня есть для вас код, я уже реализовал его в своем проекте и обсуждал в google-группах: https://groups.google.com/d/msg/discuss-webrtc/jAHCnB12khE/zJEu1vyUAgAJ

Я перенесу сюда код для следующих поколений:

Прежде всего, я создал дополнительный класс в широковещательном расширении для управления кодом, связанным с WebRTC, и назвал его PeerManager.

Настройте видеодорожку с локальным потоком, будьте осторожны, вы должны сделать это до создания локального предложения.

private func setupVideoStreaming() {        
        localStream = webRTCPeer.peerConnectionFactory.mediaStream(withStreamId: "\(personID)_screen_sharing")
        videoSource = webRTCPeer.peerConnectionFactory.videoSource()
        videoCapturer = RTCVideoCapturer(delegate: videoSource)
        videoSource.adaptOutputFormat(toWidth: 441, height: 736, fps: 15)
        let videoTrack = webRTCPeer.peerConnectionFactory.videoTrack(with: videoSource, trackId: "screen_share_track_id")
        videoTrack.isEnabled = true
        localStream.addVideoTrack(videoTrack)
        for localStream in webRTCPeer.localPeerConnection.peerConnection.localStreams {
            webRTCPeer.localPeerConnection.peerConnection.remove(localStream)

        }
        webRTCPeer.localPeerConnection.peerConnection.add(localStream)
    }

Я получил обратный вызов от системы, которая предоставляет мне CMSampleBuffer, я конвертирую его в RTCVideoFrame и отправляю в videoSource (эмулировать VideoCapturer)

override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
        switch sampleBufferType {
            case RPSampleBufferType.video:
                // Handle video sample buffer
                guard peerManager != nil, let imageBuffer: CVImageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
                    break
                }
                let pixelFormat = CVPixelBufferGetPixelFormatType(imageBuffer) // kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
                let timeStampNs: Int64 = Int64(CMTimeGetSeconds(CMSampleBufferGetPresentationTimeStamp(sampleBuffer)) * 1000000000)                
                let rtcPixlBuffer = RTCCVPixelBuffer(pixelBuffer: imageBuffer)
                let rtcVideoFrame = RTCVideoFrame(buffer: rtcPixlBuffer, rotation: ._0, timeStampNs: timeStampNs)
                peerManager.push(videoFrame: rtcVideoFrame)
            case RPSampleBufferType.audioApp:
                break
            case RPSampleBufferType.audioMic:
                break
        }
    }

Код из peerManager, это реализация функций push из кода выше. Ничего странного здесь нет, мы эмулируем поведение Capturer с помощью delegate.

 func push(videoFrame: RTCVideoFrame) {
        guard isConnected, videoCapturer != nil, isProcessed else {
            return
        }
        videoSource.capturer(videoCapturer, didCapture: videoFrame)
    }

Теперь вы готовы сгенерировать локальное предложение, отправить его и передать все, что захотите. Попробуйте проверить свое местное предложение. Если вы все сделаете правильно, вы увидите в своем предложении a = sendonly.

P.S. Как предлагает VladimirTechMan, вы также можете проверить образец кода расширения вещания в демонстрационном приложении AppRTCMobile. Я нашел для вас ссылку, это пример Objective-C https://webrtc.googlesource.com/src/+/358f2e076051d28b012529d3ae6a080838d27209 Вас должны заинтересовать файлы ARDBroadcastSampleHandler.m / .h и ARDExternalSampleCapturer.m / .h. Никогда не забывайте, что вы можете собрать его самостоятельно согласно инструкции https://webrtc.org/native-code/ios/

person Bws Sluk    schedule 10.07.2018
comment
Я пытался запустить проект, но не могу создать проект из образца кода и использовал ваши фрагменты, но он тоже не работает, или мне добавить что-нибудь еще? - person dmyma; 07.09.2018
comment
@dmyma вам следует настроить код, который вы используете для обычного вызова webRTC в своем расширении вещания, но удалите из него часть deviceCapturer и замените эту часть функцией func push (videoFrame: RTCVideoFrame), потому что в broadcastExtension у вас нет захватывающее устройство. - person Bws Sluk; 14.10.2018
comment
@MaheshShahane: Не могли бы вы ответить на мой вопрос stackoverflow.com/questions/61190672/ Я борюсь с этим уже несколько недель. - person user2801184; 27.04.2020
comment
Вы импортировали фреймворк webrtc в расширение или каким-то образом создали расширение внутри фреймворка? - person Lakshman Kumar; 05.05.2020
comment
Привет, @BwsSluk. Не могли бы вы поделиться своим исходным кодом на github? Я столкнулся с аналогичной проблемой. Попытка импортировать фреймворк webrtc в расширение вещания, похоже, не работает. Не уверен, что делаю что-то не так - person ChrisTomAlx; 05.05.2020