首页 > 解决方案 > 如何在 iOS 中流式传输没有广播扩展的屏幕

问题描述

我想将我的应用程序流式传输到 twitch、youtube 或这样的流媒体服务,而不需要任何其他应用程序,例如 mobcrush。

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

我想如果我可以获得视频数据,我可以在我的应用程序中不使用广播扩展来流式传输其他内容。所以我尝试将 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")
        }
    }
}

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

标签: iosiphoneswiftstreamingreplaykit

解决方案


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

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

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 服务。


推荐阅读