サーバの負荷に応じて加速するマリオBGMプレイヤー(html5<audio>)


こんにちは、エイチーム引越し侍の中川です。
「仕事をしながら、常に直感的にサーバの負荷状況を把握していたい」
今回はそんな要望を実現してみました。

概要

[1]サーバのロードアベレージを返すAPIと、
[2]HTML5のAudioタグで、
サーバの負荷に応じて再生速度を変えながら音楽が再生されるようにしました。
まずはこちらをご覧ください↓
https://youtu.be/u14rl3wgVSs

背景(こじつけ)

  • 日頃、直感的にサーバの負荷状況を知りたい
  • 職場の非エンジニアも知りたい
  • 視覚は気が散るのでそれ以外の何か
  • 味覚、嗅覚→負荷上がると臭くなる→実現難しい、触覚→負荷上がると椅子にビリビリ...→いや難しい
  • 「音」なら、PCのファンやエアコンの稼働音のように、鳴っていても日頃慣れて忘れることができる

音楽再生側

html5とjsで実装しました。
ちなみに、これはどこかのサーバに置かずローカルにあってもいいです。
以下の記述のあるhtmlとBGMの音データが同じ階層にあればOK。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Load Average Player</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
  audio = document.getElementById("bgm");
  audio.playbackRate = 1;
  document.getElementById("bgm").play();

  function checkLA() {
    // APIを呼ぶ
    $.ajax({
      type:"post",
      url:"/getLa.php",
      data: {
      },
      contentType: 'application/json',
      dataType: "json",
      success: function(data) {
        $('#current_la').text(data.la);
        // テンポの変わり具合をちょっと調整
        if (data.la < 0.3) {
          document.getElementById("bgm").playbackRate = 1+(data.la/2);
        } else {
          document.getElementById("bgm").playbackRate = 1+(data.la);
        }
      }
    });
  }
  setInterval(checkLA,1000);

  audio.loop = true;
});
</script>
</head>
<body>
  <div>load average: <span id="current_la">0</span></div>
  <hr/>
  <div id="content">
    <audio id="bgm">
      <source src="bgm.mp3">
    </audio>
  </div>
</body>
</html>

1.html5のaudioタグ

まずこれですね。

<audio id="bgm">
  <source src="bgm.mp3">
</audio>

ほとんどimgタグみたいな感覚で使えます。ソースのあるサーバにmp3データを置いておいて、
src="hoge.mp3"って具合に指定するだけ。

2.ajaxでAPIたたく

まあ、これは、いいでしょう。

3.曲の再生速度を変える

document.getElementById("bgm").playbackRate = 1+(data.la);

再生速度変えるのもとっても簡単、そう、html5ならね(笑)
playbackRate が1なら100%の再生速度です。今回はlaの値を足してます。
今回やってみてすげーと思ったのは、chromeの場合しか試してないですが、
再生速度あげてもピッチが変わらないんですよね。いわゆる早送りでキュルキュル・・・と
高い音になったり、反対にスローモーションで低い巨人の声みたいになったり、
普通に再生速度変えるだけだと周波数が変わることになるのでピッチ変わっちゃうはずなんですけど
ちゃんとピッチそのままでテンポだけが変わってました。すごい。
これ各ブラウザ調べてみたいです。

4.1秒ごとにAPIをたたく

setInterval(checkLA,1000);

1000ミリ秒を指定。

5.繰り返し再生させる

audio.loop = true;

最後まで再生したときに繰り返すかどうか。今回の用途では繰り返しです。

API側

<?php
date_default_timezone_set('Asia/Tokyo');
$la = sys_getloadavg();
$json_array = array(
  'la' => $la[0],
);
header("Content-Type: text/javascript; charset=utf-8");
echo json_encode($json_array);
?>

phpでロードアベレージ取得する関数あるんですね。
今回特にパラメータ受け取ることもないので、その関数の値をjsonで返してるだけです。

やってみて

いったん、イメージしてた通りのものはできました。
閾値超えたらマリオで100秒切った時みたいにしてみたいです。

実際問題、職場で音楽流すわけにはいかないけど、とりあえず満足(笑)!