#PiPとは
Picture in Picture
Youtubeアプリなどで見かける小窓表示のウィンドウ
iOS9からは、Springboardレベルでこの機能を使うことができる。
https://developer.apple.com/library/prerelease/ios/samplecode/AVFoundationPiPPlayer/Introduction/Intro.html
#AVPictureInPictureController
名前の通り、ビデオに用いることが前提となっている。
##isPictureInPictureSupported() -> Bool
クラスメソッド
PiPをサポートしているかを返す。
サポートしていない場合、nilが返るためしっかり判別しないとfatal errorで落ちる
サポートは以下のようになっている
デバイス | サポート |
---|---|
iPad2 | x |
iPad Air | o |
iPad Air2 | o |
iPad Retina | x |
iPhone | x |
iPhone以外にもAir以前のiPadでは利用できないので注意
##pictureInPictureButtonStartImageCompatibleWithTraitCollection -> UIImage
UITraitCollectionを指定して戻す画像を取得する。
任意のものを設定できるわけではない。
おそらくAirPlayとかと同じでPiPをするときはこのアイコンを使えよ!というこのなのだと思われる。
余談だけど、iOS9からは画面を分割できるのでUIScreen.Mainscreen.boundsとかやると多分死ぬ
##pictureInPictureButtonStopImageCompatibleWithTraitCollection -> UIImage
さっきの矢印が逆のやつを取得する
##init?(playerLayer: AVPlayerLayer)
イニシャライザ。
AVPlayerLayerを引数としているので、これ自身にaddSubViewしたりはできない。(要するにニコニココメントみたいなのは一度レンダリングする必要あり
なおこのAVPlayerLayerはpropertyから取得することは可能(readonly)
##delegate
後述
##startPictureInPicture()
PiPが開始される(動画の開始ではないので注意)
##stopPictureInPicture()
PiPの終了を呼ぶことができる。
ただし、呼び出し元のアプリが画面上にいる必要があり
画面分割時に自分:他[PiP]
の場合はstopに成功するが
他:他[PiP]
の場合は失敗する。
画面分割時は自分のアプリさえ出ていれば他のアプリをアクティブにしていても可能。
Springboardのホーム画面などでも失敗するので注意
##pictureInPicturePossible
PiPが使える状況か判別する。
先述のisPictureInPictureSupportedで対象となっているデバイスでもBackgroundModeを指定しないとPiPは利用できないためここでもチェックは必要。
##pictureInPictureActive
PiP中かどうか
#AVPictureInPictureControllerDelegate
Delegate
基本的にはPiPを見送る時と迎える時にしか使えない
##pictureInPictureControllerWillStartPictureInPicture:
WillStart系
##pictureInPictureControllerDidStartPictureInPicture:
DiDStart系
##pictureInPictureController:failedToStartPictureInPictureWithError:
PiPが失敗した時に呼ばれる。
どういう時に失敗するか分からないが、AVPlayerLayerが偶然クラッシュしたりするとなるかもしれない。
##pictureInPictureControllerWillStopPictureInPicture:
Stop(PiPの終了)直前に呼ばれる
##pictureInPictureController:restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:
PiP終了後に呼ばれる。
#Hacks
https://twitter.com/b3ll/status/610957432278392832
OpenGL layer being rendered on top of an AVPlayerLayer inside a PIP view.
#想像
ゲーム画面をストリーミングしたものをAVPlayerに送っている
or
OpenGL textureをAVPlayerLayerにかけている
##PiP後にplayerを差し替える
PiP後にplayerLayer.playerに対して新しいAVPlayerを再セットすると真っ暗になる。
PiP前に差し替えた場合は問題ない。
##addSubLayerについて
AVPlayerLayerを引数として渡して初期化しているが、PiP後にaddSubLayerしてもPiPの窓に貼ることはできない。