iOSアプリにYouTube動画を埋めこんだので、その覚書です。
基本
YouTubeの公式ドキュメントを見ると、YouTube-Player-iOS-HelperというOSSを使うのを推奨されます。
基本WebViewをベースに、いい感じのサイズにしたYouTube動画を埋めこんで、コントローラーをつけるという感じです。
(公式ドキュメント)
Embed YouTube Videos in iOS Applications with the YouTube Helper Library
(わかりやすいチュートリアル)
[Swift] YouTube-Player-iOS-Helper を使って YouTube 動画を再生してみる
2020年に直面した問題
YouTube-Player-iOS-Helperなんですが、メンテナンスされていないっぽいです。
最近AppleからUIWebView完全廃止の連絡があって、WKWebViewに移行したと思うんですが、
YouTube-Player-iOS-HelperはUIWebViewを使っているので、これ使っているとReject理由になります。
(YouTube公式に対応して欲しいですが、その辺はGoogleとAppleなので、あんまり息があってない感じはします)
幸いOSSなので、有志の方がWKWebView移行したライブラリを作ってくれていて、YoutubePlayer-in-WKWebViewがあるので、こちらを使いました。
pod "YoutubePlayer-in-WKWebView", "~> 0.3.0"
サムネイル画像が自由に調整できない問題
で、ここから実装にあたって苦労したこと。
サムネ画像をバーンってやっぱ表示したかったんですけど、
最初200*200ぐらいでつくろうとしたら、トリミングされた形で表示されました。
YouTubeのサムネイル画像は、下記のサイズで提供されるみたいです。
- 高クオリティ(480x360) ※ width x height
- 中クオリティ(320x180)
- 標準クオリティ(120x90)
- HQ動画の標準クオリティ(640x480)
- FULLHDのクオリティ(1920x1080)
基本iPhoneのサイズを意識すると、中クオリティ or 標準クオリティが多いでしょうか。
(iPadが入ってくると、それ以上のサイズもあるかと思われます)
このサイズに合っていないと、それより一つ大きいサイズのサムネをとってきて、よしなにトリミングするっぽいです。
YouTube-Player-iOS-Helper(から派生したYoutubePlayer-in-WKWebView)だと、
たとえば400x200のViewに中クオリティ(320x180)を引き伸ばして表示、みたいなことはできない模様です。
パラメーターが効かない問題
load(withPlaylistId:playerVars:)
のplayerVarsでプレイヤーを制御するパラメーターが色々指定できるんですが、
実際やってみると想定どおり調整できませんでした。
まずautoplay
は効かなかったです。
アプリ側のライフサイクルとかもあんのかな? と思ってますが、ちょっと謎です。
iv_load_policy
(動画アノテーション)も効かなかったですね。
(動画アノテーション:動画の上に出るクリック可能な文字)
playsinline
/controls
は効きました。
modestbranding
(YouTubeロゴ非表示)は効かなかったんですが、
メソッドをload(withPlaylistId:)
にするとなぜかYouTubeロゴが非表示になりました。
この辺の挙動はOSS内部の問題なのか、API側の問題なのか謎です。
autoplayが効かない問題
よくドキュメント読んでみたら、モバイルではautoplayが効かない可能性があることが書かれてました。
SafariだとAppleの思想的にできないようにされている模様です。
WKYTPlayerViewのWebViewは、
configuration.allowsInlineMediaPlayback = YES;
このプロパティがtrueにしてあって、autoplayイケるように思ったんですが、ダメでした。
どうしてもautoplayを実現したいなら、下記のワークアラウンドがあります。
let videoID = "xxxxxxx"
let youtubePlayer = WKYTPlayerView()
youtubePlayer.delegate = self
youtubePlayer.load(withVideoId: videoID)
// WKYTPlayerViewDelegate - データのロード完了後のDelegateメソッド
func playerViewDidBecomeReady(_ playerView: WKYTPlayerView) {
playerView.playVideo()
}