[iOS] YoutubeとVimeoに展開されている動画を再生する方法

はじめに

こんぬづは、弊社クラスメソッド株式会社は本日で本年の業務を終了しますが、それはさておき実家のリビングに転がっていたジンジャークッキーを食べたら辛すぎて辛い田中です。

さて本題です。最近、動画配信サービスに展開されている動画をiOSで再生する方法について調べたのでまとめます。

WKWebViewで再生する方法

動画配信サービスが生成してくれるiframeをhtmlのbodyに入れて、それをWKWebViewのloadHTMLStringの引数に加えます。

使うhtmlは以下のようなものになります。bodyのdiv要素内にiframeを入力します。

<html>
	<head>
		<style type=\"text/css\">body {background-color: transparent;color: black;}</style>
		<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes\"/>
	</head>
	<body style=\"margin:0\">
		<div>
			// !!! ここに埋め込み動画のiframeを入力する
		</div>
	</body>
</html>

Youtube

ブラウザで埋め込みたい動画のページに遷移して、iframeを取得します。

先述した通り、取得したiframeをhtml内に埋め込み、変数化します。その変数をWKWebViewのloadHTMLString内に指定することでYoutubeの動画の再生が可能になります。htmlをそのまま変数化するときは中の"\でエスケープする必要があります。

import UIKit
import WebKit

class ViewController: UIViewController {

    @IBOutlet weak var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let embedHTML = "<html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes\"/></head><body><div><iframe width=\"320\" height=\"180\" src=\"https://www.youtube.com/embed/JohoCyOiT1A\" frameborder=\"0\" gesture=\"media\" allow=\"encrypted-media\" allowfullscreen></iframe></div></body></html>"
        let url = URL(string: "https://")
        webView.loadHTMLString(embedHTML, baseURL: url)
        webView.contentMode = UIViewContentMode.scaleAspectFit
    }
}

Vimeo

手順はYoutubeと同じです。ブラウザで埋め込みたい動画のページに遷移して、紙飛行機のマークの共有ボタンからiframeを取得します。

先述した通り、取得したiframeをhtml内に埋め込み、変数化します。その変数をWKWebViewのloadHTMLString内に指定することでVimeoの動画の再生が可能になります。htmlをそのまま変数化するときは中の"、\でエスケープする必要があります。

import UIKit
import WebKit

class ViewController: UIViewController {

    @IBOutlet weak var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let embedHTML = "<html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes\"/></head><body><div><iframe src=\"https://player.vimeo.com/video/246720687\" width=\"320\" height=\"180\" frameborder=\"0\" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></div></body></html>"
        let url = URL(string: "https://")
        webView.loadHTMLString(embedHTML, baseURL: url)
        webView.contentMode = UIViewContentMode.scaleAspectFit
    }
}

ネイティブで再生する方法

Youtubeは方法がないようです。公式から提案されている方法が今回紹介したWebViewでの再生です。helperが公式から用意されてはいるものの、結局中身はWebViewで、しかもこのご時世にWKWebViewではなくUIWebViewを使っているという...。別のAndroidエンジニアの方に調べてみてもらったところ、Androidはネイティブ再生する方法が提供されている模様です。さすがGoogle。

また、未検証ではありますがこちらのライブラリを利用すると、Youtubeのネイティブ再生ができるとのウワサも聞きました。こちらについてもまた別の機会に試してブログ化するかもしれません。


VimeoはどうやらPro以上のPlanの場合、HLS形式のファイルへのリンクが提供されるようです。

そのURLをAVPlayerViewControllerなどに指定してあげれば、再生することができそうです!URLから動画を再生する方法は以下をご覧ください。

まとめ

WebViewで再生する方法を主に紹介しました。動画を自前で管理するのはなかなか難しいと思います。そんな中、アプリに動画を組み込む方法の一つとして、YoutubeやVimeoといったサービスを使ってWebViewで再生させるのはアリだと思います。

今回紹介したiframeの中には動画のidを刺すものがURLに含まれています。もしアプリ向けに動的に動画を配信したいのであれば、API側で動画のidを管理・返却し、アプリでは受け取ったidをiframeに組み込むことで実現することができます。

また話は変わりますが、WebViewの場合気になるのがやはりパフォーマンスです。例えば以下のようなUITableViewにWKWebViewをのせたUIで動画を見せる場合、WebViewのインスタンスが複数存在することになります。

実際に動かしてみたところ、目に見えって動作がカクついてしまいました。どう実現するのが良いか、答えは今のところ出ていないので宿題とさせてください。