質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.90%

IEでサウンドの遅延が発生する

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 968

kina9876

score 8

IEで音の遅延がないようにしたい

Howler.jsを使い、IEでサウンドの再生をさせていますが、短い時間に大量の音がなると遅延が発生します。
Chrome,Firefoxでは発生せずIEでのみ発生します。
IEのバージョンは11です。

該当のソースコード

公式から出ているspiriteサンプルを変更し、キーボードで連続再生出来るようにしたコードです。
Z,X,C,Vがそれぞれspriteされた音源を連続で10回鳴らすように指定しました。

/*!
 *  Howler.js Audio Sprite Demo
 *  howlerjs.com
 *
 *  (c) 2013-2017, James Simpson of GoldFire Studios
 *  goldfirestudios.com
 *
 *  MIT License
 */

// Cache references to DOM elements.
var elms = ['waveform', 'sprite0', 'sprite1', 'sprite2', 'sprite3', 'sprite4'];
elms.forEach(function(elm) {
  window[elm] = document.getElementById(elm);
});

/**
 * Sprite class containing the state of our sprites to play and their progress.
 * @param {Object} options Settings to pass into and setup the sound and visuals.
 */
var Sprite = function(options) {
  var self = this;

  self.sounds = [];

  // Setup the options to define this sprite display.
  self._width = options.width;
  self._left = options.left;
  self._spriteMap = options.spriteMap;
  self._sprite = options.sprite;
  self.setupListeners();

  // Create our audio sprite definition.
  self.sound = new Howl({
    src: options.src,
    sprite: options.sprite
  });
  // Setup a resize event and fire it to setup our sprite overlays.
  window.addEventListener('resize', function() {
    self.resize();
  }, false);
  self.resize();

  // Begin the progress step tick.
  requestAnimationFrame(self.step.bind(self));
};
Sprite.prototype = {
  /**
   * Setup the listeners for each sprite click area.
   */
  setupListeners: function() {
    var self = this;
    var keys = Object.keys(self._spriteMap);
    keys.forEach(function(key) {
      window[key].addEventListener('click', function() {
        self.play(key);
      }, false);
    });
  },

  /**
   * Play a sprite when clicked and track the progress.
   * @param  {String} key Key in the sprite map object.
   */
  play: function(key) {
    console.log("play");
    var self = this;
    var sprite = self._spriteMap[key];

    // Play the sprite sound and capture the ID.
    var id = self.sound.play(sprite);

    // Create a progress element and begin visually tracking it.
    var elm = document.createElement('div');
    elm.className = 'progress';
    elm.id = id;
    elm.dataset.sprite = sprite;
    window[key].appendChild(elm);
    self.sounds.push(elm);

    // When this sound is finished, remove the progress element.
    self.sound.once('end', function() {
      var index = self.sounds.indexOf(elm);
      if (index >= 0) {
        self.sounds.splice(index, 1);
        window[key].removeChild(elm);
      }
    }, id);
  },

  /**
   * Called on window resize to correctly psotion and size the click overlays.
   */
  resize: function() {
    var self = this;
    // Calculate the scale of our window from "full" size.
    var scale = window.innerWidth / 3600;

    // Resize and reposition the sprite overlays.
    var keys = Object.keys(self._spriteMap);
    for (var i=0; i<keys.length; i++) {
      var sprite = window[keys[i]];
      sprite.style.width = Math.round(self._width[i] * scale) + 'px';
      if (self._left[i]) {
        sprite.style.left = Math.round(self._left[i] * scale) + 'px';
      }
    }
  },

  /**
   * The step called within requestAnimationFrame to update the playback positions.
   */
  step: function() {
    var self = this;

    // Loop through all active sounds and update their progress bar.
    for (var i=0; i<self.sounds.length; i++) {
      var id = parseInt(self.sounds[i].id, 10);
      var offset = self._sprite[self.sounds[i].dataset.sprite][0];
      var seek = (self.sound.seek(id) || 0) - (offset / 1000);
      self.sounds[i].style.width = (((seek / self.sound.duration(id)) * 100) || 0) + '%';
    }
    requestAnimationFrame(self.step.bind(self));

    document.onkeydown = function(e){
      console.log(e.keyCode);
      switch(e.keyCode){
        //A
        case 65:
        console.log("A!");
        self.sound.play("one");
        break;
        //S
        case 83:
        self.sound.play("two");
        break;
        //D
        case 68:
        self.sound.play("three");
        break;
        //F
        case 70:
        self.sound.play("four");
        break;
        //G
        case 71:
        self.sound.play("five");
        break;
        //Z
        case 90:
        self.playtest("one");
        break;
        //X
        case 88:
        self.playtest("two");
        break;
        //C
        case 67:
        self.playtest("three");
        break;
        //V
        case 86:
        self.playtest("four");
        break;
        //Q
        case 81:
        self.sound.play("one");
        self.sound.play("two");
        self.sound.play("three");
        self.sound.play("four");
        self.sound.play("five");
        break;
        case 87:
        self.playAllTest();
        break;
      }
    }
  },

  playtest: function(name) {
    var count = 0;
    var self = this;

    var interval = setInterval(function(){
    console.log(count);
    count++;
    self.sound.play(name);
    if(count == 10){
      clearInterval(interval);
    }
  },100);
  },

  playAllTest: function() {
    var count = 0;
    var self = this;

    var inter = setInterval(function(){
      switch (count) {
        case 0:
        self.sound.play("one");
        break;
        case 1:
        self.sound.play("two");
        break;
        case 2:
        self.sound.play("three");
        break;
        case 3:
        self.sound.play("four");
        break;
        case 4:
        self.sound.play("five");
        break;
      }
      count++;
      console.log(count);
      if(count == 5) {
        clearInterval(inter);
      }
    },1000);
  }

};

// Setup our new sprite class and pass in the options.
var sprite = new Sprite({
  width: [78, 60, 62, 70, 62, 1895],
  left: [0, 342, 680, 1022, 1361],
  src: ['../../tests/audio/sound2.mp3'],
  sprite: {
    one: [0, 450],
    two: [2000, 250],
    three: [4000, 350],
    four: [6000, 380],
    five: [8000, 340],
    beat: [10000, 11163]
  },
  spriteMap: {
    sprite0: 'one',
    sprite1: 'two',
    sprite2: 'three',
    sprite3: 'four',
    sprite4: 'five',
    sprite5: 'beat',
  }
});

試したこと

別ファイルを読み込むのが原因かと思い、同じファイルを分割したのでも試してみましたが、結果は同じでした。
また、サウンドの遅延が発生するタイミングでHTTP通信のGETが走っているので、そこがネックになっているかと思い調査中ですが、今のところ原因がわかっていません。
同じPCの別ブラウザ(Chrome,Firefox)では遅延とHTTP通信は発生しません。

補足情報(言語/FW/ツール等のバージョンなど)

言語:Javascript
ライブラリ: Howler.js v2.0.3

実行環境はMacで python -m SimpleHTTPServer 8888 を使い、外部から見れるようにして、Windowsでアクセスさせています。
通信のログはこちらです。

[14/Apr/2017 15:57:22] "GET /howler.js-master/tests/audio/sound2.mp3 HTTP/1.1" 200 -
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.90%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る