【问题标题】:How to remove the pause between audio tracks in Javascript如何在Javascript中删除音轨之间的暂停
【发布时间】:2016-07-09 07:39:00
【问题描述】:

我正在构建一个 javascript 游戏,我想创建一个基于声音文件 sn-ps 的背景音乐。短 mp3 文件,可将它们作为连续曲目播放。我尝试在音频文件上绑定“结束”事件处理程序,但这会导致音频片段之间出现延迟。

为了解决这个问题,我制作了一个仍然无法正常工作的 hacky 解决方案,在完成前 1 秒更改了音频。

Ebuc.manageAudio = function(){
    var listener = function (event) {
         if (this.currentTime > (this.duration - 1) && Ebuc.bgnext) {
             Ebuc.manageAudio();
             console.log("aduio");
             Ebuc.bgnext = false;
         }
         if(this.currentTime < 2){
            Ebuc.bgnext = true;
             console.log("reset");
         }
        console.log(event);
        console.log("listener active")

    };
    var color = Level.current.color;
    if(Ebuc.bgsong == null) {
        Ebuc.bgsong = new Audio('assets/sound/' + Resources.audioSetList[color].getcurrentsong());
        Ebuc.bgsong.addEventListener('timeupdate', listener, true);

    }
    else{
        Ebuc.bgsong = new Audio('assets/sound/' + Resources.audioSetList[color].getcurrentsong());
    }

    Ebuc.bgsong.play();
    Resources.audioSetList[color].next();

};

此示例运行一次,当需要将片段 2 切换到片段 3 时,循环停止。控制台记录事件侦听器会在停止之前提供 4 次日志。

Q1:为什么这个事件监听器突然消失了? Q2:链接这些音频片段是否有非 hack 解决方案。

提前谢谢你。

【问题讨论】:

    标签: javascript audio


    【解决方案1】:

    在尝试在两个短音频剪辑之间快速切换时,您将遇到的不仅仅是暂停问题,您可能还希望在两个音轨之间快速交叉淡入淡出,以防止出现任何爆音、伪影等。

    这是一个使用来自howler's github issues. 的howler 进行交叉淡入淡出的示例您可能可以使用这个示例,并保留一个加载实例队列以进行转换。我希望这会有所帮助。

    //you'll probably want this crossfade duration to be shorter.
    var crossfadeDuration = 5000,
        volume            = 0.7;
    
    var instance1, instance2, soundDuration;
    
    // Singleton helper to build similar instances
    var createHowlerInstance = function (urls, onload) {
      return new Howl({
        urls: urls,
        loop: false,
        volume: 0,
        onload: onload
      });
    };
    
    // Create "slave" instance. This instance is meant
    // to be played after the first one is done.
    instance2 = createHowlerInstance(['file2.mp3']);
    
    // Create "master" instance. The onload function passed to
    // the singleton creator will coordinate the crossfaded loop
    instance1 = createHowlerInstance(['file1.mp3'], function(){
    
      // Get the sound duration in ms from the Howler engine
      soundDuration = Math.floor(instance1._duration * 1000);
    
      (function crossfadedLoop(enteringInstance, leavingInstance){
    
        // Fade in entering instance
        enteringInstance.pos(0).play().fade(0, volume, crossfadeDuration);
    
        // Wait for the audio end to fade out entering instance
        // white fading in leaving instance
        setTimeout(function(){
    
          enteringInstance.fade(volume, 0, crossfadeDuration);
          crossfadedLoop(leavingInstance, enteringInstance);
    
        }, soundDuration - crossfadeDuration);
    
      })(instance1, instance2);
    
    });
    

    【讨论】:

    • 感谢您的回答,虽然它没有回答问题。问题在于事件监听器的延迟,简单地淡入和退出文件超出了这个模块化声音循环的目的。
    • 这不是“简单地淡入淡出”,它被称为交叉淡入淡出,它是您平滑连接不属于连续波形一部分的两段音频的方式。在您的情况下,它会非常非常短,并且会在音频文件之间平稳过渡,而不会出现您当前遇到的延迟。对于那几毫秒,这两个文件将同时播放。这可能无法回答您的第一个问题,但这绝对是实现您所要求的非黑客方式。 setTimeout(function(){...}, soundDuration - crossfadeDuration) 解决了您的延迟问题。
    • 所以当file1淡出时,file2淡入。
    【解决方案2】:

    通过在 pantalohnes 的答案中设置 timeOut 的想法,我创建了以下代码来解决差距:

    Ebuc.manageAudio = function(){
            var color = Level.current.color;
            Ebuc.bgsong = new Audio('assets/sound/' + Resources.audioSetList[color].getcurrentsong());
            Ebuc.bgsong.addEventListener("loadedmetadata",function(){
                setTimeout(Ebuc.manageAudio, (Ebuc.bgsong.duration * 1000) - 50);
                Ebuc.bgsong.play();
                console.log(Ebuc.bgsong.duration);
                Resources.audioSetList[color].next();
            });
        };
    

    50 毫秒的超时正好弥补了排序文件之间的差距。

    【讨论】:

      【解决方案3】:

      回答你的问题(虽然我看到你找到了另一个解决方案),我想我找到了你的错误:

      您第二次进入 Ebuc.manageAudio() 时,Ebuc.bgsong 已经设置好了,您只需创建一个新的音频 Ebuc.bgsong = new Audio(...) 而不将侦听器附加到它,因此您不会收到任何“时间更新”事件的通知播放第二个音频文件时发出。

      您还应该从之前播放的音频中移除监听器。

      所以,如果一切正常,我认为这应该可以解决它:

      Ebuc.manageAudio = function(){
          var listener = function (event) {
              if (this.currentTime > (this.duration - 1) && Ebuc.bgnext) {
                  Ebuc.manageAudio();
                  console.log("aduio");
                  Ebuc.bgnext = false;
              }
              if(this.currentTime < 2){
                  Ebuc.bgnext = true;
                  console.log("reset");
              }
              console.log(event);
              console.log("listener active")
      
          };
          var color = Level.current.color;
          if(Ebuc.bgsong != null) {
              Ebuc.bgsong.removeEventListener('timeupdate', listener, true);
          }
          Ebuc.bgsong = new Audio('assets/sound/' + Resources.audioSetList[color].getcurrentsong());
          Ebuc.bgsong.addEventListener('timeupdate', listener, true);
      
          Ebuc.bgsong.play();
          Resources.audioSetList[color].next();
      
      };
      

      不仅如此,我认为如果你正确地从之前播放的音频中移除监听器,你根本不需要那个 bgnext hack:

      var listener = function (event) {
          if (this.currentTime > (this.duration - 1)) {
              Ebuc.manageAudio();
              console.log("aduio");
          }
          console.log(event);
          console.log("listener active")
      };
      
      Ebuc.manageAudio = function () {
          var color = Level.current.color;
          if (Ebuc.bgsong != null) {
              Ebuc.bgsong.removeEventListener('timeupdate', listener, true);
          }
          Ebuc.bgsong = new Audio('assets/sound/' + Resources.audioSetList[color].getcurrentsong());
          Ebuc.bgsong.addEventListener('timeupdate', listener, true);
      
          Ebuc.bgsong.play();
          Resources.audioSetList[color].next();
      
      };
      

      让我知道这是否有效:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-18
        • 1970-01-01
        • 1970-01-01
        • 2021-10-18
        • 2023-01-29
        • 1970-01-01
        相关资源
        最近更新 更多