目次
結論
無理です!
通知センターを上から開いた場合などはまだ動画は再生されますが、アプリをバックグラウンドにした瞬間に再生が終わって音声が途切れます。
悲しいので調査内容だけでもまとめました。
YouTube をWKWebView の中に埋め込む方法は、
以前の投稿 [iOS] iOSアプリにYouTube 動画を埋め込み、インライン再生させる に書いています。
試したこと
- Background Mode とAVAudioSession を設定
- JS の Player オブジェクトを操作する
- iframe の中の video タグから情報を取得する
- ネイティブのコードでPicture in Picture
- JavaScript のコードでPicture in Picture
Background Mode とAVAudioSession を設定
アプリでバックグラウンド再生させるときの通常の手法です。
Qiita: [Swift4] バックグラウンドでオーディオ再生する などを参考に設定してみましたが、
バックグラウンド再生ができるようにはなりませんでした。
JavaScript の Player オブジェクトを操作する
Webインスペクタを使ってJavaScriptの情報を探してみます。
Webインスペクタのやり方は Qiita: Simulatorを使ってiOS版SafariのWebページの挙動をデバッグする などが参考になりそう。
iPhone の Safari のデバッグ手順として記載されていますが、シミュレータ内のWKWebView などもデバッグ可能です。
で、Webインスペクタを眺めていたら player.getApiInterface()
というメソッドがありました。
何か使えそうな情報が取得できるかもしれないので実行してみると、利用可能らしいAPI一覧が取得できました。
しかし使えそうなものはありませんでした。
["cueVideoById", "loadVideoById", "cueVideoByUrl", "loadVideoByUrl", "playVideo",
"pauseVideo", "stopVideo", "clearVideo", "getVideoBytesLoaded", "getVideoBytesTotal",
"getVideoLoadedFraction", "getVideoStartBytes", "cuePlaylist", "loadPlaylist", "nextVideo",
"previousVideo", "playVideoAt", "setShuffle", "setLoop", "getPlaylist",
"getPlaylistIndex", "getPlaylistId", "loadModule", "unloadModule", "setOption",
"getOption", "getOptions", "mute", "unMute", "isMuted",
"setVolume", "getVolume", "seekTo", "getPlayerState", "getPlaybackRate",
"setPlaybackRate", "getAvailablePlaybackRates", "getPlaybackQuality", "setPlaybackQuality", "getAvailableQualityLevels",
"getCurrentTime", "getDuration", "addEventListener", "removeEventListener", "getDebugText",
"getVideoData", "addCueRange", "removeCueRange", "setSize", "getApiInterface",
"destroy", "showVideoInfo", "hideVideoInfo", "isVideoInfoVisible", "getSphericalProperties",
"setSphericalProperties", "getVideoEmbedCode", "getVideoUrl", "getMediaReferenceTime"]
iframe の中の video タグから情報を取得する
YouTube iIFrame API はiframe の中にvideoタグが生成されます。
中身が見れないかと video タグにアクセスしましたが、CORS 制限でJavaScript からは iframe の中のDOMにはアクセスできませんでした。
ざっくり言うとYouTube のドメインからしか iframe の中にアクセスできないということかと思います。
そもそもアクセスできたとしてもその情報を使うのはYouTube の規約に引っかかりそうです🙅♂️
ネイティブのコードでPicture in Picture
切り口を変えて、Picture in Picture でずっと再生させられないかを検討しました。
Appleのドキュメントがありました。
しかしこれはAVPlayer を使って実現する機能なので、WKWebView では実現できません。
WKWebView から AVPlayer を抽出する方法もあるようですが、YouTube の規約に引っかかりそうなので採用しない方がよさそう。
JavaScript のコードでPicture in Picture
こちらはWebView が再生する動画に対してPicture in Picture の属性を付与する方法。
Appleの公式ドキュメント にやり方が載っていましたが、video エレメントに webkitSetPresentationMode を設定するという手法でした。
そもそも CORS の制限により iframe 内の videoエレメントが取得・操作できないのでこれも採用できません。
結論
無理です!
ダーティな手を使うと実現可能だとは思いますが、現状は正攻法では実現できないと思います!
もし実現方法を知っている方がいらっしゃったら、コメントしていただけるととてもありがたいです🙌
最後に
以上です。お疲れ様でした!