twilio / video-quickstart-ios

Twilio Video Quickstart for iOS
https://www.twilio.com/docs/api/video
MIT License
461 stars 178 forks source link

Unable to share screen #599

Closed hitgupta closed 2 years ago

hitgupta commented 3 years ago

Hi,

I am trying to share my application screen while in a video call but I am unable to do so. Here is the piece of code being used to share screen :

@IBAction func shareScreenTapped(_ sender: Any) {

    // Start recording the screen.
    let options = AppScreenSourceOptions() { builder in
        builder.screenContent = .video
    }
    if let source = AppScreenSource(options: options, delegate: self), let track = LocalVideoTrack(source: source, enabled: true, name: "Screen") {
        room?.localParticipant?.publishVideoTrack(track)
        source.startCapture()
    }
}

Can you please help?

timrozum commented 3 years ago

Hi @hitgupta,

Your code snippet looks ok so it may be something else. Here are some ideas:

  1. Use startCaptureWithCompletion so that you know if capture was started successfully or not. And if not what the error is.
  2. Use delegate methods appScreenSourceDidReceiveCaptureError and didStopCapturingWithError to determine if other errors are being reported.
  3. Verify localParticipant is not nil when publishing the track.
  4. Provide more details about what is not working. On the other device are you even receiving the video track?
  5. Enable debug log and reproduce.
  6. Confirm that you are able to get the screen capture quickstart working on your device.

Thanks, Tim

hitgupta commented 3 years ago

Hey @timrozum , Thanks for responding. So I was able to share my screen after I passed another VideoTrack just to share screen :

func prepareLocalMedia() {

    // We will share local audio and video when we connect to the Room.

    // Create an audio track.
    if (localAudioTrack == nil) {
        localAudioTrack = LocalAudioTrack(options: nil, enabled: true, name: "Microphone")

        if (localAudioTrack == nil) {
            logMessage(messageText: "Failed to create audio track")
        }
    }

    // Create a video track which captures from the camera.
    if (localVideoTrack == nil) {
        self.startPreview()
    }
    if localShareVideoTrack == nil {
        // Start recording the screen.
        let options = AppScreenSourceOptions() { builder in
            builder.screenContent = .video
        }
        if let source = AppScreenSource(options: options, delegate: self) {
            self.screenSource = source
            self.localShareVideoTrack = LocalVideoTrack(source: source, enabled: true, name: "Screen")

        }
    }

}

// MARK:- IBActions @IBAction func connect(sender: AnyObject) {

    // 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.localShareVideoTrack!] : [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
        }

        // 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.roomName
    }

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

    self.showRoomUI(inRoom: true)
}

@IBAction func shareScreenTapped(_ sender: UIButton) { if sender.isSelected { screenSource?.stopCapture() sender.isSelected.toggle() room?.localParticipant?.unpublishVideoTrack(localShareVideoTrack!) } else { self.room?.localParticipant?.publishVideoTrack(self.localShareVideoTrack!) screenSource?.startCapture(completion: { error in sender.isSelected.toggle() if error != nil { print("Screen capture error: ", error as Any) } else { print("Screen capture started.") } }) } }

But now I am facing new issues: (2 participants, 1 on web and 1 on Mobile)

  1. At the web end of the call I am unable to see my video (mobile participant) once I join the call.
  2. After I click on the share button I am able to share the application screen (which is now visible on the web end too) and If I press it again to stop sharing, it does stop and now I get to see my video on the web end too. But if I press it the third time to share my screen again I am unable to share the screen again. I have a feeling that there's something wrong with the way I am publishing and unpublishing the share screen video track.
timrozum commented 3 years ago

Hi @hitgupta,

Are you still having these issues?

With regard to not seeing the mobile participant video from the web app I would suggest confirming that both mobile and web are using the same track name convention. It is odd that your camera video appears on web after you stop sharing your screen. To narrow the problem down are you able to view from another iOS device to determine if the issue is on iOS or web end?

For the issue with screen share not coming back on the second time I don't see an obvious issue with your code. Although it should not be necessary you might try completely deallocating the screen share source and track when it is not in use to see if something can be learned. This may also be the safest and cleanest implementation also but that depends on your app. If you still have issues maybe you could upload a sample app or try collecting logs from the SDK and attach them. See TwilioVideoSDK.setLogLevel.

timrozum commented 2 years ago

I'm going to close this out but @hitgupta please feel free to report back here if there are more issues. Thanks!