【问题标题】:How can I queue a series of sound HTML5 <audio> sound clips to play in sequence?如何将一系列声音 HTML5 <audio> 声音剪辑排队以按顺序播放?
【发布时间】:2011-10-09 03:51:15
【问题描述】:

我正在尝试将一个名为 VoiceWalker 的简单音频实用程序移植到 Javascript。 VoiceWalker 是一个帮助人们转录音频的工具,它的工作原理如下:

http://i.imgur.com/rafgl.png

所以这里的想法是它播放一点,重复它,向前移动,再播放一点,重复,向前移动,等等。

我拼凑了一个播放声音片段的函数,它看起来像这样:

function clip(audio, start, stop){
    audio.currentTime = start;
    audio.play();
    int = setInterval(function() {
        if (audio.currentTime > stop) {
            audio.pause();
            clearInterval(int);
        }
    }, 10);
}    

提出与上述模式匹配的开始/停止时间列表是一个简单的建议,但有一个问题:我如何将我的 clip() 呼叫排队,以便一个只会在另一个停止后运行?

【问题讨论】:

    标签: javascript audio html5-audio


    【解决方案1】:

    clip 调用自己:

    function clip(audio, start, stop){
        audio.currentTime = start;
        audio.play();
        int = setInterval(function() {
            if (audio.currentTime > stop) {
                audio.pause();
                clearInterval(int);
                // Play it again, 2 seconds further.
                clip(audio, start + 2, stop + 2);
            }
        }, 10);
    }
    

    【讨论】:

      【解决方案2】:

      遵循 JavaScript 中其他 API 的结构:让您的剪辑函数也包含“下一步做什么”函数。 (更专业的术语:“回调”)。这个想法是你的剪辑函数知道它什么时候完成它的工作,然后可以在正确的时间调用回调。

      举个例子,假设我们有一个函数会慢慢地向文档的正文拼出一个单词:

      var spell = function(word, onSuccess) {
          var i = 0;
          var intervalId = setInterval(function() { 
                          if (i >= word.length) { 
                              clearInterval(intervalId);
                              onSuccess();
                          } else {
                              document.body.appendChild(
                                  document.createTextNode(word.charAt(i)));
                              i++;
                          }
                      }, 100)
      };
      

      当这个计算完成拼写单词时,它会调用 onSuccess,这将是我们的回调。一旦我们有了spell(),我们就可以尝试使用它了:

      var startIt = function() {
          spell("hello", afterHello);
      };
      
      var afterHello = function() {
          spell("world", afterHelloWorld);
      };
      
      var afterHelloWorld = function() {
          alert("all done!"); 
      };
      

      尝试调用 startIt,你会看到它完成了它的工作。

      这种方法允许我们将这些异步计算链接在一起。每个好的 JavaScript 异步 API 都允许您在计算成功后定义“下一步做什么”。您可以编写自己的函数来做同样的事情。

      【讨论】:

      • 谢谢,我终于明白如何在Javascript中异步做事了。
      【解决方案3】:
      var count = 1;  //initialize and set counter
      var clipstart = [0,10,20,30,40,50,60]; //initialize and set array of starting points
      var clipend   = [5,15,25,35,45,55,65]; //initialize and set array of ending points
      var clip = document.getElementById('clip'); //the clip you want to work with
      var end; //initialize the current end point
      var start; //initialize the current start point
      
      function stop(){ //function to check if the clip needs to be stopped and asks for next track
        if(clip.currentTime >= end){
          clip.pause(); //pause playback
            //if it's not on the 2 iteration, and the there are still cues left ask for next track.
            if(!(count == 1 && clipstart.length == 0)){ 
                skip();
            }
        }
      }
      
      function play(){ //skip to start and play
        clip.currentTime = start;
        clip.play();
      }
      
      function skip(){ //sets the start and end points
        count++;
        if(count == 2){
          count = 0;
          start = clipstart.shift();
          end = clipend.shift();
        }  
        play();
      }
      
      skip();
      clip.addEventListener('timeupdate', stop); //listens for if the clip is playing, and if it is, every second run the stop function.
      

      看看here,它可以应用于音频或视频元素。

      【讨论】:

        【解决方案4】:

        这是一个可以做你想做的事情的模块。

        设置为播放两秒的剪辑两次,中间有一个短暂的停顿,然后前进起点半秒 strong>,再次暂停,然后从新起点开始播放下一个两秒,以此类推。 (您可以在顶部的属性中非常轻松地更改这些设置。

        这段代码需要一个 id 为“debug”的 html 元素——我为此使用了一个段落。如果您愿意,可以删除对此元素的所有引用。 (其中有四个,以 var d... 开头的行和以 d.innerHTML... 开头的三行。

        var VOICEWALKER = (function () {
        // properties
        var d = document.getElementById("debug");
        var audio = document.getElementsByTagName('audio')[0];
        var start = 0;
        var stop = 2;
        var advanceBy = 0.5;
        var pauseDuration = 500; // milliseconds between clips
        var intv; // reference to the setInterval timer
        var clipCount = 0; // how many times we have played this part of the clip
        var clipMax = 2; // how many times we shall play this part of the clip
        
        // methods
        var pauseFinished = function () {
            d.innerHTML = "Pause finished";
            clip();
        };
        
        var pollClip = function () {
        
            d.innerHTML = String(audio.currentTime);
        
            if (audio.currentTime > stop) {
                audio.pause();
                d.innerHTML = "Pause";
                clearInterval(intv);
        
                clipCount += 1;
                if (clipCount === clipMax) {
                    clipCount = 0;
                    // advance clip
                    start += advanceBy;
                    stop += advanceBy;
                }
        
                // pause a little
                setTimeout(pauseFinished, pauseDuration);
            }
        
        
        };
        
        var clip = function () {
            audio.currentTime = start;
            audio.play();
            intv = setInterval(pollClip, 10);
        };
        
        var init = function () {
            audio.addEventListener('canplaythrough', clip, false);
        };
        
        return {
            init : init
        };
        }());
        
        VOICEWALKER.init();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-12-21
          • 2011-01-03
          • 1970-01-01
          • 2012-03-09
          相关资源
          最近更新 更多