23 comments on “Guide to WebRTC with Safari in the Wild (Chad Phillips)

  1. Pingback: September 17th RealTimeWeekly #247

  2. Thanks for this Chad, currently struggling with this myself, where a portable ‘web’ app is being written..
    I’m hopeful it will creep into wkwebview soon!

  3. Thanks for detailing the issues.

    One suggestion for any future article would be including the iOS Safari limitation on simultaneous playing of multiple elements with audio present.

    This means refactoring so that multiple (remote) audio sources are rendered by a single element.

  4. The same issue I’m facing New getUserMedia() request kills existing stream track. Let’s see whether it helps me or not.

  5. iOS calling getUserMedia() again kills video display of first getUserMedia(). This is the issue I’m facing but I want to pass the stream from one peer to another peer.

  6. Thank you Chad for sharing this, I was struggling with the resolution issue on iOS and I was not sure why I was not getting the full hd streaming. Hope this will get supported soon.

  7. VP8 is a nightmare. I work on a platform where we publish user-generated content, including video, and the lack of support for VP8 forces us to do expensive transcoding on these videos. I wonder why won’t vendors just settle on a universal codec for mobile video.

  8. Great Post!
    Chad I am facing an issue with iOS Safari, The issue is listed below.
    I am using KMS lib for room server handling and calling, There wasn’t any support for Safari / iOS safari in it, I added adapter.js (shim) to make my application run on Safari and iOS (Safari). After adding it worked perfectly on Safari and iOS, but when more than 2 persons join the call, The last added remote stream works fine but the existing remote stream(s) get struck/disconnected which means only peer to peer call works fine but not multiple remote streams. Can you please guide how to handle multiple remote streams in iOS (Safari).

  9. No low/limited video resolutions: 1920×1080 not supported
    -> are you talking about IOS12 ?
    Because I’m doing 4K on IOS 12.3.1 with janus echo test with iphone XS Max (only one with 4K front cam)
    Of course if I run your script on my MBP it will say fullHD not supported -> because the cam is only 720p.

    • That may be a standard camera resolution on that particular iPhone. The larger issue has been that only resolutions natively supported by the camera have been available, leading to difficultly in reliably selecting resolutions in apps, especially lower resolutions like those used in thumbnails.

      Thankfully, this appears to be fully addressed in the latest beta of iOS 13.

  10. How many days of work I lost before find this article. It’s amazing and explain a lot the reasons of all the strange bugs in iOS. Thank you so much.

  11. Hi, i’m having issues with Safari on iOS. In the video tag, adding autoplay and playsinline doesn’t work on our Webrtc implementation.
    Obviously it works fine in any browser on any other platform.

    I need to add the controls tag, then manually go to full screen and press play.

    Is there a way to play the video inside the web page ?


  12. First of all, thanks for detailing the issues.

    This article is unique to provide many insides for WebRTC/Safari related issues. I learned a lot and applied some the techniques in our production application.

    But I had very unique case which I am struggling with right now, as you might guess with Safari. I would be very grateful if you can help me or at least to guide to the right direction.

    The case:

    We have webrtc-based one-2-one video chat, one side always mobile app (host) who is the initiator and the other side is always browser both desktop and mobile. Making the app working across different networks was pain in the neck up to recently, but managed to fix this by changing some configurations. So the issue was in different networks WebRTC was not generating relay and most of the time server reflexive candidates, as you know without at least stun provided candidates parties cannot establish any connection. Solution was simple as though it look a lot of search on google,
    (https://github.com/pion/webrtc/issues/810), we found out that mobile data providers mostly assigning IPv6 to mobile users. And when they used mobile data plan instead of local wifi, they could not connect to each other. By the way, we are using cloud provider for STUN/TURN servers (Xirsys). And when we asked their technical support team they said their servers should handle IPv6 based requests, but in practice it did not work. So we updated RTCPeerConnection configurations, namely, added optional constraints (and this optional constraints are also not provided officially, found them from other non official sources), the change was just disabling IPv6 on both mobile app (iOS and Android) and browser. After this change, it just worked perfectly until we found out Safari was not working at all. So we reverted back for Safari and disabled IPv6 for other cases (chrome, firefox, Android browsers)

    const iceServers = [ { urls: “stun:” }, { urls: [“turn:”,”turn:”,… ],
    credential: “secret”, username: “secret” } ];

    let RTCConfig;
    // just dirty browser detection
    const ua = navigator.userAgent.toLocaleLowerCase();
    const isSafari = ua.includes(“safari”) && !ua.includes(“chrome”);

    if (isSafari) {
    RTCConfig = iceServers;
    } else {
    RTCConfig = {
    constraints: { optional: [{ googIPv6: false }] }

    if I wrap iceServers array inside envelop object and optional constraints and use it in new RTCPeerConnection(RTCConfig); is is throwing error saying: Attempted to assign readonly property pointing into => safari_shim.js : 255

    Can you please help with this issue, our main customers use iPhone, so making our app work in Safari across different networks are very critical to our business. If you provide some kind of paid consultation, it is also ok for us

    Looking forward to hearing from you

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.