2015-05-25 13 views
5

tôi là tạo ra một cây đàn piano trong trình duyệt sử dụng javascript. Để tôi chơi cùng một phím nhiều lần cùng một lúc, thay vì chỉ chơi đối tượng Audio, tôi sao chép và chơi bản sao, nếu không tôi sẽ phải chờ âm thanh kết thúc hoặc khởi động lại, mà tôi không muốn t muốn.nguồn âm thanh Cloning mà không cần phải tải về nó một lần nữa

tôi đã thực hiện một cái gì đó như thế này:

var audioSrc = new Audio('path/'); 
window.onkeypress = function(event) { 
    var currentAudioSrc = audioSrc.cloneNode(); 
    currentAudioSrc.play(); 
} 

Vấn đề là, tôi đã kiểm tra thanh tra chrome, và tôi nhận thấy rằng mỗi khi tôi sao chép đối tượng, trình duyệt tải về nó một lần nữa

enter image description here

tôi đã kiểm tra một số người muốn đạt được những điều tương tự, và nhận thấy rằng hầu hết trong số họ có cùng một vấn đề mà tôi làm, họ redownload tập tin. Ví dụ duy nhất tôi thấy có thể phát cùng một nguồn âm thanh nhiều lần cùng một lúc là SoundJs http://www.createjs.com/SoundJS

Tôi đã thử kiểm tra nguồn có thể nhưng không thể tìm ra cách thực hiện. Bất kỳ ý tưởng?


+1

Vâng tôi có thể thấy làm thế nào mà sẽ rất khó để theo dõi nếu bạn không quen với các kiến ​​trúc SoundJS. WebAudioLoader._sendComplete giải mã tệp đã nạp vào một AudioBuffer sau đó được chuyển thành _result, được xử lý trong AbstractPlugin._handlePreloadComplete bằng cách lưu nó trong hàm băm _audioSources (WebAudioPlugin mở rộng AbstractPlugin). AudioBuffer được lưu trữ này sau đó được truyền cho mỗi WebAudioSoundInstance mới và được sử dụng để tạo các nút âm thanh. Ý tưởng giống như câu trả lời được chấp nhận, lưu trữ bộ đệm âm thanh và sử dụng nó để tạo các nút âm thanh mới. – OJay

Trả lời

3

Với webAudioAPI bạn có thể làm một cái gì đó như thế:

  • Tải xuống một lần tệp qua XMLHttpRequest.
  • Nối phản ứng với một bộ đệm
  • Tạo một bufferSource mới và chơi nó trên mỗi cuộc gọi
  • dự phòng để thực hiện đầu tiên của bạn nếu webAudioAPI không được hỗ trợ (IE)

window.AudioContext = window.AudioContext||window.webkitAudioContext; 
 
if(!window.AudioContext) 
 
    yourFirstImplementation(); 
 
else{ 
 
var buffer, 
 
ctx = new AudioContext(), 
 
gainNode = ctx.createGain(); 
 
gainNode.connect(ctx.destination); 
 
var vol = document.querySelector('input'); 
 
vol.value = gainNode.gain.value; 
 
vol.addEventListener('change', function(){ 
 
    gainNode.gain.value = this.value; 
 
    }, false); 
 

 
function createBuffer(){ 
 
    ctx.decodeAudioData(this.response, function(b) { 
 
    buffer = b; 
 
    }, function(e){console.warn(e)}); 
 
    var button = document.querySelector('button'); 
 
    button.addEventListener('click', function(){playSound(buffer)}); 
 
    button.className = 'ready'; 
 
    } 
 

 
var file = 'https://dl.dropboxusercontent.com/s/agepbh2agnduknz/camera.mp3', 
 
xhr = new XMLHttpRequest(); 
 
xhr.onload = createBuffer; 
 
xhr.open('GET', file, true); 
 
xhr.responseType = 'arraybuffer'; 
 
xhr.send(); 
 

 
function playSound(buf){ 
 
    var source = ctx.createBufferSource(); 
 
    source.buffer = buf; 
 
    source.connect(gainNode); 
 
    source.onended = function(){if(this.stop)this.stop(); if(this.disconnect)this.disconnect();} 
 
    source.start(0); 
 
    } 
 
} 
 

 
function yourFirstImplementation(){ 
 
    alert('webAudioAPI is not supported by your browser'); 
 
    }
button{opacity: .2;} 
 
button.ready{opacity: 1};
<button>play</button> 
 
<input type="range" max="5" step=".01" title="volume"/>

+2

Tôi không thể ngừng chơi: D – myfunkyside

+0

nó hoạt động như một sự quyến rũ. Cảm ơn bạn thực sự nhiều –

+0

là có bất kỳ cách nào tôi có thể kiểm soát khối lượng của bộ đệm âm thanh này? –

0

cloneNode có một đối số boolean:

var dupNode = node.cloneNode(deep); 
/* 
    node 
    The node to be cloned. 
    dupNode 
    The new node that will be a clone of node 
    deep(Optional) 
    true if the children of the node should also be cloned, or false to clone only the specified node. 
*/ 

Cũng lưu ý từ MDN:

sâu là một lập luận không bắt buộc. Nếu bỏ qua, phương thức hoạt động như nếu giá trị của sâu là sự thật, mặc định để sử dụng nhân bản sâu như hành vi mặc định. Để tạo bản sao nông, phải đặt độ sâu thành sai.

Hành vi này đã được thay đổi trong thông số kỹ thuật mới nhất và nếu bỏ qua, phương thức sẽ hoạt động như thể giá trị của độ sâu là sai. Mặc dù Nó vẫn tùy chọn, bạn nên luôn luôn cung cấp những luận cứ sâu cho cả tương thích ngược và chuyển tiếp

Vì vậy, hãy cố gắng sử dụng deep = false để ngăn chặn tải tài nguyên:

var audioSrc = new Audio('path/'); 
window.onkeypress = function(event) { 
    var currentAudioSrc = audioSrc.cloneNode(false); 
    currentAudioSrc.play(); 
} 
+1

Từ các thử nghiệm của tôi, nó không hoạt động đối với vấn đề trong chrome. Bạn có quản lý để tránh việc tải xuống lại theo cách này không? – Kaiido

+0

Nó cũng không hoạt động ở đây. –

Các vấn đề liên quan