2016-10-31 1 views
0

Ich habe eine „asd.wav“ Probe mit Gesamtdauer 3 Sekunden und es spielen:Wie kann ich ein Stück Sound Sample von Web Sound API spielen?

let source = audioCtx.createBufferSource(); 
source.buffer = buffer; // recieved buffer of asd.wav 
source.connect(audioCtx.destination); 
source.start(0); 

Es spielt perfekt 0,00-3,00 Sekunde, aber wie kann ich diese Probe nur 1,00-2,00 zweites Spiel?

+0

teilen Sie bitte den gesamten Code. Woher bekommst du 'Puffer'? –

+0

@ sid-m als Beispiel: http://codepen.io/anon/pen/PGrxvy. "asd.wav" kann nicht angehängt werden (brauche einen Proacc). –

Antwort

0

Zusätzlich zur expliziten Anforderung der Ressource, die abgespielt werden soll, und zum Teilen eines Teils davon, können Sie auch ein audio-Element verwenden. Nach dem docs, indem Sie #t=[starttime][,endtime] an die URL anhängen, können Sie den interessierenden Teil angeben.

Von dort ist es eine triviale Angelegenheit, eine Quelle aus dem Medienelement zu erstellen und sie zu spielen, anstatt alles von Grund auf neu zu machen.

Wie bei einer AJAX-Anfrage unterliegen Sie immer noch den Cross-Origin-Einschränkungen.

Hier ist ein Beispiel - ersetzen Sie die URL durch eine URL in der gleichen Domäne, eine verweist auf eine Ressource mit einem CORS-Header oder eine, die Ihren eigenen Server als Proxy für eine kompatible Ressource verwendet CORS-Header.

Wie Sie sehen können, benötigt der Code für diese Methode zusammen mit dem zugehörigen HTML weit weniger Code als der AJAX-Ansatz. Sie können auch audio Elemente dynamisch erstellen und laden, wie in der Schaltfläche Click-Handler gezeigt.

<!doctype html> 
<html> 
<head> 
<script> 
"use strict"; 
function byId(id){return document.getElementById(id)} 
/////////////////////////////////// 
window.addEventListener('load', onDocLoaded, false); 

function onDocLoaded(evt) 
{ 
    //loadAndPlayPortion("3 seconds.wav", 0.0, 1.0); 
    playAudioElement(byId('myAudioElem')); 
}; 

function onBtnClicked(evt) 
{ 
    var audio = document.createElement('audio'); 
    audio.onloadeddata = function(){ playAudioElement(this); }; 
    audio.src = '3 seconds.wav#t=2,3'; // could build this URL from user input 
} 


function playAudioElement(audioElem) 
{ 
    var AudioContext = window.AudioContext || window.webkitAudioContext; 
    var audioCtx = new AudioContext(); 
    var source = audioCtx.createMediaElementSource(audioElem); 
    source.connect(audioCtx.destination); 
    audioElem.play(); 
} 


function loadAndPlayPortion(soundUrl, startTimeSecs, endTimeSecs) 
{ 
    var AudioContext = window.AudioContext || window.webkitAudioContext; 
    var audioCtx = new AudioContext(); 

    var ajax = new XMLHttpRequest(); 
    ajax.open("GET", soundUrl, true); 
    ajax.responseType = "arraybuffer"; 
    ajax.onload = onFileLoaded; 
    ajax.send(); 

    function onFileLoaded() 
    { 
     audioCtx.decodeAudioData(this.response, onDataDecoded); 
    } 

    function onDataDecoded(sampleBuffer) 
    { 
     let source = audioCtx.createBufferSource(), numChannels=sampleBuffer.numberOfChannels, 
      sampleRate = sampleBuffer.sampleRate, 
      nRequiredSamples = (endTimeSecs-startTimeSecs)*sampleRate, 
      newBuffer = audioCtx.createBuffer(numChannels, nRequiredSamples, sampleRate); 
     for (var curChannel=0; curChannel<numChannels; curChannel++) 
     { 
      var channelData = sampleBuffer.getChannelData(curChannel); 
      channelData = channelData.slice(startTimeSecs*sampleRate, endTimeSecs*sampleRate); 
      newBuffer.copyToChannel(channelData, curChannel, 0); 
     } 
     source.buffer = newBuffer;    // chosen portion of received buffer of sound-file 
     source.connect(audioCtx.destination); 
     source.start(0); 
    } 
} 
</script> 
<style> 
</style> 
</head> 
<body> 
    <button onclick='onBtnClicked()'>Create Audio element</button> 
    <audio id='myAudioElem' src='3 seconds.wav#t=1,2'></audio> 
</body> 
</html> 
1

Dies sollte den Trick tun. Mag sein, dass es einfacher geht, aber das könnte ich mir vorstellen.

var AudioContext = window.AudioContext || window.webkitAudioContext; 
var audioCtx = new AudioContext(); 

var getSound = new XMLHttpRequest(); 
getSound.open("GET", "./asd.wav", true); 
getSound.responseType = "arraybuffer"; 
getSound.onload = function() { 
    audioCtx.decodeAudioData(getSound.response, function(buffer) { 
    let start_time = 1, end_time = 2, sample_rate = buffer.sampleRate, 
     channel_number = 0; // assuming a mono (one channel) audio 
    let source = audioCtx.createBufferSource(); 
    let data = buffer.getChannelData(channel_number); 
    data = data.slice(start_time * sample_rate, end_time * sample_rate) 
    let new_buffer = audioCtx.createBuffer(1 /*number of channels =1*/ , data.length, sample_rate); 
    new_buffer.copyToChannel(data, 0); 
    source.buffer = new_buffer 
    source.connect(audioCtx.destination); 
    source.start(0); 
    }); 
}; 

getSound.send(); 

Im Fall von Mehrkanalaudio müssen Sie die Schritte wiederholen, um Daten in jeden Kanal zu kopieren.

+0

scheint super! Ich versuche es zu Hause (nach 4 Stunden), danke! –