как получать уведомления об изменениях состояния WKMediaPlaybackState

#ios #swift #webview #wkwebview #vimeo-player

Вопрос:

Как добавить наблюдателя, который выполняет обратный вызов, когда изменяется значение WKMediaPlaybackState веб-представления

Я пытаюсь внести некоторые изменения, когда видео vimeo в веб-представлении приостановлено

это мой код

 @IBOutlet weak var vimeoVideoPlayer: WKWebView!

func buildVimeoVideoPlayer(with video: Video) {
    let url = URL(string: "https://player.vimeo.com/video/(video.id)")!
    let requestObj = URLRequest(url: url)
    vimeoVideoPlayer.load(requestObj)
    vimeoVideoPlayer.contentMode = UIView.ContentMode.scaleAspectFit
    vimeoVideoPlayer.configuration.allowsAirPlayForMediaPlayback = true
    vimeoVideoPlayer.configuration.allowsInlineMediaPlayback = true
    vimeoVideoPlayer.configuration.allowsPictureInPictureMediaPlayback = true
    
    vimeoVideoPlayer.navigationDelegate = self
    vimeoVideoPlayer.scrollView.isScrollEnabled = false

    vimeoVideoPlayer.requestMediaPlaybackState { mediaState in
            switch mediaState {
            case .paused:
                print("the video was Paused")
            case .playing:
                print("the video is playing")
            case .suspended:
                print("the video is suspended")
            default:
                break
            }
    }
}
 

на данный момент я использую функцию requestMediaPlaybackState, но она запускается только один раз

Ответ №1:

Вы можете наблюдать за состоянием видеоплеера непосредственно из java-скрипта, и для этого вам следует добавить video в объект необходимые прослушиватели событий, а затем опубликовать состояние в native через webkit.messageHandlers :

 webView.configuration.userContentController.add(self, name: "playbackMessageHandler")

let js = """
    function onPlaybackState(playbackState) {
        const { webkit: { messageHandlers: { playbackMessageHandler } } } = window;
        playbackMessageHandler?.postMessage({ playbackState });
    };

    window.addEventListener('load', (event) => {
        const video = document.querySelector('video');
        video?.addEventListener('play', (event) => onPlaybackState('playing'));
        video?.addEventListener('pause', (event) => onPlaybackState('paused'));
        video?.addEventListener('suspend', (event) => onPlaybackState('suspended'));
    });
"""

let script = WKUserScript(source: js, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
webView.configuration.userContentController.addUserScript(script)

webView.load(...)

...

extension ViewController: WKScriptMessageHandler {
    
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        guard let body = message.body as? [String : String], let playbackState = body["playbackState"] else { return }
        print(playbackState)
    }   
}