0

In my app(audio base app), i'm playing remote audio.

before start playing i set following category

AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [])

so while i'm playing audio, i also play vimeo video in WKWebView which cause audio interrupt. how to avoid this behaviour?

<!DOCTYPE html>
        <html>
        <body>
        <style type="text/css">
        body, html {width: 100%; height: 100%; margin: 0; padding: 0;background:black}
        .main {position: absolute;top: 0; left: 0; right: 0; background-color: #101010;height:100%;}
        .main iframe {display: block; width: 100%; height: 100%; border: none;}
        </style>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
        <script src="https://player.vimeo.com/api/player.js"></script>
        <div class="main">
        <iframe src=\(url)></iframe>
        </div>

        <script src="https://player.vimeo.com/api/player.js"></script>
        <script>
        var iframe = document.querySelector('iframe');
        var player = new Vimeo.Player(iframe);

        player.on('play', function() {
        window.webkit.messageHandlers.play.postMessage("play")
        });

        player.on('pause', function() {
        window.webkit.messageHandlers.pause.postMessage("pause")
        });

        player.on('ended', function(data) {
        window.webkit.messageHandlers.ended.postMessage("ended")
        });

        player.on('bufferstart', function(data) {
        window.webkit.messageHandlers.bufferstart.postMessage("bufferstart")
        });

        player.on('bufferend', function(data) {
        window.webkit.messageHandlers.bufferend.postMessage("bufferend")
        });

        Promise.all([player.getVideoWidth(), player.getVideoHeight()]).then(function(dimensions) {
        window.webkit.messageHandlers.dimensions.postMessage(dimensions)
        });

        player.getDuration().then(function(duration) {
            window.webkit.messageHandlers.duration.postMessage(duration);
        });

        player.ready().then(function () {
        player.setVolume(1)
        window.webkit.messageHandlers.ready.postMessage("ready");
        });

        function play() {
        player.play();
        }

        function pause() {
        player.pause();
        }

        function destroy() {
        player.destroy();
        }

        </script>

        </body>
        </html>
SPatel
  • 4,768
  • 4
  • 32
  • 51
  • You are using the wrong category - try `AVAudioSessionCategory.ambient` instead. – Rog Jan 24 '20 at 13:35

1 Answers1

3

The interruption happens because WKWebview sound is handled by different process and a separate AVAudioSession. The WKWebview AVAudioSessionCategory category will switch to .playback while the sounds is playing either through <audio> or <video> tags (or its javascript counterparts). This must be the underlying mechanism that your vimeo playback uses (otherwise the interrupts would not occur).

There are 2 main routes you can go:

1) If you're ok with your main app sounds(not the WKWebView ones) mixing with any other iOS sounds (like the iPod music playback) then go with @Rog 's suggestion from the comment to use .ambient for your main app audiosession category. (This will also cause your app main audio session not to emit sound while the hardware silent switch is in off position).

2) A more flexible but requiring careful timing handling is to additionally set .mixWithOthers options for your main app audiosession .playback category. You would remove .mixWithOthers once you detect WKWebView is done playing it's own sound. From user perspective it would appear as your app is using .playback all the time.

I covered somewhat related topic in my answer here

Kamil.S
  • 5,205
  • 2
  • 22
  • 51