iosswiftwkwebviewpicture-in-picture

How to detect if video is running in PiP mode inside WKWebView


I have a WKWebView which allows to enable PiP mode on videos.

The problem is that when the user "closes" the WKWebView, I have to call wkWebView.pauseAllMediaPlayback(), otherwise the sound keeps playing in the system even if I unload the WKWebView with = nil.

This works great, but if PiP is enabled I want to keep the WKWebView alive and do not call the stop media playback method.

So is there a way to detect if PiP is opened?

I thought of attaching a delegate to the player inside WKWebView, but I'm not allowed to do that:

player inside WKWebView


Solution

  • Since it doesn't seem possible from Swift side, I managed to detect PiP via Javascript.

    You have to listen to PiP enter/leave events triggered by videos in Javascript, then call your own code via a Javascript Bridge.

    Please see this answer on how to do this.

    Then you have to change the Javascript code to look like this:

        window.addEventListener('load', () => {
            var videos = document.getElementsByTagName('video');
            for (var i = 0; i < videos.length; i++) {
                videos[i].addEventListener('enterpictureinpicture', () => window.webkit.messageHandlers.iosListener.postMessage('enterpictureinpicture'), false);
                videos[i].addEventListener('leavepictureinpicture', () => window.webkit.messageHandlers.iosListener.postMessage('leavepictureinpicture'));
            }
        });
    

    This is calling your Swift code passing enterpictureinpicture or leavepictureinpicture as a message.