livekit / client-sdk-swift

LiveKit Swift Client SDK. Easily build live audio or video experiences into your mobile app, game or website.
https://livekit.io
Apache License 2.0
176 stars 85 forks source link

Multiple issue related to mic and camera #287

Closed LakhinaRajat closed 6 months ago

LakhinaRajat commented 6 months ago

Implemented Live kit connect to room

  1. Even after turning off the camera other users are able to see that user who turned of the camera but for that particular user camera is off.
  2. turning off mic lead to turn off camera as well.
  3. for some user status of mic is incorrect.
  4. if I reload participant grid camera is turning off some time.
hiroshihorie commented 6 months ago

Hello which version of the SDK are you using ?

LakhinaRajat commented 6 months ago

Hello which version of the SDK are you using ?

Screenshot 2024-01-02 at 7 18 44 PM

I am using 1.1.3 and I have integrated Live kit in UIKit Project

davidzhao commented 6 months ago

Can you please share the code that is used to achieve each of the above? Can you reproduce with our sample app?

LakhinaRajat commented 6 months ago

Can you please share the code that is used to achieve each of the above? Can you reproduce with our sample app?

I have implemented in UIKit by taking reference from sample project

here are the functions that I am calling for mic mute and un-mute

private func toggleCameraEnabled(isMuted: Bool) {

    guard let localParticipant = room.localParticipant else {
        //log("LocalParticipant doesn't exist", .notice)
        return
    }

    localParticipant.setCamera(enabled: !isMuted).then {  [weak self] publication in
        DispatchQueue.main.async {
            self?.rtDataSource?.updateGrid(for: localParticipant)
        }
    }.catch { error in
        debugPrint(error)
    }
}

private func toggleMicrophoneEnabled(isMuted: Bool) {

    guard let localParticipant = room.localParticipant else {
        //log("LocalParticipant doesn't exist", .notice)
        return
    }

    localParticipant.setMicrophone(enabled: !isMuted).then { publication in
        DispatchQueue.main.async { [weak self] in
            self?.rtDataSource?.updateGrid(for: localParticipant)
        }
    }.catch { error in
        debugPrint(error)
    }

}

and in UICollectionViewCell

public weak var participant: Participant? { didSet { guard oldValue != participant else { return }

        if let oldValue = oldValue {
            oldValue.remove(delegate: self)
            videoView.track = nil
            labelView.text = ""
        }

        if let participant = participant {
            participant.add(delegate: self)

            if trackEnabled {
                _ = participant.videoTracks.first?.track?.start()

                if !disableAudioTrack {
                    _ = participant.audioTracks.first?.track?.start()
                } else {
                    _ = participant.audioTracks.first?.track?.stop()
                }

                setFirstVideoTrack()
            } else {
                _ = participant.videoTracks.first?.track?.stop()
                _ = participant.audioTracks.first?.track?.stop()
            }

            setNeedsLayout()
        }
    }
}

func setParticipantData(with participant: Participant, showMoreButton: Bool, localParticipantId: String) {
    self.participant = nil
    self.participant = participant

    let isModerator = RoomHelper.shared.handleMetaAndCheckModerator(for: participant)
    let isWildcard = RoomHelper.shared.handleMetaAndCheckWildCard(for: participant) && localParticipantId == participant.identity

    self.labelView.text = "@\(participant.name)"

    switch RoomHelper.shared.getParticipantRole(for: participant) {
        case .panelist, .ownerPanelist:
            self.roleLabelView.text = "[\(AppString.panellistsString)]"
        case .moderator, .ownerModerator, .moderatorCoOwner:
            self.roleLabelView.text = "[\(AppString.moderatorRTString)]"
        case .wildcard:
            self.roleLabelView.text = "[\(AppString.wildcardString)]"
        default:
            break
    }

    // handle meeting stated
    self.profileImage.image = nil
    self.profileImage.image = UIImage(resource: .placeholderProfile)
    self.profileImage.sd_cancelCurrentImageLoad()

    if let name = self.participant?.name {
        if let url = URL(string: Domain.getUserBoardinURL()+URLStruct.userProfilePhoto+"/\(name)/medium/"){
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                    self.profileImage.loadImageWithUrl(url, name)
            }

        } else {
            var nameChar = String()
            let trimmedName = name.trimmingCharacters(in: .whitespacesAndNewlines)
            let nameArray = trimmedName.components(separatedBy: " ")
            if nameArray.count > 1 && (!nameArray[1].isEmpty && nameArray[1].first != nil){
                nameChar = String(nameArray[0].first!) + String(nameArray[1].first!)
            }else{
                nameChar = String(nameArray[0].first ?? "A")
            }
            let url = URLStruct.profilePicUrl + "\(nameChar)"
            self.profileImage.sd_setImage(with: URL(string: url))
        }
    }

    let showMoreButton = isWildcard ? false : (isModerator ? true : !showMoreButton)

    self.moreButton.isHidden = showMoreButton
    self.moreButtonContainerView.isHidden = showMoreButton

    self.toggleViews(for: participant)
}

private func toggleViews(for participant: Participant) {
    DispatchQueue.main.async {

        self.micImage.image = ((participant.audioTracks.first?.muted ?? false) || !participant.isMicrophoneEnabled()) ? UIImage(resource: .component831) : UIImage(resource: .group22372)

        let showVideoView = participant.isCameraEnabled() || participant.isScreenShareEnabled()

        self.videoView.isHidden = self.trackEnabled ? !showVideoView : self.trackEnabled
        self.profileImage.isHidden = self.trackEnabled ? showVideoView : !self.trackEnabled

        self.videoView.setNeedsLayout()
    }
}

private func setFirstVideoTrack() {
    DispatchQueue.main.async {
        if self.trackEnabled {
            let track = self.participant?.videoTracks.first?.track as? VideoTrack
            //print("participant naem: \(participant?.name), isCameraEnabled: \(participant?.isCameraEnabled() ?? false)")
            self.videoView.track = track //- > nil
        }
    }
}
davidzhao commented 6 months ago

your code in UICollectionViewCell is likely where the bug is. It's extremely unlikely that the issues that you are seeing originates from the SDK.

LakhinaRajat commented 6 months ago

If this is UICollectionViewCell turning off the camera other users are able to see that user who turned of the camera but for that particular user camera is off.

your code in UICollectionViewCell is likely where the bug is. It's extremely unlikely that the issues that you are seeing originates from the SDK.

if UICollectionViewCell has issue

how I am getting these

`

  1. Even after turning off the camera other users are able to see that user who turned of the camera but for that particular user camera is off.
  2. turning off mic lead to turn off camera as well.
  3. for some user status of mic is incorrect. `

there is no role of UICollectionViewCell in 3 of them