elektricni
elektricni

Reputation: 329

ios - Disable Youtube autoplay in WkWebView

I'm using WKWebView to open pages in Youtube. Problem is that on opening they start playing videos and go fullscreen, which is not wanted behavior. Videos are not embeded, it's whole pages with description, comments etc..

Is there a way to stop them playing?

Upvotes: 1

Views: 2808

Answers (1)

taku_oka
taku_oka

Reputation: 453

It works. Please read comments.

import UIKit
import WebKit
import RxSwift

class WebViewController: UIViewController {

    let webview: WKWebView

    init() {
        // 🌟 add config
        let config = WKWebViewConfiguration()
        config.allowsInlineMediaPlayback = true
        if #available(iOS 10.0, *) {
            config.mediaTypesRequiringUserActionForPlayback = .video
        }
        self.webview = WKWebView(frame: .zero, configuration: config)

        super.init(nibName: nil, bundle: nil)
        webview.frame = view.bounds
        subscribeURL()
    }

    private func subscribeURL() {
        self.webview.rx.url
        .shareReplay(1)
            .subscribe(onNext: { [weak self] url in
                guard let url = url else { return }
                // 🌟 Navigation Delegate can not detect transition because YouTube is Single Page Application.
                startInlinePlayApplyInterval()
            })
            .addDisposableTo(disposeBag)
    }

    private func startInlinePlayApplyInterval() {
        // 🌟 There is time rag to come out new video element so start repeat interval.
        //Useful Timer extension: http://stackoverflow.com/a/39600244/3276863
        let loop = Timer.schedule(repeatInterval: 0.2) { [weak self] timer in
            self?.applyInlinePlay { success in
                if success {
                    timer?.invalidate()
                }
            }
        }
        Timer.schedule(delay: 2) { _ in
            loop?.invalidate()
        }
    }

    private func applyInlinePlay(completion: @escaping (Bool)->Void) {
        // 🌟 add attributes 'webkit-playsinline','playsinline','controls' to video element
        let script = "(function(){var applied=document.querySelector('video').attributes.playsinline!=undefined;if(applied){return false}var videos=document.querySelectorAll('video');var attrList=['webkit-playsinline','playsinline','controls'];for(video of videos){for(attr of attrList){video.setAttribute(attr,'');}}return true})();"
        webview.evaluateJavaScript(script) { res, err in
            let isSuccessToApply: Bool = (res as? Bool) ?? false
            completion(isSuccessToApply)
        }
    }
}

Upvotes: 2

Related Questions