株式会社イロコト株式会社イロコト

Blogイロコトのブログ

  1. Home
  2. Blog
  3. BGM(音楽)をサイト内で流す際にページ遷移しても途切れない方法

BGM(音楽)をサイト内で流す際にページ遷移しても途切れない方法

2022.02.22
  • コーディング

こんにちは、コーダーのばやしです。

 

突然ですが、バックグラウンドで音楽を再生しつつ、ページ遷移を行っても再生が途切れないようにしたい時ってありますよね。(←そんな無いと思うよ。イロコト代表穂刈より。)

 

CookieやSessionStorageに再生位置を保存させて、遷移後に同じ所から再生ということも可能ですが、ページ遷移の際に処理が止まるためどうしても音声は途切れてしまいシームレスとは言えません。

 

また、近年自動再生系への締付けがきつく(特にiOS)、ユーザーによる操作を挟まないと再生すらさせてもらえないので通常であれば表題のような実装は困難です。

 

そのような場合に役に立つのが、非同期ページ遷移です。

 

非同期ページ遷移について

一般的に非同期ページ遷移というと、AjaxとpushState(History API)を活用してシームレスにページ遷移を行う、所謂Pjaxによる一連の実装の事を指す事が多いかと思いますが、本項もPjaxをベースにした話になります。

 

使用するライブラリ

非同期処理

jquery-pjaxなど様々ありますが、今回はBarba.jsを利用します。

 

古いバージョンと最新バージョン(v2)とで記述方法が変わるのでネットで情報を探す際は気をつけてください。(個人的に、コード上でBarbaと書かれている方が旧版、barbaとなっている方がv2という認識でいます。断言はしません。)本項ではv2を利用します。

 

Barba.js 公式サイト

 

音楽再生について

音声処理系において定番のライブラリであるHowler.jsを利用します。

 

各ブラウザごとの面倒な調整などもまとめて行ってくれるので、ただ音を流すだけであればかなり簡単に実装できます。

 

下記の公式サイトの下部のUsed byに錚々たる面子が列挙されている通り、ワールドワイドで多く使われているので情報も多いです。より詳細な情報を探ろうとすると殆ど英語になりますが、Google先生やDeepL先生に活躍していただけば特に問題はないです。

 

Howler.js 公式サイト

 

デモ

※音声が流れますのでご注意ください。

※再生されない場合はページ内でタップまたはクリックをしてみてください。

 

(デモページ)

 

使用楽曲:"Ethiopia Rag" (1909), by Joseph F. Lamb (Wikimedia)

 

基本的な構造

Barba.jsとHowler.jsの各ライブラリの詳細な使い方は巷に溢れていますので、表題のような実装をする際の考え方と簡単なデモコードを紹介していきます。

 

非同期遷移実装がなされていない通常のページで音声を再生した場合、ページ遷移によってJSの処理が閉じるため当然音声再生も止まってしまいます。

 

 

Barba.jsで非同期遷移する場合、現在表示されているページの指定した領域内を遷移先のページのものに差し替えます。

 

JSによって遷移先のページの情報を取得して差し替えを行うため通常のページ遷移は発生せず、最初に表示したページで実行した音声再生の処理がそのまま継続され、音声を再生し続けてくれます。

 

 

音楽再生部分(Howler.js)

Wikimediaにある適当な音源を再生してみます。


const music = new Howl({
  src: 'https://upload.wikimedia.org/wikipedia/commons/b/b8/%22Ethiopia_Rag%22_%281909%29%2C_by_Joseph_F._Lamb.mp3',
  autoplay: true,
  volume: 0.5,
  loop: true,
});
music.play();
autoplay: true
自動再生を試みることができます。
volume: 0.5
ボリュームを0〜1で設定できます。
loop: true
指定することでループ再生が出来ます。

近年のブラウザにおいては自動再生が出来ない事が多く、ユーザーの何らかのアクションが求められるため、基本的には「再生ボタンを押したら再生される」という形を推奨します。

 

非同期遷移部分(Barba.js)

今回は3ページ間を非同期遷移するように設定します。

 

HTML

<body data-barba="wrapper">
  <div class="menu">
    <ul>
      <li><a href="./index.html">PAGE01</a></li>
      <li><a href="./index_02.html">PAGE02</a></li>
      <li><a href="./index_03.html">PAGE03</a></li>
    </ul>
  </div>

  <!-- ここから切り替える内容 -->
  <main data-barba="container" data-barba-namespace="home">
    <div class="body body-01">
      <p>これはPAGE01です。</p>
    </div>
  </main>
  <!-- ここまで切り替える内容 -->
  <!-- JS読み込み -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.2.3/howler.min.js"
    integrity="sha512-6+YN/9o9BWrk6wSfGxQGpt3EUK6XeHi6yeHV+TYD2GR0Sj/cggRpXr1BrAQf0as6XslxomMUxXp2vIl+fv0QRA=="
    crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/@barba/core"></script>
  <script src="./assets/base.js"></script>
</body>

data-barba="wrapper"

bodyなどラッパー要素に指定します。

 

data-barba="container"

切り替わる要素に指定します。

 

data-barba-namespace="home"

各ページで処理を分けたい場合などに、こちらで定義します。無くても動きます。

 

JavaScript

HTML側で上記の属性を各ページに設定の上、下記のようにbarba.init();を実行すると、それだけで非同期で遷移するようになります。data-barba="container"が指定されている要素を非同期で差し替えるという動きになります。


barba.init({
  transitions: [{
    leave(data) {
      return gsap.to(data.current.container, {
        x:"100%"
      });
    },
    enter(data) {
      gsap.from(data.next.container, {
        x: "-100%"
      });
    }
  }]
});

※アニメーションはGSAPを使っています。

 

注意点

注意点として、titleタグは遷移後のページのものに自動で差し替わりますが、descriptionなど他のメタタグは差し替わらないので、差し替えるコードを書く必要があります。

 

参考サイト

参考サイト2

 

GoogleAnalyticsでアクセス解析をしている場合も調整が必要です。

 

GoogleAnalyticsにおいては基本的にはページビューを判定してアクセス計測をしていますが、Barba.jsを用いて非同期遷移にするとページビューが発生するのは初期読み込み時とリロード時のみで、正しく計測されません。GA/GTM側で、履歴の更新で判定する方式を追加する必要があります。

 

また、タイトルが1つズレて計測されるというパターンもありました。GTM側に情報を送るタイミングがBarba.jsによりtitleタグが書き換えられる前になってしまっている影響で1つ前のタイトルが計測されるというもので、情報送信タイミングをずらすことで対応可能です。

 

参考サイト

 

 

デモ

そうして出来上がったものが下記になります。

リンクを押してページを移動しても音楽が途切れないことが分かるかと思います。

 

(デモページ)

 

※音声が流れますのでご注意ください。

※再生されない場合はページ内でタップまたはクリックをしてみてください。

 

 

あとがき

今回は主に音楽をシームレスで再生することに焦点を合わせましたが、音声ではなく背景で動画を再生させそれを途切れさせないようにするなど様々な活用方法がありそうです。弊社のフィールドですと、特にアニメやゲームサイトの世界観を表現するための表現に有用と思います。

 

主にJS周りの調整で工数が通常より多くかかってしまいますが、初見時の効果は大きいと思いますので、表現方法の一手としてレパートリーに加えたいですね。

 

お読みいただきありがとうございました。

それではまた。

Contact

案件のご相談や、弊社についてのご質問など、
お気軽にご連絡くださいませ。

お問い合わせ