我怎样才能通过网络声音API播放一些声音样本?

时间:2016-10-31 08:52:13

标签: javascript html5 html5-audio

我有一个“asd.wav”样本,总持续时间为3秒,然后播放:

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

它在0.00到3.00秒之间完美播放,但我怎么能在1.00到2.00秒之间播放这个样本呢?

2 个答案:

答案 0 :(得分:1)

这应该可以解决问题。也许可以用更简单的方式完成,但这就是我能想到的。

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

如果是多声道音频,您需要重复步骤将数据复制到每个频道。

答案 1 :(得分:0)

除了显式请求播放资源并切出部分资源外,您还可以使用audio元素。根据{{​​3}},通过将#t=[starttime][,endtime]附加到网址,您可以指定感兴趣的部分。

从那里开始,从媒体元素创建一个源并播放它是一个微不足道的事情,而不是从头开始。

与AJAX请求一样,您仍然受到跨源限制。

以下是一个示例 - 只需将URL替换为同一域中的一个,一个引用具有CORS头的资源,或者使用您自己的服务器作为不兼容资源的代理的URL。 ;来自CORS标题。

正如您所看到的,此方法的代码及其附带的HTML需要的代码远远少于AJAX方法。您还可以动态创建和加载audio元素,如按钮单击处理程序所示。

<!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>