twilio / video-quickstart-ios

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

How to restrict remote participant video when both are connect to same room? #530

Closed mouli457 closed 3 years ago

mouli457 commented 4 years ago

I have integrate TwilioVideo functionality in my project.when both users connect to same room by mobile and web.Web user video displaying in mobile without accepting from web.

 var tokenUrl = "http://localhost:3000/token.php"

 // Video SDK components
 var room: Room?
 var camera: CameraSource?
 var localVideoTrack: LocalVideoTrack?
 var localAudioTrack: LocalAudioTrack?
 var remoteParticipant: RemoteParticipant?
 var remoteView: VideoView?
 var roomName = String()
var accessToken = String()

@IBAction func connect(sender: AnyObject) {
// Configure access token either from server or manually.
// If the default wasn't changed, try fetching from server.
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!] : [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)

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

}

 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()
}
}

// Update our UI based upon if we are in a Room or not
func showRoomUI(inRoom: Bool)
 {
 self.micButton.isHidden = !inRoom
 self.disconnectButton.isHidden = !inRoom
 self.navigationController?.setNavigationBarHidden(inRoom, animated: true)
  UIApplication.shared.isIdleTimerDisabled = inRoom

 // Show / hide the automatic home indicator on modern iPhones.
 self.setNeedsUpdateOfHomeIndicatorAutoHidden()
  }

 func logMessage(messageText: String) {
NSLog(messageText)
messageLabel.text = messageText
 }

  func renderRemoteParticipant(participant : RemoteParticipant) -> Bool {
// This example renders the first subscribed RemoteVideoTrack from the RemoteParticipant.
let videoPublications = participant.remoteVideoTracks
for publication in videoPublications {
    if let subscribedVideoTrack = publication.remoteTrack,
        publication.isTrackSubscribed {
       setupRemoteVideoView()
        self.showRoomUI(inRoom: true)
        subscribedVideoTrack.addRenderer(self.remoteView!)
        self.remoteParticipant = participant
        return true
    }
}
return false
}

 func renderRemoteParticipants(participants : Array<RemoteParticipant>) {
for participant in participants {
    // Find the first renderable track.
    if participant.remoteVideoTracks.count > 0,
        renderRemoteParticipant(participant: participant) {
        break
    }
   }
 }

  func setupRemoteVideoView() {
// Creating `VideoView` programmatically
self.remoteView = VideoView(frame: CGRect.zero, delegate: self)

self.view.insertSubview(self.remoteView!, at: 0)

// `VideoView` supports scaleToFill, scaleAspectFill and scaleAspectFit
// scaleAspectFit is the default mode when you create `VideoView` programmatically.
self.remoteView!.contentMode = .scaleAspectFill;

let centerX = NSLayoutConstraint(item: self.remoteView!,
                                 attribute: NSLayoutConstraint.Attribute.centerX,
                                 relatedBy: NSLayoutConstraint.Relation.equal,
                                 toItem: self.view,
                                 attribute: NSLayoutConstraint.Attribute.centerX,
                                 multiplier: 1,
                                 constant: 0);
self.view.addConstraint(centerX)
let centerY = NSLayoutConstraint(item: self.remoteView!,
                                 attribute: NSLayoutConstraint.Attribute.centerY,
                                 relatedBy: NSLayoutConstraint.Relation.equal,
                                 toItem: self.view,
                                 attribute: NSLayoutConstraint.Attribute.centerY,
                                 multiplier: 1,
                                 constant: 0);
self.view.addConstraint(centerY)
let width = NSLayoutConstraint(item: self.remoteView!,
                               attribute: NSLayoutConstraint.Attribute.width,
                               relatedBy: NSLayoutConstraint.Relation.equal,
                               toItem: self.view,
                               attribute: NSLayoutConstraint.Attribute.width,
                               multiplier: 1,
                               constant: 0);
self.view.addConstraint(width)
let height = NSLayoutConstraint(item: self.remoteView!,
                                attribute: NSLayoutConstraint.Attribute.height,
                                relatedBy: NSLayoutConstraint.Relation.equal,
                                toItem: self.view,
                                attribute: NSLayoutConstraint.Attribute.height,
                                multiplier: 1,
                                constant: 0);
self.view.addConstraint(height)
}

this is my publication response

trackSid: MTb80db34080ec204bd978608425dd3bad trackName: 45339dcc-1ab8-4044-85c8-981d9d8a0229 isEnabled: YES

I don't want to show remote participant video directly to mobile.I want to show when remote participant accept from web.

ceaglest commented 4 years ago

Hey @mouli457,

I don't want to show remote participant video directly to mobile.I want to show when remote participant accept from web.

If you are accepting the web Participant after they are in the Room, then the web Participant should not publish tracks until they accept. The iOS app can just wait for the subscription callbacks as usual.

Borrowing some similar code from our Web guide.

const { createLocalVideoTrack } = require('twilio-video');

// Web has accepted.
createLocalVideoTrack().then(localVideoTrack => {
  return room.localParticipant.publishTrack(localVideoTrack);
}).then(publication => {
  console.log('Successfully published your video:', publication);
});

Best, Chris

mouli457 commented 4 years ago
   func didSubscribeToVideoTrack(videoTrack: RemoteVideoTrack, publication: RemoteVideoTrackPublication, participant: RemoteParticipant) {

    logMessage(messageText: "Subscribed to \(publication.trackName) video track for Participant \(participant.identity)")

    if (self.remoteParticipant == nil) {
        _ = renderRemoteParticipant(participant: participant)
    }
}

when remote participant join room above method was calling and getting tracksid,trackname and isenable(as YES).

ceaglest commented 4 years ago

Hey @mouli457,

when remote participant join room above method was calling and getting tracksid,trackname and isenable(as YES).

Yes, that's why I suggested changing your JavaScript application which controls the RemoteParticipant. Have you had a chance to try the code snippet where the JavaScript Participant publishes after connecting to the Room (https://github.com/twilio/video-quickstart-ios/issues/530#issuecomment-663164642)?

Best, Chris

piyushtank commented 3 years ago

Closing an old ticket but feel free to reopen or file another if you run into any issues.