HTML5の<video>タグをフルスクリーン制御するjavascript

29/08/2018

html5のvideo要素をjsでの全画面制御です。
PC/スマホ/タブレット各ブラウザ,端末ios/android,でも仕様が異なったり
変わったりで毎回面倒な思いしてる気がするのでメモ代わりの備忘録としてまとめます。
IE11/android等もある程度対応してます。

サンプル

See the Pen
JzYYgx
by admin@nocebo.jp (@nocebojp)
on CodePen.

なんだか以外と全画面系でアクセスきてもらっているみたいで
サンプルもなしだと申し訳ないので
codepenデビュー&追加してみました。(2019/02)
内容は当時の物流し込んだただけなので不備とかあれば恐縮です。

PCはIE11はまだ対応する流れだと思うので それぞれベンダープレフィックスつける必要もあり
スマホとかタブレットもiOS10以降からインライ再生が可能になってりハンドラの名前が変わったり?
android4系とか入れるとかなるとさらに調整いるかもです。

android4系とか爆ぜればいいのに。
関係ないけどここ最近はIEよりむしろfirefoxが引っかかる事の方が多い気がする

youtubeの埋め込みとかだと多分apiがうまくやってくれるのか気軽なのですが、
※結果要望でyoutube/iframeになりました。が
とりあえず要件自体は満たして動いてたと思います。(2018年頃ぐらい)

今回はビデオのサムネイルをclick,touchstartしたら
videoがフルスクリーンになり全画面を解除したら
非表示、再生停止にするという内容でした。

基本の要素(videoタグとjsで要素取得)

[html] video要素

<div class="video">
   <video id="video" preload="auto">
     <source src="sample.mp4">
   </video>
</div>

souceは昔はwebmとかも入れてたけど、最近はmp4だけで特に問題ないように思う。

[js] jsでvideo要素のDOM取得

//ビデオ要素DOMエレメント取得
this.videlm = document.getElementById("video");
//jquery利用の場合は[0]でdom要素取得できる
this.videlm = $("#video")[0];

フルスクリーンON/OFF

実際呼び出すフルスクリーンのmethod
多分下記ぐらい入れとけば大体は大丈夫なはず。
多分大体は。

[js] 全画面実行

//全画面実行
requestFullScreen(){
  if (!!this.videlm.requestFullScreen) {
    this.videlm.requestFullScreen();
  } else if (!!this.videlm.webkitRequestFullScreen) {
    this.videlm.webkitRequestFullScreen();
  } else if (!!this.videlm.webkitEnterFullscreen) {
    this.videlm.webkitEnterFullscreen();
  }else if (!!this.videlm.mozRequestFullScreen) {
    this.videlm.mozRequestFullScreen();
  }else if (!!this.videlm.msRequestFullscreen) {
    this.videlm.msRequestFullscreen();
  }
}

[js] 全画面終了

//全画面終了
exitFullScreen(){
  if (!!this.videlm.exitFullscreen) {
    this.videlm.exitFullscreen();
  } else if (!!this.videlm.cancelFullScreen) {
     this.videlm.cancelFullScreen();
  }else if (!!this.videlm.mozCancelFullScreen) {
     this.videlm.mozCancelFullScreen();
  }else if (!!this.videlm.webkitCancelFullScreen) {
     this.videlm.webkitCancelFullScreen();
  }else if (!!this.videlm.msExitFullscreen) {
     this.videlm.msExitFullscreen();
  }
}

因みにdocument自体にdocument.requestFullScreen()とかでもフルスクリーンにはなりますが
videoの再生とか停止だとかのデフォルトのUI周りが出てこないパターンが多い。
端末によると思いますがandroid等は全画面状態から終了できない(身動きとれない)
致命的な状態になります。

イベントの制約

あとスマホ(iOS)の場合は特に基本ですが、
audioとかvideoタグ等の要素操作する場合に制約があり
呼び出し元がクリック等のユーザーイベントからでないと発火しません。

全画面操作はPCでも制約がある様子かと思います。
呼び出し元はユーザーイベントである必要あり
です。

実際検証はしてない&video周りは結構ブラウザの仕様変わりそう、
で何ともですが多分アクセス時に自動でフルスクリーン表示。とかは出来ないと思う。

開始と終了とハンドラ等

今回だと
サムネクリック->フルスクリーン
フルスクリーン終了時->ビデオ止める&非表示

という流れです。

実際使用する時は多分これが良くある普通のパターンな気がする

[js] フルスクリーン開始

//サムネとか何かタップでフルスクリーン開始
startVideo(){
   this.requestFullScreen();
   if(!isiphone) $("video").show();
   //iphoneでdisplay変えると二回目の表示以降見れなくなるバグ?にあったので回避
   this.videlm.play();
   window.setTimeout(()=>{
     // "document.fullscreenElement"って状態もあったりなかったりで面倒なので自前で値入れる。
     this.state = true;
   },1000)// screenchangeの発火がブラウザ/端末事でまちまちな気がするのでdelay入れてごまかす
}

[js] screenchangeかwebkitendfullscreenでフルスクリーン終了

//フルスクリーン終了
exitVideo(){
  this.exitFullScreen();
  if(!isiphone) $("video").hide();
  //開始と同じiphoneのバグ?がでるので回避
  this.videlm.pause();
  this.state = false;
}

// addEventListener/onで書き方統一してませんが抜けた際のハンドラ。

// endfullscreenってのはwebkitだけなのかな?多分、みつけられなかっただけかもですが
this.videlm.addEventListener("webkitendfullscreen", (e)=>{
  this.exitVideo();
}, false);

// その他IEとかで対応してないのはdocumentにfullscreenchange系を一括でいい気がする。
document.onfullscreenchange = document.onmozfullscreenchange = document.onwebkitfullscreenchange = document.onmsfullscreenchange = ( e ) => {
  if(this.state) this.exitVideo();
  // start時なのかend時なのかthis.stateで判定
}

iphoneのバグ?(当時なので今は解消してるかも)

iphoneだと何故かdisplay変えると
二回目の表示以降真っ暗になったのですが
<video>fullscreen時は強制表示?なのかnoneのままでもみれたので
判定用の変数isiphone用意して回避。
で一応期待通りの動きになりました。
逆にPCとかで回避すると動画は非表示のままになってしまうのでご注意をばです。

fullscreenchange

あとfullscreenchange時の状態判定用にthis.stateがあるのですが
発火のタイミングがまちまちな気がするのでsetTimeoutでdelay入れてごまかしました。
Promiseとかの導入予定はあるっぽいですが。
どっちにしても一部だけだと思うので

CSS

/* css */
.video{
 position: fixed;
  z-index: 10000;
 display: none;
  width: 100%;
  height: 100%;
 background-color: #000;
}
.video #video{
  width: 100%;
  height: 100%;
}
/* 問題ないような気がしましたが一応つけた方がいいのかも? */
.video #video::-webkit-full-screen {
 width: 100%;
  height: 100%;
}

あとcssは
::-webkit-full-screen
とかのベンダープレフィックス付けるとかつけないとか情報のありましたが
が特に気にせず。

で問題ないように思いました。
以上です。

まとめ

という訳で以上でございます。
ここまで書いてなんですが、
特に理由がなければyoutubeが無難かと思います。

videoやaudioタグを操作すると
少し凝ったコンテンツやサイトの演出等が可能ですが、

ブラウザや端末毎のクセ・制約もあり、
他の要素の操作よりも、若干複雑かもです


javascript, web

Posted by admin