こんにちは、CTOの奥田です。
最近は招待制の音声SNS「Clubhouse」が話題になったり、音声コンテンツに非常に注目が集まっていますね。
私もPodcastでラジオを始めてみました。
Anchorというアプリを使えば手軽にBGMを付けられたり、Spotifyや主要な配信サービスにも配信されて非常に便利です。
何より音声は手軽にすぐ配信できることがメリットですね。音声コンテンツの今後に期待です。
さて、今回はVideojs Panoramaについてです。
公式のデモをそのまま実装すれば動作はするのですが、ジャイロセンサーに対応させる際に少し変更が必要でしたので今回はその対処法についてご紹介します。
こちらが今回のデモです。
Table of contents
Videojs Panoramaとは
Videojs Panoramaとは、Video.JSのプラグインでVideo.JSを360度の動画に対応させるためのプラグインです。
GitHubページはこちらです。
実装する
実装方法はとても簡単です。まず必要なリソースを読み込みます。
<link href="https://vjs.zencdn.net/5.8/video-js.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/videojs-panorama@0.1.7/dist/videojs-panorama.min.css" rel="stylesheet"> <script src="https://vjs.zencdn.net/5.8/video.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r76/three.js"></script> <script src="https://cdn.jsdelivr.net/npm/videojs-panorama@0.1.7/dist/videojs-panorama.v5.min.js"></script>
次にvideo要素を配置します。.vjs-big-play-centeredで再生ボタンが真ん中に配置されます。
<video id="player" class="video-js vjs-big-play-centered" data-player controls> <source src="[Video url]" type="video/mp4"> </video>
#playerに対してvideojsを実行し、さらにpanorama()を実行するだけです。
const player = videojs("#player", {}) player.panorama({ clickToToggle: (!this.isMobile()), autoMobileOrientation: true, initFov: 100, clickAndDrag: true, NoticeMessage: (this.isMobile())? "please move your phone" : "please use your mouse drag and drop the video" });
これで簡単に3D動画になります。
ただ、このままだとページ内に複数動画を配置した際に動画がフルスクリーンでうまく機能しない時があります。
こちらは下記の通りフルスクリーンボタンを押した際にクラスを付与し、CSSで対応可能です。
if (this.isIOS()) { player.controlBar.fullscreenToggle.on("tap", () => { if (!player.isFullscreen()) { player.el_.classList.add("is-fullscreen") } else { player.el_.classList.remove("is-fullscreen") } }); }
.is-fullscreen{ z-index: 99999 !important; }
ジャイロセンサーに対応する
iOS13からジャイロセンサーに対応するための devicemotion イベントに許可が必要になっています。
そのためには DeviceMotionEvent.requestPermission() を実行する必要があるのですがこの機能自体がユーザーのクリックイベントにバインドしないと機能しません。
ページ内にボタンを設置して押してもらってから再生させるというのもいいですが再生ボタンを押した際に許可を取りたいのでボタン要素をオーバーレイします。
<button type="button" data-enable-devicemotion></button>
.c-video__wrapper [data-enable-devicemotion]{ background-color: transparent; border: none; cursor: pointer; outline: none; padding: 0; appearance: none; position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: 2; }
iOS以外の時はそのまま非表示に、iOSの時のみクリックしたら DeviceMotionEvent.requestPermission() を実行するようにします。
再生も同時にするように player.play() を同時に実行し、ボタンを非表示にします。
const edm = elements.querySelector(this.edm_name) if(edm){ if(!this.isIOS()){ edm.style.display = "none" }else{ edm.addEventListener("click",() => { this.requestDeviceMotionPermission(player) player.play() edm.style.display = "none" }) } }
最後に devicemotion イベントに canvas.handleMobileOrientation(event.data.events) をバインドするだけです。
requestDeviceMotionPermission = (player) { if ( DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === 'function') { // iOS 13+ の Safari // 許可を取得 DeviceMotionEvent.requestPermission() .then( function(permissionState) { if (permissionState === 'granted') { // 許可を得られた場合、devicemotionをイベントリスナーに追加 window.addEventListener('devicemotion', (event) => { var canvas = player.getChild('Canvas'); if(event.data){ if (canvas) canvas.handleMobileOrientation(event.data.events); } }) } else { // 許可を得られなかった場合の処理 } }) .catch(console.error) // https通信でない場合などで許可を取得できなかった場合 } else { // 上記以外のブラウザ } }
これでジャイロセンサーに対応できます。
Amazon S3に動画を置く場合
外部の動画を読み込む場合まず、video要素に crossorigin=”anonymous” を付与する必要があります。
<video id="player" class="video-js vjs-big-play-centered" data-player crossorigin="anonymous" controls> <source src="[Video url]" type="video/mp4"> </video>
また、S3に配置した動画を再生したい場合はファイルをパブリックにする以外にCross-Origin Resource Sharing (CORS)の設定が必要です。
バゲットのアクセス許可のページへ行き、
Cross-Origin Resource Sharing (CORS)の欄に下記を記述しておく必要があります。
[ { "AllowedHeaders": [ "*" ], "AllowedMethods": [ "GET" ], "AllowedOrigins": [ "*" ], "ExposeHeaders": [] } ]
これでAmazon S3の動画を読み込むことができます。
さいごに
今回はVideojs Panoramaについてご紹介いたしました。
OSの変更等で多少厄介な部分はありましたが、ドキュメントをそれほど読むことなく、意外と簡単に実装できたのに驚きました。
今後VR動画も増えてくると思いますので是非参考にしていただければと思います。