Issue developing native iOS client

Hello everybody,

I’m currently developing an iOS native client for openvidu starting from the already available repository that I’ve found here

I’ve solved many issues and I have a working sample of it, with one problem that happens in specific network conditions.

The connection is established without problems, I can see on both ends the incoming messages, and the outgoing media stream have no problem.

The incoming media stream is black though and there is no audio.
Fun fact: if I’m using a specific mobile connection (Tim, an italian operator) it works just fine. On anything else, wifi, other mobile connections it’s always black incoming video.

I can see the participants, their names, and all the text messages.

Any thoughts?

Thanks
Dario

Hello Dario,

I can try to help as I had these kind of issues (also with native Android app). They are usually related to the TURN server required in some network configurations (for example behind NAT).

First of all you need to test if the WebRTC stream is working from the same network as the iOS app with the OpenVidu Call web app that’s automatically installed on OpenVidu server deployment. If that’s working then the problem is most likely in the outdated iOS code.

You can try fixing this by modifying the iOS code where the RTC peer connections (local and remote) are created. Add the TURN server retrieved from the token to the iceServers array (with the credentials).

If it’s still not working tell me some info about your media server, is it installed through Docker on an AWS instance? Are you using the latest version 2.15.0 and all required ports are open? You can find this info in the documentation.

Regards,
Mihail

Hello Mihailj,

Thanks for your answer!

Here’s my join room method and where I pass the token information to the room (just like the android sdk does).

   var joinRoomParams: [String: String] = [:]
        joinRoomParams["recorder"] = "false"
        joinRoomParams["platform"] = "iOS"
        joinRoomParams[JSONConstants.Metadata] = "{\"clientData\": \"" + "\(self.participantName)" + "\"}"
        joinRoomParams["secret"] = ""
        joinRoomParams["session"] = sessionName
        joinRoomParams["token"] = token
        sendJson(method: "joinRoom", params: joinRoomParams)

The TURN credentials retrieved from openvidu are passed in the “token” attribute, and the socket url is wss://BASE_URL/openvidu without the parameters added.
It’s the same way on android and it works on that platform.

I’m going to publish the full code soon, for now where do you think I may be missing something relative to the TURN settings on the iOS client?

Thanks!

So it is working on Android - in the same network where iOS fails? That’s a bit weird but not unheard off.

What I meant is to extract the TURN server info from the token, basically parse the token URI for the ‘coturnIp’, ‘turnUsername’ and ‘turnCredential’ parameters:

wss://YOUR_SERVER?sessionId=room1&token=tok_IGtB93UbFasHbcbB&role=PUBLISHER&version=2.15.0&coturnIp=YOUR_SERVER_IP&turnUsername=YOUR_COTURN_USERNAME&turnCredential=YOUR_COTURN_CREDENTIAL

Then you need to add the TURN server details here in this array:

I can show you how I do it in my Android code that’s working, then you translate it to iOS:

[Uri uri = Uri.parse(this.token);

String turnServer = uri.getQueryParameter("coturnIp");
String turnUsername = uri.getQueryParameter("turnUsername");
String turnCredential = uri.getQueryParameter("turnCredential");

PeerConnection.IceServer iceServer = PeerConnection.IceServer.builder("stun:" + turnServer + ":3478").createIceServer();
iceServers.add(iceServer);
PeerConnection.IceServer turn =  PeerConnection.IceServer.builder("turn:" + turnServer + ":3478").setUsername(turnUsername).setPassword(turnCredential).createIceServer();
iceServers.add(turn);
PeerConnection.IceServer turn2 =  PeerConnection.IceServer.builder("turn:" + turnServer + ":3478?transport=tcp").setUsername(turnUsername).setPassword(turnCredential).createIceServer();
iceServers.add(turn2);

As you can see I’ve even replaced the STUN server with the address extracted from the token. This way you’ll get a lot of valid ICE candidates for the WebRTC connection.

I would also do the same for the local peer connection, here:

Hope that it’s clearer now and it will work for you.

Mihail

Hi,

Sadly this fix didn’t work. I was able to replicate your android code on iOS and extract the turn information, but it won’t connect at all if I don’t add also this server:

let stunServer = RTCIceServer(urlStrings: [“stun:stun.l.google.com:19302”])

and with the same problem I had before.

I’m starting to think it might be a server issue, have you ever tried the public on of openvidu?
Can you point me at what exact url secret and username does this server use?

(new code is updated on the github repo)
Thanks!

Demos server has this configuration:

URL: https://demos.openvidu.io/
SECRET: MY_SECRET

Hi Micael,

I can confirm that my iOS client is working with the Openvidu Call Demo, in wifi too.
Feel free to test yourself my code that I have just updated.
Honestly nothing was changed from the last version, except for using your server instead of ours.

What could be the issue on our server that affects only iOS?
Do we have to open other specific ports or does the openvidu call demo do something specific to work at best?

Bye and thanks
Dario

Amazing job!!! Well done.

We will accept the PR to the repository :wink:

Thanks Micael,

Just a couple of things before i make the PR:

  • Have you tried to build the iOS client I’ve made and make a quick test yourself? Just for double checking.
  • What kind of issue could it be with our openvidu server?

Also let me make the server init more open to edits by other users, without having to touch the VideoVM class.

Dario

Nop. We will do with the PR.

Open a new entry in the forum and provide as much information as possible about the deployment. Please test it with PC browsers, different networks, etc to have a better idea of the problem.

Hi Guys!

Any update on the iOS native client for openvidu ?

I tested this PR quickly and I couldn’t stablish a successfully videocall between iPhone iOS 13 and Chrome Browser.

You can test by your own to see if you can.

I tested the PR. We can get the images from the IOS mobile and show it in the chrome. But, for the IOS side, there is no image from the chrome side. Just pure black screen.

Yes, that’s exactly my issue. Do you have the same issue @Dario_Pacchi ?

Hi, thanks for testing my pr.

That’s the issue I’m having when I use my openvidu server. But I don’t have that problem when using the openvidu call server. (The demo)
I can see the other partecipant and he can see me.

Which server are you using?
Could be a setup issue? (Turn maybe?)

Im using our dev environment
url: https://demos.openvidu.io
secret: MY_SECRET

Hi @Dario_Pacchi ,

Collecting the information…

I’ve been working with your PR about iOS. I am able to install the app and joint to session from iPhone. After that, A chorme browser user will connect to the same session. (OpenVidu Call demo)

The issue is the iPhone user is receiving only the audio of browser user but can’t see him.
The browser user, is working fine, it’s receiving audio and video from the iPhone user.

As you said that you made it work, could you please, give me some indications to make it work?

Thank you

I am also facing same issue @CSantosM.

@Dario_Pacchi i can see that PR is not accepted yet, but i have check your PR and looks that it improved a lot of things, but unfortunately its not working for us.

I can see the stream of iPhone user in chrome browser but not able to see remote participant in iPhone.

We’ve developed an iOS native sample from scratch: