在iOS中如何在没有广播扩展的情况下流式传输屏幕

时间:2018-08-29 02:48:38

标签: ios iphone swift streaming replaykit

我想流式传输我的应用程序以抽搐,youtube或诸如此类的流式传输服务,而没有其他应用程序像暴民喜欢。

根据Apple的说法,通过使用Broadcast Extension,我可以流式传输应用程序屏幕。 广播扩展将视频数据作为CMSampleBuffer的一种类型提供。然后,我应该将该数据发送到rtmp服务器,例如youtube,抽搐等。

我认为,如果我可以获取视频数据,则可以流式传输其他内容,而无需在我的应用程序中使用Broadcast Extension。因此,我尝试将RPScreenRecorder数据发送到rtmp服务器,但无法正常工作。

这是我写的代码。 我使用HaishinKit开源框架进行rtmp通信。 (https://github.com/shogo4405/HaishinKit.swift/tree/master/Examples/iOS/Screencast

    let rpScreenRecorder : RPScreenRecorder = RPScreenRecorder.shared()
    private var broadcaster: RTMPBroadcaster = RTMPBroadcaster()

    rpScreenRecorder.startCapture(handler: { (cmSampleBuffer, rpSampleBufferType, error) in
        if (error != nil) {
            print("Error is occured \(error.debugDescription)")
        } else {

            if let description: CMVideoFormatDescription = CMSampleBufferGetFormatDescription(cmSampleBuffer) {
                let dimensions: CMVideoDimensions = CMVideoFormatDescriptionGetDimensions(description)
                self.broadcaster.stream.videoSettings = [
                    "width": dimensions.width,
                    "height": dimensions.height ,
                    "profileLevel": kVTProfileLevel_H264_Baseline_AutoLevel
                ]
            }
            self.broadcaster.appendSampleBuffer(cmSampleBuffer, withType: .video)

        }
    }) { (error) in
        if ( error != nil) {
            print ( "Error occured \(error.debugDescription)")
        } else {
            print ("Success")
        }
    }
}

如果您有任何解决方案,请回答我:)

1 个答案:

答案 0 :(得分:0)

我尝试了类似的设置,并且可以实现您想要的,只需要稍微调整一下即可:

在您的示例中我没有看到它,但是请确保正确设置了广播公司的端点。例如:

let endpointURL: String = "rtmps://live-api-s.facebook.com:443/rtmp/"
let streamName: String = "..."
self.broadcaster.streamName = streamName
self.broadcaster.connect(endpointURL, arguments: nil)

然后,您需要在startCapture的处理程序块中按缓冲区类型进行过滤,以将正确的数据发送到流。在这种情况下,您仅发送视频,因此我们可以忽略音频。 (您也可以通过HaishinKit找到一些示例来发送音频。)例如:

RPScreenRecorder.shared().startCapture(handler: { (sampleBuffer, type, error) in
        if type == .video, broadcaster.connected {
            if let description: CMVideoFormatDescription = CMSampleBufferGetFormatDescription(sampleBuffer) {
              let dimensions: CMVideoDimensions = CMVideoFormatDescriptionGetDimensions(description)
               broadcaster.stream.videoSettings = [
                  .width: dimensions.width,
                  .height: dimensions.height ,
                  .profileLevel: kVTProfileLevel_H264_Baseline_AutoLevel
              ]
            }
            broadcaster.appendSampleBuffer(sampleBuffer, withType: .video)
        }
    }) { (error) in }

还要确保在流式传输过程中更新了屏幕。我注意到,如果您正在使用RPScreenRecorder录制静态窗口,则只有在实际上有新的视频数据要发送时,它才会更新处理程序。为了进行测试,我添加了一个简单的UISlider,当您移动提要时,该提要会更新。

我已经在Facebook Live中对其进行了测试,并且我认为它也可以与其他RTMP服务一起使用。