如何将一系列声音 HTML5 <audio> 声音剪辑排队以按顺序播放?

Posted

技术标签:

【中文标题】如何将一系列声音 HTML5 <audio> 声音剪辑排队以按顺序播放?【英文标题】:How can I queue a series of sound HTML5 <audio> sound clips to play in sequence? 【发布时间】: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() 呼叫排队,以便一个只会在另一个停止后运行?

【问题讨论】:

【参考方案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();

【讨论】:

以上是关于如何将一系列声音 HTML5 <audio> 声音剪辑排队以按顺序播放?的主要内容,如果未能解决你的问题,请参考以下文章

html5网页播放声音

HTML5 Web Audio API给网页JS交互增加声音效果

HTML5 Web Audio API给网页JS交互增加声音效果

HTML5 audio 如何实现播放多个MP3音频

HTML5 <audio> 中断移动音乐(Spotify,...)

录制使用 javascript 播放的声音