在iOS中使用Twilio进行屏幕共享

时间:2020-10-18 17:41:21

标签: swift twilio

我正在使用Twilio iOS框架在会议室中进行连接。 在下面的“单击连接房间”按钮上,是我使用的代码

let recorder = RPScreenRecorder.shared()
recorder.isMicrophoneEnabled = false
recorder.isCameraEnabled = false

// The source produces either downscaled buffers with smoother motion, or an HD screen recording.
videoSource = ReplayKitVideoSource(isScreencast: true, telecineOptions: ReplayKitVideoSource.TelecineOptions.disabled)

screenTrack = LocalVideoTrack(source: videoSource!,
                              enabled: true,
                              name: "Screen")

recorder.startCapture(handler: { (sampleBuffer, type, error) in
    if error != nil {
        print("Capture error: ", error as Any)
        return
    }
    
    switch type {
    case RPSampleBufferType.video:
        self.videoSource?.processFrame(sampleBuffer: sampleBuffer)
        break
    case RPSampleBufferType.audioApp:
        break
    case RPSampleBufferType.audioMic:
        // We use `TVIDefaultAudioDevice` to capture and playback audio for conferencing.
        break
    }
    
}) { (error) in
    if error != nil {
        print("Screen capture error: ", error as Any)
    } else {
        print("Screen capture started.")
    }
}

if (accessToken == "TWILIO_ACCESS_TOKEN") {
    do {
        accessToken = try TokenUtils.fetchToken(url: tokenUrl)
    } catch {
        let message = "Failed to fetch access token"
        logMessage(messageText: message)
        return
    }
}

// Prepare local media which we will share with Room Participants.
self.prepareLocalMedia()

// Preparing the connect options with the access token that we fetched (or hardcoded).
let connectOptions = ConnectOptions(token: accessToken) { (builder) in
    
    // Use the local media that we prepared earlier.
    builder.audioTracks = self.localAudioTrack != nil ? [self.localAudioTrack!] : [LocalAudioTrack]()
    builder.videoTracks = self.localVideoTrack != nil ? [self.localVideoTrack!, self.screenTrack!] : [LocalVideoTrack]()
    
    // Use the preferred audio codec
    if let preferredAudioCodec = Settings.shared.audioCodec {
        builder.preferredAudioCodecs = [preferredAudioCodec]
    }
    
    // Use the preferred video codec
    if let preferredVideoCodec = Settings.shared.videoCodec {
        builder.preferredVideoCodecs = [preferredVideoCodec]
    }
    
    // Use the preferred encoding parameters
    if let encodingParameters = Settings.shared.getEncodingParameters() {
        builder.encodingParameters = encodingParameters
    }
    
    // Use the preferred signaling region
    if let signalingRegion = Settings.shared.signalingRegion {
        builder.region = signalingRegion
    }
    
    builder.roomName = self.roomTextField.text
}

// Connect to the Room using the options we provided.
room = TwilioVideoSDK.connect(options: connectOptions, delegate: self)

logMessage(messageText: "Attempting to connect to room \(String(describing: self.roomTextField.text))")

当我将组与远程参与者连接时,我想与远程参与者共享屏幕。
为了实现此功能,我已将“ ReplayKitExample”与应用程序内捕获方法一起使用。但是无法做到这一点。
远程参与者无法看到屏幕共享内容。
与此相关的任何事情都与屏幕共享无关,并且正在寻找实现它的投入。
我想与远程参与者共享屏幕。

1 个答案:

答案 0 :(得分:1)

它的发生是因为您试图同时发送“ cameraSource”和“ videoSource”这两个数据,而在发送“ viseoSource”之前必须取消订阅“ cameraSource”。 您可以参考以下代码:

// MARK:-通过replaykit进行屏幕共享 扩展CallRoomViewController:RPScreenRecorderDelegate {

func broadCastButtonTapped(){
    guard screenRecorder.isAvailable else {
        print("Not able to Broadcast")
        return
    }
    print("Can Broadcast")

    if self.videoSource != nil {
        self.stopConference()
    } else {
        self.startConference()
    }
}
func publishVideoTrack(){
    if let participant = self.room?.localParticipant,
            let videoTrack = self.localVideoTrack {
            participant.publishVideoTrack(videoTrack)
        }
}

func unpublishVideoTrack(){
    if let participant = self.room?.localParticipant,
        let videoTrack = self.localVideoTrack {
        participant.unpublishVideoTrack(videoTrack)
    }
}

func stopConference() {
    self.unpublishVideoTrack()
    self.localVideoTrack = nil
    self.videoSource = nil
    self.localVideoTrack = LocalVideoTrack(source: cameraSource!, enabled: true, name: "Camera")

    screenRecorder.stopCapture{ (captureError) in
        if let error = captureError {
            print("Screen capture stop error: ", error as Any)
        } else {
            print("Screen capture stopped.")
            self.publishVideoTrack()
        }
    }
}

func startConference() {

    self.unpublishVideoTrack()
    self.localVideoTrack = nil

    // We are only using ReplayKit to capture the screen.

    // Use a LocalAudioTrack to capture the microphone for sharing audio in the room.
    screenRecorder.isMicrophoneEnabled = false
    // Use a LocalVideoTrack with a CameraSource to capture the camera for sharing camera video in the room.
    screenRecorder.isCameraEnabled = false

    // The source produces either downscaled buffers with smoother motion, or an HD screen recording.
    self.videoSource = ReplayKitVideoSource(isScreencast: true,
                                       telecineOptions: ReplayKitVideoSource.TelecineOptions.p60to24or25or30)

    self.localVideoTrack = LocalVideoTrack(source: videoSource!,
                                  enabled: true,
                                  name: "Screen")

    let videoCodec = Settings.shared.videoCodec ?? Vp8Codec()!
    let (_, outputFormat) = ReplayKitVideoSource.getParametersForUseCase(codec: videoCodec,
                                                                                      isScreencast: true,
                                                                                   telecineOptions:ReplayKitVideoSource.TelecineOptions.p60to24or25or30)
    self.videoSource?.requestOutputFormat(outputFormat)

    screenRecorder.startCapture(handler: { (sampleBuffer, type, error) in
        if error != nil {
            print("Capture error: ", error as Any)
            return
        }

        switch type {
        case RPSampleBufferType.video:
            self.videoSource?.processFrame(sampleBuffer: sampleBuffer)
            break
        case RPSampleBufferType.audioApp:
            break
        case RPSampleBufferType.audioMic:
            // We use `TVIDefaultAudioDevice` to capture and playback audio for conferencing.
            break
        default:
            print(error ?? "screenRecorder error")
        }

    }) { (error) in
        if error != nil {
            print("Screen capture error: ", error as Any)
        } else {
            print("Screen capture started.")
            self.publishVideoTrack()
        }
    }
}

}

您可以从viewDidLoad()连接房间

    func connectToChatRoom(){
    
    // Configure access token either from server or manually.
    // If the default wasn't changed, try fetching from server.
    accessToken = self.callRoomDetail.charRoomAccessToken
    
    guard accessToken != "TWILIO_ACCESS_TOKEN" else {
        let message = "Failed to fetch access token"
        print( message)
        return
    }
    // Prepare local media which we will share with Room Participants.
    self.prepareLocalMedia()
    
    // Preparing the connect options with the access token that we fetched (or hardcoded).
    let connectOptions = ConnectOptions(token: accessToken) { (builder) in
        
        // The name of the Room where the Client will attempt to connect to. Please note that if you pass an empty
        // Room `name`, the Client will create one for you. You can get the name or sid from any connected Room.
        builder.roomName = self.callRoomDetail.chatRoomName
        
        // Use the local media that we prepared earlier.
        if let audioTrack = self.localAudioTrack {
            builder.audioTracks = [ audioTrack ]
        }
        
        if let videoTrack = self.localVideoTrack {
            builder.videoTracks = [ videoTrack ]
        }
        
        
        // Use the preferred audio codec
        if let preferredAudioCodec = Settings.shared.audioCodec {
            builder.preferredAudioCodecs = [preferredAudioCodec]
        }
        
        // Use the preferred video codec
        if let preferredVideoCodec = Settings.shared.videoCodec {
            builder.preferredVideoCodecs = [preferredVideoCodec]
        }
        
        // Use the preferred encoding parameters
        let videoCodec = Settings.shared.videoCodec ?? Vp8Codec()!
        let (encodingParams, _) = ReplayKitVideoSource.getParametersForUseCase(codec: videoCodec,
                                                                                          isScreencast: true,
                                                                                       telecineOptions:ReplayKitVideoSource.TelecineOptions.p60to24or25or30)

        builder.encodingParameters = encodingParams

        // Use the preferred signaling region
        if let signalingRegion = Settings.shared.signalingRegion {
            builder.region = signalingRegion
        }
        
        builder.isAutomaticSubscriptionEnabled = true
        
        builder.isNetworkQualityEnabled = true
        builder.networkQualityConfiguration = NetworkQualityConfiguration(localVerbosity: .minimal,
                                                                          remoteVerbosity: .minimal)
        
    }
    
    // Connect to the Room using the options we provided.
    room = TwilioVideoSDK.connect(options: connectOptions, delegate: self)
    print( "Attempting to connect to room \(self.callRoomDetail.chatRoomName ?? ""))")
    
    self.showRoomUI(inRoom: true)
}

您可以从twilio存储库https://github.com/twilio/video-quickstart-ios/tree/master/ReplayKitExample

中获取ReplayKitVideoSource文件和其他文件。