Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local video source not displayed on the remote side after first displaying #657

Open
Robtles opened this issue Dec 6, 2022 · 0 comments

Comments

@Robtles
Copy link

Robtles commented Dec 6, 2022

Description

Hello, I am trying to implement Twilio Video in an application, but I'm struggling with the case when a user stops his camera, and then starts it again. The local video track is correctly being published to the room the first time, but when he stops and starts again the camera, it's not displayed again on the remote side.

I am working with a web/backend team which handles the code for Twilio implementation on the web side, which is where the error occurs (the local iOS video is not displayed there), so I don't have access to this code but I wanted to know if something might be wrong with mine.

Here is what I have written so far :

Code

final class VideoViewController: UIViewController {
    /// Instance
    private var accessToken: String?
    private var cameraIsOn: Bool = true {
        didSet {
            guard oldValue != cameraIsOn else { return }
            updateLocalCameraStatus()
        }
    }
    private var roomName: String?

    /// Twilio
    private var cameraSource: CameraSource?
    private var localVideoTrack: LocalVideoTrack?
    private var room: Room?

    /// View
    @IBOutlet weak var cameraButton: UIButton!
    @IBOutlet weak var previewView: VideoView?

    /// Action
    @IBAction func tappedCamera() {
        cameraIsOn.toggle()
    }

    /// Lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()
        previewView?.delegate = self
        updateLocalCameraStatus()
        connectToTheRoom()
    }

    /// Twilio
    private func connectToTheRoom() {
        guard let accessToken else { return }
        let connectOptions = ConnectOptions(
            token: accessToken
        ) { [weak self] builder in
            guard let self else { return }
            builder.videoTracks = [self.localVideoTrack].compactMap { $0 }
            builder.roomName = self.roomName
        }
        room = TwilioVideoSDK.connect(
            options: connectOptions,
            delegate: self
        )
    }
    
    private func startPreview() {
        guard let frontCamera = CameraSource.captureDevice(position: .front),
              let source = CameraSource(delegate: self),
              let previewView else {
            return
        }
        localVideoTrack = LocalVideoTrack(source: source, enabled: true, name: "camera")
        cameraSource = source
        cameraSource?.startCapture(device: frontCamera)
        guard let localVideoTrack else { return }
        localVideoTrack.addRenderer(previewView)
        room?.localParticipant?.publishVideoTrack(localVideoTrack)
    }
    
    private func stopPreview() {
        cameraSource?.stopCapture()
        if let localVideoTrack {
            room?.localParticipant?.unpublishVideoTrack(localVideoTrack)
            if let previewView {
                localVideoTrack.removeRenderer(previewView)
            }
        }
        cameraSource = nil
        localVideoTrack = nil
    }
    
    private func updateLocalCameraStatus() {
        cameraIsOn ? startPreview() : stopPreview()
    }
}

/// Twilio Extensions
extension VideoViewController: RoomDelegate {
    func roomDidConnect(room: Room) {
        print("roomDidConnect")
    }
}

extension VideoViewController: CameraSourceDelegate {
    func cameraSourceWasInterrupted(source: CameraSource, reason: AVCaptureSession.InterruptionReason) {
        localVideoTrack?.isEnabled = false
    }

    func cameraSourceInterruptionEnded(source: CameraSource) {
        localVideoTrack?.isEnabled = true
    }
}

extension VideoViewController: VideoViewDelegate {
    func videoViewDimensionsDidChange(view: VideoView, dimensions: CMVideoDimensions) {
        view.setNeedsLayout()
    }
}

Expected Behavior

Every time the user stops the camera (stopPreview()) then starts it again (startPreview()), the remote participant should be able to watch its track.

Actual Behavior

The video track is not displayed after the first time the user stops the preview.

Reproduces How Often

Always.

Logs

No relevant log.

Versions

Video iOS SDK

5.3.0

Xcode

14.0.1

iOS Version

16.1.1

iOS Device

iPhone XR

Thank you for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant