GoogleAPIClientForRESTを使ってYouTubeをiOSで再生
はじめに
- iOSアプリでYouTube動画を再生しようとした場合に、GoogleAPIClientForRESTを使った、まとまった記事がなかったので記述
- GoogleAPIClientForRESTを使わずにAPI叩いてJSONパースしてる記事が多かった
- Googleに未ログインで取得できる情報のみに対応
- RxSwift + RxCocoa を利用
実装サンプル
- GoogleAPIClientForRESTを使わずにAPI叩いてJSONパースしてる記事が多かった
- Googleに未ログインで取得できる情報のみに対応
使うライブラリ
YouTubeiOSPlayerHelper
- 再生に使う
- メンテされてないけど、動く
- webviewを生成して、Youtube iFrame APIを実行しているだけ
-
YouTube 埋め込みプレーヤーとプレーヤーのパラメータが指定可能
GoogleAPIClientForREST
- 動画リストを取得に使う
- obj-cだけどメンテされてる (公式にはswift版なし)
- YouTube Data API (v3)をラッピングしている
- JSONパースするよりは短く記述できる
- Responseの各データが階層化されており、最初は追うのが大変
- 公式の
API Referenceを追っていくのをおすすめ
RxSwiftとRxCocoa
- TableViewに使用
Nuke
- 画像表示に利用
R.swift
- リソースのコード補完
実装
- Youtubeでsearch video した結果を表示するサンプルを元に解説
初期設定
- YouTube Data API公式の作業を始める前にを参照にYOUR_API_KEYを取得しておく
-
pod install
を実行
- YOUR_API_KEY を
YouTubeClient/Models/VideoPlaylistFactory.swift
に設定
一部解説
取得
VideoPlaylistFactory.swift
- ここはハマる箇所は少なめ。リクエストを組み立てていくだけ。
- 検索したい場合は、
GTLRYouTubeQuery_SearchList
を使う。利用したいAPIと対応したquery見つけるのに少し手間取るかも
-
apiKey
以外に、iOS限定のリクエスト制限をかけている場合APIKeyRestrictionBundleID
を設定可能
- リンク先 API キーに制限を追加するを参照
-
query
組み立ては、 公式リファレンスSearch: list を参照
-
query(withPart: "snippet")
のpartは "snippet"
を指定しないとresponseに個々のビデオ情報が含まれないので注意
-
query.type = "video"
としないとプレイリストやチャンネルも返ってくるのでご注意
- response objectはそのまま扱えず、利用したAPIにあったclassを指定する必要あり
- 今回の場合は
GTLRYouTube_SearchListResponse
- 最終的には
response.items
にてGTLRYouTube_SearchResult
を返す
YouTubeClient/Models/VideoPlaylistFactory.swift
import RxSwift
import GoogleAPIClientForREST
class VideoPlaylistFactory {
let result = BehaviorSubject<[GTLRYouTube_SearchResult]>(value: [])
func search(keyward: String = "音楽",
maxResult: UInt = 50) {
let query = GTLRYouTubeQuery_SearchList.query(withPart: "snippet")
query.q = keyward
query.type = "video"
query.maxResults = maxResult
let service = GTLRYouTubeService()
service.apiKey = "YOUR_API_KEY"
service.executeQuery(query) { (_, object, error) in
if error != nil {
self.result.onNext([])
return
}
guard let response = object as? GTLRYouTube_SearchListResponse,
let playlist = response.items else {
self.result.onNext([])
return
}
self.result.onNext(playlist)
}
}
}
リスト表示(見出し画像やタイトル)
VideoListViewController.swift
- 今回は、取得した
GTLRYouTube_SearchResult
に snippetが含まれるので、そちらからサムネイルやタイトルを表示する
-
let entity: GTLRYouTube_SearchResultSnippet = element.snippet
の部分
- 後は、cell側で
entity.title
したり、entity.thumbnails?.medium?.url
したりして、表示する
- RxCocoaのTableViewバインディングしてるので、慣れてないとわかりにくいコードかも
- 慣れるとスッキリかけて好き
- 詳しくはRxSwiftのUITableViewとのバインディングまとめ
YouTubeClient/ViewControllers/VideoListViewController.swift
// 中略
private func bindData() {
self.playlistFactory
.result
.bind(to: self.tableView.rx.items) { tableView, row, element in
guard let cell = tableView.dequeueReusableCell(
withIdentifier: R.reuseIdentifier.videoListTableViewCell,
for: IndexPath(row: row, section: 0)),
let entity: GTLRYouTube_SearchResultSnippet = element.snippet else {
return UITableViewCell()
}
cell.configure(entity: entity)
return cell
}
.disposed(by: disposeBag)
}
再生
VideoDetailViewController.swift
- webviewを生成して、Youtube iFrame APIを実行しているだけなので、iFrame APIのリファレンスが参考になる
- よく使うパラメータは
"playsinline": 1
インライン再生かと
-
YTPlayerViewDelegate
の playerViewDidBecomeReady
を実装して、ロード終わったら即再生するのも定番
YouTubeClient/ViewControllers/VideoDetailViewController.swift
// 中略
extension VideoDetailViewController {
private func loadVideo(videoId: String = "") {
let playerVars = [
"playsinline": 1
]
self.playerView.load(withVideoId: videoId,
playerVars: playerVars)
}
}
extension VideoDetailViewController: YTPlayerViewDelegate {
func playerViewDidBecomeReady(_ playerView: YTPlayerView) {
self.playerView.playVideo()
}
func playerView(_ playerView: YTPlayerView, didChangeTo state: YTPlayerState) {}
func playerView(_ playerView: YTPlayerView, didChangeTo quality: YTPlaybackQuality) {}
func playerView(_ playerView: YTPlayerView, receivedError error: YTPlayerError) {}
func playerView(_ playerView: YTPlayerView, didPlayTime playTime: Float) {}
func playerViewPreferredWebViewBackgroundColor(_ playerView: YTPlayerView) -> UIColor { return .black }
func playerViewPreferredInitialLoading(_ playerView: YTPlayerView) -> UIView? { return nil }
}
おわりに
-
GoogleAPIClientForREST
使ってみたけど、レスポンスやitemsを都度キャストする手間があるのが、もどかしい
- (リファレンスを参考に)APIのリクエスト・レスポンス構造さえ覚えちゃえば、キャストも迷わず楽になるのでおすすめ
- メンテされてないけど、動く
- webviewを生成して、Youtube iFrame APIを実行しているだけ
- obj-cだけどメンテされてる (公式にはswift版なし)
- YouTube Data API (v3)をラッピングしている
- JSONパースするよりは短く記述できる
- 公式の API Referenceを追っていくのをおすすめ
- Youtubeでsearch video した結果を表示するサンプルを元に解説
初期設定
- YouTube Data API公式の作業を始める前にを参照にYOUR_API_KEYを取得しておく
-
pod install
を実行 - YOUR_API_KEY を
YouTubeClient/Models/VideoPlaylistFactory.swift
に設定
一部解説
取得
VideoPlaylistFactory.swift
- ここはハマる箇所は少なめ。リクエストを組み立てていくだけ。
- 検索したい場合は、
GTLRYouTubeQuery_SearchList
を使う。利用したいAPIと対応したquery見つけるのに少し手間取るかも-
apiKey
以外に、iOS限定のリクエスト制限をかけている場合APIKeyRestrictionBundleID
を設定可能- リンク先 API キーに制限を追加するを参照
-
-
query
組み立ては、 公式リファレンスSearch: list を参照-
query(withPart: "snippet")
のpartは"snippet"
を指定しないとresponseに個々のビデオ情報が含まれないので注意 -
query.type = "video"
としないとプレイリストやチャンネルも返ってくるのでご注意
-
- response objectはそのまま扱えず、利用したAPIにあったclassを指定する必要あり
- 今回の場合は
GTLRYouTube_SearchListResponse
- 最終的には
response.items
にてGTLRYouTube_SearchResult
を返す
- 今回の場合は
YouTubeClient/Models/VideoPlaylistFactory.swift
import RxSwift
import GoogleAPIClientForREST
class VideoPlaylistFactory {
let result = BehaviorSubject<[GTLRYouTube_SearchResult]>(value: [])
func search(keyward: String = "音楽",
maxResult: UInt = 50) {
let query = GTLRYouTubeQuery_SearchList.query(withPart: "snippet")
query.q = keyward
query.type = "video"
query.maxResults = maxResult
let service = GTLRYouTubeService()
service.apiKey = "YOUR_API_KEY"
service.executeQuery(query) { (_, object, error) in
if error != nil {
self.result.onNext([])
return
}
guard let response = object as? GTLRYouTube_SearchListResponse,
let playlist = response.items else {
self.result.onNext([])
return
}
self.result.onNext(playlist)
}
}
}
リスト表示(見出し画像やタイトル)
VideoListViewController.swift
- 今回は、取得した
GTLRYouTube_SearchResult
に snippetが含まれるので、そちらからサムネイルやタイトルを表示する-
let entity: GTLRYouTube_SearchResultSnippet = element.snippet
の部分 - 後は、cell側で
entity.title
したり、entity.thumbnails?.medium?.url
したりして、表示する
-
- RxCocoaのTableViewバインディングしてるので、慣れてないとわかりにくいコードかも
- 慣れるとスッキリかけて好き
- 詳しくはRxSwiftのUITableViewとのバインディングまとめ
YouTubeClient/ViewControllers/VideoListViewController.swift
// 中略
private func bindData() {
self.playlistFactory
.result
.bind(to: self.tableView.rx.items) { tableView, row, element in
guard let cell = tableView.dequeueReusableCell(
withIdentifier: R.reuseIdentifier.videoListTableViewCell,
for: IndexPath(row: row, section: 0)),
let entity: GTLRYouTube_SearchResultSnippet = element.snippet else {
return UITableViewCell()
}
cell.configure(entity: entity)
return cell
}
.disposed(by: disposeBag)
}
再生
VideoDetailViewController.swift
- webviewを生成して、Youtube iFrame APIを実行しているだけなので、iFrame APIのリファレンスが参考になる
- よく使うパラメータは
"playsinline": 1
インライン再生かと
- よく使うパラメータは
-
YTPlayerViewDelegate
のplayerViewDidBecomeReady
を実装して、ロード終わったら即再生するのも定番
YouTubeClient/ViewControllers/VideoDetailViewController.swift
// 中略
extension VideoDetailViewController {
private func loadVideo(videoId: String = "") {
let playerVars = [
"playsinline": 1
]
self.playerView.load(withVideoId: videoId,
playerVars: playerVars)
}
}
extension VideoDetailViewController: YTPlayerViewDelegate {
func playerViewDidBecomeReady(_ playerView: YTPlayerView) {
self.playerView.playVideo()
}
func playerView(_ playerView: YTPlayerView, didChangeTo state: YTPlayerState) {}
func playerView(_ playerView: YTPlayerView, didChangeTo quality: YTPlaybackQuality) {}
func playerView(_ playerView: YTPlayerView, receivedError error: YTPlayerError) {}
func playerView(_ playerView: YTPlayerView, didPlayTime playTime: Float) {}
func playerViewPreferredWebViewBackgroundColor(_ playerView: YTPlayerView) -> UIColor { return .black }
func playerViewPreferredInitialLoading(_ playerView: YTPlayerView) -> UIView? { return nil }
}
おわりに
-
GoogleAPIClientForREST
使ってみたけど、レスポンスやitemsを都度キャストする手間があるのが、もどかしい
- (リファレンスを参考に)APIのリクエスト・レスポンス構造さえ覚えちゃえば、キャストも迷わず楽になるのでおすすめ
GoogleAPIClientForREST
使ってみたけど、レスポンスやitemsを都度キャストする手間があるのが、もどかしいAuthor And Source
この問題について(GoogleAPIClientForRESTを使ってYouTubeをiOSで再生), 我々は、より多くの情報をここで見つけました https://qiita.com/KazukiTanaka/items/ddfc056e6d34d3302105著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .