2011-10-09 30 views
5

Tôi đang thử nghiệm với việc chuyển một tiện ích âm thanh đơn giản có tên là VoiceWalker sang Javascript. VoiceWalker là một công cụ để giúp mọi người ghi lại âm thanh, và nó hoạt động như thế này:Tôi làm cách nào để xếp hàng loạt các clip âm thanh HTML5 <audio> âm thanh để phát theo trình tự?

VoiceWalker playing patternhttp://i.imgur.com/rafgl.png

Vì vậy, ý tưởng đó là nó đóng một chút, lặp đi lặp lại nó, scoots về phía trước, đóng chút khác, lặp đi lặp lại rằng, scoots mong vv

tôi đã gom góp một chức năng để chơi một clip âm thanh, nó trông như thế này:

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

đó là một đề xuất dễ dàng để đưa ra một danh sách các start/stop lần phù hợp với ở trên, nhưng có một vấn đề: làm cách nào để xếp hàng các cuộc gọi clip() của tôi để cuộc gọi đó chỉ chạy sau khi cuộc gọi khác dừng lại?

Trả lời

5

Thực hiện theo cấu trúc của API khác trong JavaScript: có chức năng clip của bạn cũng có chức năng "cần làm gì tiếp theo". (Thuật ngữ kỹ thuật khác: "gọi lại"). Ý tưởng là chức năng clip của bạn biết khi nào nó được thực hiện với công việc của nó, và sau đó có thể gọi lại cuộc gọi vào đúng thời điểm.

Như một ví dụ, giả sử rằng chúng ta có một chức năng mà sẽ từ từ đánh vần một từ để cơ thể của tài liệu:

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

Khi tính toán này kết thúc đánh vần ra từ đó, nó sẽ gọi onSuccess, đó sẽ là cuộc gọi lại của chúng tôi. Một khi chúng ta có chính tả(), chúng ta có thể cố gắng sử dụng nó:

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

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

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

Thử gọi startIt và bạn sẽ thấy nó làm điều này.

Cách tiếp cận này cho phép chúng tôi kết hợp các tính toán không đồng bộ này với nhau. Mỗi API không đồng bộ JavaScript tốt cho phép bạn xác định "phải làm gì tiếp theo" sau khi tính toán thành công. Bạn có thể viết các chức năng của riêng bạn để làm như vậy.

+0

Cảm ơn bạn, cuối cùng tôi đã hiểu cách thực hiện mọi thứ không đồng bộ trong Javascript. –

6

Hãy clip gọi riêng của mình:

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

hãy nhìn vào nó here, nó có thể được áp dụng cho một yếu tố âm thanh hoặc video.

0

Đây là mô-đun sẽ thực hiện những gì bạn muốn.

Nó được thiết lập để chơi hai giây của clip hai lần, với một khoảng dừng ngắn ở giữa, sau đó tiến điểm khởi đầu nửa giây, tạm dừng một thời gian ngắn nữa, và sau đó chơi tiếp theo hai giây từ điểm xuất phát mới, v.v. (Bạn có thể thay đổi các cài đặt này rất dễ dàng trong các thuộc tính ở trên cùng).

Mã này dự kiến ​​sẽ có phần tử html có id "gỡ lỗi" - tôi đã sử dụng một đoạn cho việc này. Bạn có thể xóa tất cả tham chiếu đến phần tử này nếu muốn. (Có bốn trong số này, dòng bắt đầu var d ..., và ba dòng bắt đầu 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(); 
Các vấn đề liên quan