I'm building an app with WebRTC and it's not working in Angular 5 on iOS Safari. I use native WebRTC API, no framework.
First without Angular
To prove my point Angular is the problem, I did a WebRTC test with plain html and javascript. So I had an index.html
and a my-webrtc.js
.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebRTC Test</title>
</head>
<body>
<div>
<video id="local-video" playsinline autoplay muted></video>
<video id="remote-video" playsinline autoplay></video>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="js/my-webrtc.js"></script>
</body>
</html>
I put those two files on a TSL/SSL secured webserver. On the same server I have a basic signaling server installed. In the my-webrtc.js
there is everything: signaling, offer, answer, ice candidates and connecting the stream to the HTML elements.
For all the tests I used only the LAN just to make sure no STUN or TURN is needed.
Test results
Everything works fine in these tested situations:
- Desktop/Chrome <-> Desktop/Chrome
- Desktop/Chrome <-> Desktop/Firefox
- Desktop/Chrome <-> Desktop/Safari
- Desktop/Chrome <-> Android/Tab/Chrome
- Desktop/Chrome <-> iPhone/Safari
- Desktop/Chrome <-> iPad/Safari
- Desktop/Safari <-> iPhone/Safari
- Desktop/Safari <-> iPad/Safari
- iPad/Safari <-> iPhone/Safari
Specifications of the devices:
Desktop/Chrome
- Macbook MacOS 10.12.6
- Chrome 64.0.3282.140
Desktop/Firefox
- Macbook MacOS 10.12.6
- Firefox 58.0.1
Desktop/Safari
- Macbook MacOS 10.12.6
- Safari 11.0.3
Android/Tab/Chrome
- Samsung Galaxy Tab3 8.0 inch (SM-T310)
- Android 4.4.2
- Chrome 64.0.3282.137
iPad/Safari
- iPad mini 2 (A1489)
- iOS 11.2.5
- Safari
iPhone/Safari
- iPhone 6 (A1586)
- iOS 11.2.5
- Safari
After that I did another test leaving the adapter-latest.js
out of the index.html
and then still all the above tested situations work fine.
Now I put everything in Angular
Now I make the next step. I use Angular CLI version 1.6.3 to create a new Angular test app:
ng new webrtc-angular-test
It generates a new Angular 5.2.3 app. For signaling I need to install socket.io
:
npm install --save socket.io-client@2.0.4
For typings in typescript I add:
npm install --save @types/webrtc@0.0.22
npm install --save @types/socket.io-client@1.4.32
Then in app.component.html
I put the same as the index.html
:
<video id="local-video" playsinline autoplay muted></video>
<video id="remote-video" playsinline autoplay></video>
And in app.component.ts
I paste everything from my-webrtc.js
. I had to make some small modifications so the javascript works in typescript. I didn't import any adaptor yet.
Then building it:
ng build
And copy the content of the dist
to the same TSL/SSL secured webserver where also the signaling server runs.
Test result
It works well in these cases:
- Desktop/Chrome <-> Desktop/Chrome
- Desktop/Chrome <-> Desktop/Safari
- Desktop/Chrome <-> Android/Tab/Chrome
- Desktop/Chrome <-> Desktop/Firefox
After giving permission on iOS localStream is visible. When the RTCPeerConnection
is established the remoteStream is normal visible on iOS and almost at the same time the localStream freezes. No error messages in the console. On the Desktop side everything is normal. If two iOS devices are involved, on both side localStream freezes. This happens in these cases:
- Desktop/Chrome <-> iPhone/Safari
- Desktop/Chrome <-> iPad/Safari
- Desktop/Safari <-> iPhone/Safari
- Desktop/Safari <-> iPad/Safari
- iPad/Safari <-> iPhone/Safari
Adding the Webrtc Adapter
Then I install the webrtc-adapter
:
npm install --save webrtc-adapter@6.1.1
In app.component.ts
I put a import 'webrtc-adapter';
But things get even worse !!
Test result
It works well in these cases:
- Desktop/Chrome <-> Desktop/Chrome
- Desktop/Chrome <-> Desktop/Safari
- Desktop/Chrome <-> Android/Tab/Chrome
- Desktop/Chrome <-> Desktop/Firefox
After giving permission on iOS localStream is visible. When the RTCPeerConnection
is established the remoteStream is normal visible on iOS and almost at the same time the localStream freezes. No error messages in the console. On the Desktop side everything is normal. If two iOS devices are involved, on both side localStream freezes. This happens in these cases:
- Desktop/Chrome <-> iPhone/Safari
- Desktop/Chrome <-> iPad/Safari
LocalStream is visible on both sides, but remoteStream is not visible on both sides. The logging says peerConnection is created. Offer is send/received and answer is send/received. RemoteStream is added but not visible. No Ice Candidates are being send. RTC peer connection state is changed to 'checking'. There are no error messages. The same happens in the following cases:
- Desktop/Safari <-> iPhone/Safari
- Desktop/Safari <-> iPad/Safari
- iPad/Safari <-> iPhone/Safari
My conclusion:
I have a working WebRTC environment, just plain html with javascript. Then I put this into Angular 5 with typescript and it's not working anymore on iOS Safari. This must be a problem with Angular 5, or typescript or a dependency like zone.js.
My questions:
Do you agree with my conclusion or do I overlook something?
Who knows what is the problem and knows a solution?
Help is greatly appreciated!!
The problem that occurs after adding the
webrtc-adapter
is caused byzone.js
and is solved by adding the following line inpolyfills.ts
(if usingangular-cli
)You should add this after
import 'zone.js/dist/zone';
that's already in this file.I dropped an issue on GitHub for the main problem on iOS where localStream freezes.