[Swift]UIWebViewでYouTubeを見るとき、ネイティブの動画プレーヤーを閉じて、動画のURLをパースし、自前のプレーヤーで再生させるためのメモ


スクリーンショット 2015-12-05 1.01.22

UIWebViewでYouTubeを開くと、勝手にネイティブのプレーヤーが動画を再生してしまいます。それを強制的に閉じて、YouTubeの動画IDからURLをパースして、自前のプレーヤーにURLを渡して動画を再生させたいときが、きっとあるはず。そのためのメモ。

環境

Swift2.0
Xcode Version 7.1.1

ネイティブの動画プレーヤーのフルスクリーンを検知する

ネイティブの動画プレーヤーは、full screenで動画を再生します。なので、videoがフルスクリーンになった状態を検知します。

NSNotificationのUIWindowDidBecomeVisibleNotificationを使いましょう。

参考:[Swift] UIWebViewでvideoタグをクリックしたときの、Videoプレイヤーのイベントハンドリング

ネイティブの動画プレーヤーを終了させる

UIWebViewではJavaScriptが使えます。以下のように、JavaScriptで、UIWebViewが再生する動画プレーヤーを強制的に閉じましょう。ネイティブの動画プレーヤーがフルスクリーンになったタイミングで閉じるのが良いかも。


func windowDidBecomeVisible(notification: NSNotification?) {
webView.stringByEvaluatingJavaScriptFromString("Array.prototype.forEach.call(document.getElementsByTagName('video'),function(v){v.webkitExitFullscreen();});")
}

参考:YouTube などのフルスクリーンで再生される UIWebView の動画をプログラムから終了させる方法

URLからYouTubeIDをとる

以下のような感じで、今WebViewが開いているURLをとって、正規表現を使って、IDだけを抽出。

let absoluteUrl: String = webView.request!.URL!.absoluteString
let youTubeID = extractYoutubeID(absoluteUrl)


func extractYoutubeID(youtubeURL: String) -> String {
let pattern: String = "(?<=v(=|/))([-a-zA-Z0-9_]+)|(?<=youtu.be/)([-a-zA-Z0-9_]+)" let regex = try! NSRegularExpression(pattern: pattern, options: .CaseInsensitive) if let regexMatch = regex.firstMatchInString(youtubeURL, options: [], range: NSRange(location: 0, length: youtubeURL.characters.count)) { let youtubeId: String = (youtubeURL as NSString).substringWithRange(regexMatch.range) return youtubeId }

タイミングは、ネイティブの動画プレーヤーが閉じたことを検知する、UIWindowDidBecomeHiddenNotificationあたりがよいでしょうか。

参考1:Youtube Video ID From URL - Objective C
参考2:[Swift] UIWebViewでvideoタグをクリックしたときの、Videoプレイヤーのイベントハンドリング

YouTubeIDから動画のURLをパースする

YouTubeIDから動画のURLを取ってくるParserが公開されてますので、それを使いましょう。

参考1:SSYoutubeParser
参考2:HCYoutubeParser

私が困ったこと

以下のように、UIWebViewで開いているYouTubeのURLを見ていると、

let absoluteUrl: String = webView.request!.URL!.absoluteString
print(absoluteUrl)

どうも、YouTubeIDがはいったURLがうまく読み込めないときがある。
例えば、一度ある動画を見た(とあるYouTubeIDがはいったURLを読み込む)あと、別の動画(別のYouTubeIDがはいったURLを読み込む)のページに移動しても、print(absoluteUrl)すると、最初にみた動画のURLがまんま入ってたり。。。

そんなときは、とりあえずWebViewを再読み込みすることで対応している。
webView.reload()

なんかうまく説明できなかったけど、ゆるしてください。
以上。