如何对一系列声音 HTML5

发布于 2024-12-09 00:55:14 字数 833 浏览 0 评论 0原文

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

VoiceWalker 播放模式https://i.sstatic.net/wyl1J.png

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

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

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

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

I'm experimenting with porting a simple audio utility called VoiceWalker to Javascript. VoiceWalker is a tool to help people transcribe audio, and it works like this:

VoiceWalker playing patternhttps://i.sstatic.net/wyl1J.png

So the idea there is that it plays a bit, repeats it, scoots forward, plays another bit, repeats that, scoots forward, etc.

I've cobbled together a function to play a sound clip, it looks like this:

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

It's an easy proposition to come up with a list of start/stop times that match the pattern above, but there's one problem: how do I queue up my clip() calls so that one will only run after the other has stopped?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

同展鸳鸯锦 2024-12-16 00:55:14

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);
}

Make clip call itself:

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);
}
冷清清 2024-12-16 00:55:14

遵循 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 都允许您定义计算成功后“下一步做什么”。您可以编写自己的函数来执行相同的操作。

Follow the structure of other API's in JavaScript: have your clip function also take in a "what to do next" function. (More technical term: "callback"). The idea is that your clip function knows when it's done with its work, and can then call the callback at the right time.

As an example, let's say that we have a function that will slowly spell out a word to the document's body:

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)
};

When this computation finishes spelling out the word, it will call onSuccess, which is going to be our callback. Once we have spell(), we can try to use it:

var startIt = function() {
    spell("hello", afterHello);
};

var afterHello = function() {
    spell("world", afterHelloWorld);
};

var afterHelloWorld = function() {
    alert("all done!"); 
};

Try calling startIt and you'll see it do its thing.

This approach allows us to chain together these asynchronous computations. Every good JavaScript asynchronous API allows you to define "what to do next" after the computation succeeds. You can write your own functions to do the same.

风情万种。 2024-12-16 00:55:14
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.

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

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.

take a look at it here, it can be applied to an audio or video element.

痕至 2024-12-16 00:55:14

这是一个可以完成您想要的操作的模块。

它被设置为播放两秒的剪辑两次,中间有短暂的暂停,然后将起点推进半秒,再次短暂暂停,然后从新的起点播放接下来两秒,依此类推。 (您可以在顶部的属性中轻松更改这些设置)。

这段代码期望有一个 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();

Here is a module which will do what you want.

It is set up to play two seconds of the clip twice, with a short pause in between, then advance the starting point half a second, pause briefly again, and then play the next two seconds from the new starting point, and so on. (You can change these settings very easily in the properties at the top).

This code expects there to be an html element with id "debug" - I used a paragraph for this. You can delete all reference to this element if you wish. (There are four of these, the line which begins var d..., and the three lines which begin 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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文