2016年4月26日火曜日

城VOLUME

firefox greasemonkey拡張

機能がなければ作ればいい.
とあるゲームに全体ボリュームの変更を行う機能をこっそり追加します.

greasemonkey拡張を導入し,下記のスクリプトをインストールすると
ゲーム画面左下にBGMとサウンドエフェクトの音量を変更するツマミが追加されます.

※作者は下記スクリプトの動作について、如何なる保証もしません.どのような損害を被っても自己責任でおねがいします.

何をしているの?
ゲームが使っているAPIをフックして,内部で呼び出しているHTMLAudioElementを特定しています.ここまでくれば後は適当なGUIを用意してやればボリューム調整機能の追加なぞさほど難しくない.
※なお,本家がボリューム調整機能を実装した際に機能が競合するかもしれないので,あくまで暫定的な機能ということで…

NOTE:
セリフと効果音毎のボリューム設定はできるの?
→できません.loopの有無でBGMとそれ以外は区別できるのですが・・・



// ==UserScript==
// @name        shiro_vol
// @namespace   defghi1977
// @description 御城プロジェクト:REのサウンドボリュームを調整します.
// @include     http://assets.shiropro-re.net/html/Oshiro.html
// @version     2
// @grant       none
// ==/UserScript==
'use strict';
(function (proto) {
  var version = '2.0';
  var keyBGM = 'defghi1977.shiro_vol.bgm';
  var keyEFC = 'defghi1977.shiro_vol.effect';
  var body = document.body;
  var audios = [
  ]; //max 11 elements
  var panel = document.createElement('div');
  panel.className = 'shiro_vol';
  var style = panel.style;
  style.position = 'absolute';
  style.top = '720px';
  style.left = '5px';
  style.fontSize = '10px';
  style.color = 'white';
  style.textShadow = '1px 1px 0 black';
  style.backgroundColor = 'rgba(0,0,0,0.5)';
  style.zInidex = 100;
  var rangeBGM = document.createElement('input');
  rangeBGM.type = 'range';
  rangeBGM.min = 0;
  rangeBGM.max = 1;
  rangeBGM.step = 0.1;
  rangeBGM.style.width = '100px';
  rangeBGM.value = localStorage.getItem(keyBGM) || 1;
  var rangeEFC = rangeBGM.cloneNode(false);
  rangeEFC.value = localStorage.getItem(keyEFC) || 1;
  panel.appendChild(document.createTextNode('城VOL v' + version));
  panel.appendChild(document.createTextNode(' BGM:'));
  panel.appendChild(rangeBGM);
  panel.appendChild(document.createTextNode('EFC:'));
  panel.appendChild(rangeEFC);
  body.appendChild(panel);
  rangeBGM.addEventListener('input', function (e) {
    localStorage.setItem(keyBGM, this.value);
    syncAll();
  });
  rangeEFC.addEventListener('input', function (e) {
    localStorage.setItem(keyEFC, this.value);
    syncAll();
  });
  var op = proto.play;
  proto.play = function () {
    if (!this._captured) {
      //console.log('is loop:' + this.loop);
      audios.push(this);
      this._captured = true;
    }
    syncAll();
    return op.apply(this, arguments);
  }
  function syncAll() {
    audios.forEach(sync);
  }
  function sync(audio) {
    audio.volume = audio.loop ? rangeBGM.value : rangeEFC.value;
  }
}) (HTMLAudioElement.prototype);

0 件のコメント:

コメントを投稿