これは何?
safari で、ビデオの Picture in Picture をするのに、2つのAPI
- Web 標準: Picture-in-Picture API
- webkit 独自: webkitPresentationMode
が利用できるので、その違いについて調べてみた。
とりま使い方
Picture-in-Picture API
ボタンクリックに応じて toggle するようなケースだと、以下のようなスニペットになる。
if (document.pictureInPictureEnabled) {
if (document.pictureInPictureElement) {
document.exitPictureInPicture();
} else {
videoEl.requestPictureInPicture();
}
}
- document.pictureInPictureEnabled
- Picture-in-Picture APIが使えるかどうかを返す boolean
- document.pictureInPictreElement
- PinP になっている要素があれば true
- [video element].requestPictureInPicture()
- 該当のビデオ要素を P2P 表示する
- document.exitPictureInPicture()
- P2P表示の解除
あとイベントとしてはビデオ要素に対し
- enterpictureinpicture
- leavepictureinpicture
を、それぞれ PinP になったとき/解除されたときに発火してくれる
webkitPresentationMode
PresentationMode では、 inline
, picture-in-picture
, fullscreen
と 3 つの表示モードを切り替えられる。スニペットで書くと以下のような感じ
if(
videoEl.webkitSupportsPresentationMode &&
typeof videoEl.webkitSetPresentationMode === "function"
) {
btnInline.onclick = () => {
videoEl.webkitSetPresentationMode("inline")
}
btnPinP.onclick = () => {
videoEl.webkitSetPresentationMode("picture-in-picture")
}
btnFullscreen.onclick = () => {
videoEl.webkitSetPresentationMode("fullscreen")
}
}
全て video要素に対する API となっており、
- webkitSupportsPresentationMode
- presentation mode に対応しているかを返す boolean
- webkitSetPresentationMode()
- ビデオ要素に対し、presentation mode を設定する。指定できる値は
inline
,picture-in-picture
,fullscreen
- ビデオ要素に対し、presentation mode を設定する。指定できる値は
なので、 webkitEnterFullscreen
と Picture-in-Picture API
をがっちゃんこしたような仕様となっている。
イベントに関してはモードが変化した際
- webkitpresentationmodechange
を発火してくれるので、この中で、 webkitPresentationMode
を参照してモードを判定する。スニペットで書くと、
videoEl.onwebkitpresentationmodechanged = () => {
console.log( videoEl.webkitPresentationMode )
// `inline` or `picture-in-picture` or `fullscreen`
}
といった感じ
違い
基本的な動作は一緒だが、以下の違いがある
- 対応する iOS のバージョンが違う
- fullscreen にも対応
- 仕様の紹介のところで書いたように、
picture-in-picture
以外にもfullscreen
に対応している。もちろん、 fullscreen 用途であれば webkitEnterFullscreen を使えば良いが、webkitpresentationmodechanged
で、フルスクリーンが解除されたことをイベント検知できるのは嬉しいところ( iPhone safari だと、 現状(iOS15) W3C Fullscreen API に対応していないし。あと、webkitEnterFullscreen()
を使った場合も、上のイベントは発火してくれる)
- 仕様の紹介のところで書いたように、
- iOS simulatorで Picture-in-Picture API はオフになっている
- iOS simulator だと、
document.pictureInPictureEnabled
が false を返し、この API を動かすことはできない。一方、 webkitPresentationMode であれば、メソッドを呼ぶことはできる(ただし、simulator の safari が固まってしまうので、実質的には使えない
- iOS simulator だと、
てなところ。