tvOSのAVPlayerViewControllerはなぜこんなに使いやすいのか

iOSでは見向きもされないAVPlayerViewControllerですが、tvOSでは力の入れ方が全然違います。
やはり体験として動画視聴というのが第一になるという想定なのでしょう。結構採用しているアプリも多いです。
パッとみた感じ以下のアプリで標準プレイヤーを確認できました。

- AbemaTV
- Netflix
- DAZN
- YouTube
- dTV

結構有名なアプリも採用に至っています。
単純にぼーっとみているだけというユースケースが多いからシンプルな標準UIでも不自由しないというのもあるのかもしれませんが、実際に使ってみるとユーザが喜ぶ気の利いた機能が充実していて、さらにOSアップデートごとに新機能がモリモリ追加されてきており、今後の発展にも期待できそうな印象です。

この記事では実際どんな機能があるのか紹介していこうと思います。

# シークバーサムネイル
まずはこの目玉機能。なんとシークバーサムネイルを自動で生成してくれます。
![atvavpvc-seekbar-thumbnail.gif](https://qiita-image-store.s3.amazonaws.com/0/35008/58869fa7-616b-f1e9-b71b-7c78771abe12.gif "atvavpvc-seekbar-thumbnail.gif")


こういうのってサーバ側で1枚ペラにまとめた画像をダウンロードさせてアプリ側で切り貼りというのがよく取られる手法かと思うのですが、AVPlayerViewControllerは勝手に動画から切り取ってくれます。
自前のプレイヤーでも使えるようにAPI提供して欲しいですよね。

## シークバーサムネイル出ないんだけど？？

と、ここまで書いたあたりで実際に試してみると、tvOS11でのみ、シークバーサムネイルが出ないことに気づきました。調べてみるとなんとtvOS11からはI-FRAMEプレイリストである必要があるそうです。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">tvOS11からAVPlayerViewControllerのシークバーサムネが表示されない件、m3u8でI-FRAME指定しないとダメになったらしい。そりゃないわ。。 <a href="https://t.co/66cTLTFOhR">https://t.co/66cTLTFOhR</a></p>&mdash; ネバダ最速の鈴木 (@toshi0383) <a href="https://twitter.com/toshi0383/status/927770622935015424?ref_src=twsrc%5Etfw">2017年11月7日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

ツイートの日付からお察しの通りGMになってから気づきました。

こちらがシークバーサムネイルが出るプレイリストのサンプルです。マスタープレイリスト内で`EXT-X-I-FRAME-STREAM-INF`を使って別途iframe_index.m3u8を指定しています。

https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8

```
#EXT-X-STREAM-INF:BANDWIDTH=1924009,CODECS="mp4a.40.2, avc1.4d401f",RESOLUTION=1920x1080,AUDIO="bipbop_audio",SUBTITLES="subs"
gear5/prog_index.m3u8
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=669554,CODECS="avc1.4d401f",URI="gear5/iframe_index.m3u8"
```

配信のお話になるのでこれ以上は割愛します。

# Infoパネル
プレイヤー上で下スワイプするとInfoパネルが出てきます。何もしなければ「オーディオ」タブしか出ませんが、以下のようなメタデータを設定することで「情報」タブも出てくるようになります。
tvOS11からは、`playbackControlsIncludeInfoViews`をfalseに設定すると下スワイプしても出てこなくなります。

## AVPlayerItem.externalMetadata
`externalMetadata`のプロパティを利用して、コンテンツに関する基本的な情報を表示できます。

もともとこれだけでしたが、
- title
- description
- artwork
- genre
- rating

tvOS11から、開始、現在、終了時刻を設定すると、シークバー上に表示してくれるようになりました。
![Screen Shot 2017-11-07 at 15.24.36.png](https://qiita-image-store.s3.amazonaws.com/0/35008/04b34fdd-ddf1-d8d3-ee96-ef7a2f33d2ad.png "Screen Shot 2017-11-07 at 15.24.36.png")

`AVPlayerItem`のヘッダーにもドキュメントがありました。

```swift
    
    /*!
    	@property	externalMetadata
    	@abstract	Supplements metadata contained in the asset.
    	@discussion This property is for display purposes, and will also be published as Now Playing Info. All keys defined in AVMetadataIdentifiers.h are valid. The full set of presentable metadata varies by release. The following are displayed on tvOS:
    		 AVMetadataCommonIdentifierTitle
    		 AVMetadataCommonIdentifierDescription
    		 AVMetadataIdentifieriTunesMetadataContentRating
    		 AVMetadataIdentifierQuickTimeMetadataGenre
    	 Values are normally strings. Poster artwork can be provided with AVMetadataCommonIdentifierArtwork.
    	 These may be used to constrain and/or label the displayed time range of live and event streams:
     		 AVKitMetadataIdentifierExactStartDate
     		 AVKitMetadataIdentifierApproximateStartDate
     		 AVKitMetadataIdentifierExactEndDate
     		 AVKitMetadataIdentifierApproximateEndDate
    	 The duration that is displayed and published to Now Playing Info is modified to reflect these dates.
    	 The following are not displayed, but will be published through Now Playing Info:
    		 AVKitMetadataIdentifierExternalContentIdentifier
    		 AVKitMetadataIdentifierExternalProfileIdentifier
    		 AVKitMetadataIdentifierPlaybackProgress
    		 AVKitMetadataIdentifierServiceIdentifier
     */
    open var externalMetadata: [AVMetadataItem]
```

ちなみにここで言うratingは映画の評価とかではなく、日本で言うR18みたいな制限のことです。
https://en.wikipedia.org/wiki/Motion_Picture_Association_of_America_film_rating_system

その証拠に `"G"` とか `"PG"` といった文字列を設定するとそれっぽく表示してくれますが、 

![Simulator Screen Shot - Apple TV - 2017-11-08 at 10.48.32.png](https://qiita-image-store.s3.amazonaws.com/0/35008/367f21cb-ded5-ac8a-8013-660982e0e070.png "Simulator Screen Shot - Apple TV - 2017-11-08 at 10.48.32.png")

`"A"` や `"R18"` ではそれっぽく表示してくれませんでした。
![Simulator Screen Shot - Apple TV - 2017-11-08 at 10.49.13.png](https://qiita-image-store.s3.amazonaws.com/0/35008/b0102070-7240-2d94-6ea3-2dff696e64d1.png "Simulator Screen Shot - Apple TV - 2017-11-08 at 10.49.13.png")

使えるのか使えないのかよくわからないですね😇

## シーンごとのマーカー
チャプターごとのサムネイルとタイトルを表示し、クリックでその地点にシークすることができます。
![Screen Shot 2017-11-08 at 8.03.36.png](https://qiita-image-store.s3.amazonaws.com/0/35008/fb0c8836-a7e1-f909-ffe8-776e5fa36e47.png "Screen Shot 2017-11-08 at 8.03.36.png")

## Infoパネルのローカライズ
「情報」「オーディオ」が「Info」「Audio」と表示されてしまうアプリをよく目にしますが、デバイスの設定言語で表示するにはプロジェクトのローカライズ設定が必要です。
こちらの記事に以前まとめましたので気になる方はご覧ください。
http://qiita.com/toshi0383/items/4d98eee8395cc3fa061f

## カスタムタブ
tvOS11から、カスタムタブを追加できるようになりました。
`customInfoViewController`のプロパティを利用します。

```swift
class ViewController: AVPlayerViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        customInfoViewController = makeCustomInfoViewController()
	}

    private func makeCustomInfoViewController() -> UIViewController {
        let sb = UIStoryboard(name: "CustomInfoViewController", bundle: nil)
        let vc = sb.instantiateInitialViewController()!
        vc.title = "コメント"
        return vc
    }
}
```

![panel-comments.gif](https://qiita-image-store.s3.amazonaws.com/0/35008/c6095e57-05e5-de8c-c523-0b1d2ad4b4d6.gif "panel-comments.gif")

カスタムタブで遊びすぎないようにとのことでしたので念のため載せておきます。
![custom-info-panel-rules.png](https://qiita-image-store.s3.amazonaws.com/0/35008/dd1e1b95-261f-d24f-793e-f5ac27382eff.png "custom-info-panel-rules.png")

スクリーンの半分以上の高さにしないこと！とありますが、重要なのはこの **No taller than** の部分で、`customInfoViewController`の高さが半分以上でなければ、タブの部分と合わせて半分を超えてしまっても良い、と解釈できますね。。？審査通るかは知らないです😊
あとはボタン使うなとあるので、詳細画面に遷移させるとかはもしかして微妙。。？こちらも審査通るのかは未知数ですね。

# 次のコンテンツを提案
AVContentProposalというAPIを使うと、次に再生するコンテンツのオススメを簡単に表示することができます。
こちらはちょっと込み入った話があるので別の記事にしようと思っています。

# オーバーレイ
他にも、ちょっとしたロゴなどを表示する目的で、動画とシークバーの間に表示できるそうです。
![Screen Shot 2017-11-08 at 8.01.02.png](https://qiita-image-store.s3.amazonaws.com/0/35008/ea90b315-cae5-9a71-b27d-e357cf897b7a.png "Screen Shot 2017-11-08 at 8.01.02.png")

# まとめ
以上、AppleTVのAVPlayerViewControllerについて紹介しました。
結構機能豊富で驚きますよね。動画配信業界はいまライブ配信がトレンドで、今回AppleもHLSの仕様のレベルからこの記事で紹介したtvOSのAVKitまで、ライブ配信を意識した機能を頑張って追加してきています。今後もさらなるブラッシュアップに期待できそうなので、動向を見守っていきたいと思います。

tvOSアドベントカレンダー、明日は一旦バトンタッチして @dekatotoro による「UIFocusGuideの使い方」です！