Switch Camera Track Count Is Wrong On iPhone

Hi

I love open vidu, but i’m having a strange issue. I have followed this: OpenVidu Docs

I loaded up on my iphone, and after getting the tracks array there is only showing up, my iphone has 2 cameras.

Can i please get some help on switching cameras? Here is the basic code i am using to detect the tracks and do switch on button press:

OVSession.connect(token).then(() => {

OVUserMedia = OV.getUserMedia({
  audioSource: false
}).then(mediaStream => {

  OVVideoTracks = mediaStream.getVideoTracks();
  console.log("MEDIA STREAM",mediaStream);
});
console.log("USER MEDIA",OVUserMedia)
OVPublisher = OV.initPublisher("publisher-video");
OVSession.publish(OVPublisher);

}).catch(error =>{
alert('There was an error connecting to the session: ’ + error.message);
})

OVVideoTracks has only got 1element in it instead of two?

Also, when i actually tell it to switch the track to index 0, the video just goes black?

OVPublisher.replaceTrack(OVVideoTracks[0]).then(() => {
console.log(“SWITCHED TRACK”);
//OVCurrentCamera = 0;
}).catch(()=>{
console.log(“TRACK SWITCH FAILED”);
});

This is not a mobile app by the way, it’s a website and loaded up in safari on iphone.

hey instead of audiosource: false
try this ```
videoSource: true or use both

Hi

Thanks. What actually do those settings mean?

Anyway, i tried it, and it has seemed to do something but now i get the following error in the console:

OpenViduError: {“name”:“DEVICE_ACCESS_DENIED”,“message”:“TypeError: Type error”}

I’m assuming this means the back camera has not been granted access? Yet it doesn’t ask me to give it access like it does with the front facing when the stream first starts.

yes give the access of cameras on first time and its need only once

That’s what I am saying, when the camera is first accessed the phone asks for permission then the front camera works. Then, I press my button to switch the camera to the back one and it says access denied

Then something else wrong in your code.
Without seeing complete code I can’t guess permission problem.
But I think now your replace track code working. So just solve permission issue.

Thanks
Regards
Vipin

What do yoh mean? I don’t have any permission code. The phone asks for permission automatically when the publisher feed is started. When the switch camera code is run it doesn’t then ask for permission again it just shows that error in the console; yet already gave permission when activating the feed.

If it helps, here is the function to connect the publisher:

unction hostCam(sessionId,token,videoId)
{
OV = new OpenVidu();
OVSession = OV.initSession();

OVSession.on(‘streamCreated’,function (event) {
OVSession.subscribe(event.stream,‘publisher-video’);
})

console.log(sessionId+’ ‘+token+’ '+videoId);

OVSession.connect(token).then(() => {

OVPublisher = OV.initPublisher("publisher-video");
OVSession.publish(OVPublisher);

}).catch(error =>{
alert('There was an error connecting to the session: ’ + error.message);
})
}

And here is the code to switch the camera, it hits the catch statement with access denied:

function switchCam(){
//console.log(“track”,OV.getUserMedia())

OVUserMedia = OV.getUserMedia({
audioSource: false,
videoSource: true
}).then(mediaStream => {

OVVideoTracks = mediaStream.getVideoTracks();
console.log("TRACKS",OVVideoTracks);

}).catch((error)=>{
console.log(“TRACKS ERROR”,error)

switch(error.name){
  case 'DEVICE_ACCESS_DENIED':
    console.log("ACCESS DENIED");
    console.log("TRACKS DEVICE",OV.getDevices())
 
    break;
  default:
    console.log("DEFAULT ERROR");
    break;
}

})
}

It’s the getUserMedia() causing the error

You are confusing two totally different concepts. The video input devices that your mobile or computer has available have nothing to do with the video stream tracks, which are the video stream feed inside an already initialized MediaStream. These are all basic WebRTC and web API concepts. OpenVidu allows you to list the available devices with method OpenVidu.getDevices: https://docs.openvidu.io/en/latest/api/openvidu-browser/classes/openvidu.html#getdevices

You initialize a MediaStream (the Stream objectusing one of your input devices). Then that MediaStream will have the desired video stream track.

Regards.

I followed your document here OpenVidu Docs which at the top to switch camera says to look at the media stream and set the track?

When the stream is first published it just uses the first available camera and asks permission.

If the code in that document at the top doesn’t work how it says, then how am i to make it switch the device without unpublushing the stream? We don’t want to unpublish it, if people are watching the video and we just want to change camera.

If you want to replace the video track, then you need a new video track. You obtain a new video track using native Web API or using OpenVidu.getUserMedia method (which is a simple wrap around it). You can get a new video track from any video input device.

So can you help me then, how on earth do we actually switch the camera?

I can get the devices and have some code to determine which is currently being used and then switch the one it’s using, but then how do we then make the stream itself use the other device?

Unpublishable the stream surely won’t work as it will just click off all the subscribers when all I want to do it change which camera on the phone is being used in the same stream . Like when I use FaceTime I can just switch cameras.

As the documentation sais, you call method Publisher.replaceTrack using an already published Publisher (so it is the same stream that is being currently published). You pass as parameter a new MediaStreamTrack object. How you get a MediaStreamTrack object? You get a new MediaStreamTrack object from a MediaStream object. How you get a MediaStream object? You can get it on your own using native web API or using OpenVidu.getUserMedia. Either way, you initilize that new MediaStream with the input devices or any other kind of option that you want for the new video stream track.

I cannot really tell you more than this, it is really not that complex. You have a Publisher object. You change its internal video track by calling Publisher.replaceTrack, providing a different native object MediaStreamTrack.

Best regards.

That’s what my code is doing? And as i say when i try OV.getUserMedia() it gives me access denied?

Your code is trying to get a new MediaStream using the default video input device (with videoSource: true), which is already being used by your first Publisher initialization. Probably your device is not allowing you to do that, and that’s why you get the ACCESS DENIED error. To sum up, I don’t think your switchCam method is actually getting a different video feed. You must pass as videoSource other video input device.

Ah so this:

OVUserMedia = OV.getUserMedia({
audioSource: false,
videoSource: VIDEO DEVICe ID TO SWITCH TO
}).then(mediaStream => {

So i provide it with the device id i want to use?

1 Like

https://docs.openvidu.io/en/2.16.0/advanced-features/switch-camera/#by-initializing-a-new-publisher
Here you will get another methods
but i think in above code you have to filter your device name and pass different camera track
Thanks
Vipin

I think it will work.

How would i know when the user has accepted permissions on the device? I ask because before they do the getDevices() method won’t give all the device info so i think i need to hook into an event when the user has allowed permissions.

Yes you have to wait till user accept and give permission

Got it working thanks!