ScriptProcessorNode
与OfflineContext
不兼容。
它可以在Chrome,Mozilla Firefox中使用。
在Edge 25,Safari 10中不起作用。
问题是在处理上下文OfflineContextis
时,事件被调用一次。
[没有jsfiddle的BufferSource
上的示例。
基于MDN]的jsfiddle示例> example和BufferSource
。
console.clear(); var playButton = document.querySelector('.play'); var playButtonOffline = document.querySelector('.play-offline'); var current = 0; var buffer_size = 4096; var buffer_length = buffer_size * 10; var audioCtx = new(window.AudioContext || window.webkitAudioContext)(); var scriptNode = audioCtx.createScriptProcessor(buffer_size, 1, 1); scriptNode.onaudioprocess = whiteNoise; function whiteNoise(audioProcessingEvent) { console.log('onaudioprocess', current); // The output buffer contains the samples that will be modified and played var outputBuffer = audioProcessingEvent.outputBuffer; // Loop through the output channel for (var channel = 0; channel < outputBuffer.numberOfChannels; channel++) { var outputData = outputBuffer.getChannelData(channel); for (var sample = 0; sample < buffer_size; sample++) { // add noise to each output sample outputData[sample] += ((Math.random() * 2) - 1); } } current += buffer_size; if (current > buffer_length) scriptNode.disconnect(); } playButton.onclick = function() { current = 0; scriptNode.connect(audioCtx.destination); } playButtonOffline.onclick = function() { var offlineCtx = new(window.OfflineAudioContext || window.webkitOfflineAudioContext)(1, buffer_length, 48000); var scriptNodeOffline = offlineCtx.createScriptProcessor(buffer_size, 1, 1); scriptNodeOffline.onaudioprocess = whiteNoise; current = 0; offlineCtx.oncomplete = function(e) { console.log('rendered buffer', e.renderedBuffer.getChannelData(0).filter(f => f != 0).length); } scriptNodeOffline.connect(offlineCtx.destination); offlineCtx.startRendering(); }
<button class="play"> play </button> <button class="play-offline"> Render offline </button>
在Chrome和Firefox中多次单击Render offline
会产生same输出。
在[[Safari
和Edge中多次单击Render offline
产生了different输出。jsfiddle上的示例。 // Create AudioContext and buffer source
console.clear();
var playButton = document.querySelector('.play');
var playButtonOffline = document.querySelector('.play-offline');
var myBuffer = null;
var audioCtx = new(window.AudioContext || window.webkitAudioContext)();
var source = audioCtx.createBufferSource();
// Create a ScriptProcessorNode with a bufferSize of 4096 and a single input and output channel
var scriptNode = audioCtx.createScriptProcessor(4096, 1, 1);
// load in an audio track via XHR and decodeAudioData
function getData() {
request = new XMLHttpRequest();
request.open('GET', 'https://s3-ap-northeast-1.amazonaws.com/storage.cowrite.decodeapps.io/Materials/Media/Audio/59f2b85dd3aed-20171027-043853.mp3', true);
request.responseType = 'arraybuffer';
request.onload = function() {
var audioData = request.response;
audioCtx.decodeAudioData(audioData, function(buffer) {
myBuffer = buffer;
source.buffer = myBuffer;
},
function(e) {
"Error with decoding audio data" + e.err
});
}
request.send();
}
function addNoise(audioProcessingEvent) {
console.log("onaudioprocess")
// The input buffer is the song we loaded earlier
var inputBuffer = audioProcessingEvent.inputBuffer;
// The output buffer contains the samples that will be modified and played
var outputBuffer = audioProcessingEvent.outputBuffer;
// Loop through the output channels (in this case there is only one)
for (var channel = 0; channel < outputBuffer.numberOfChannels; channel++) {
var inputData = inputBuffer.getChannelData(channel);
var outputData = outputBuffer.getChannelData(channel);
// Loop through the 4096 samples
for (var sample = 0; sample < inputBuffer.length; sample++) {
// make output equal to the same as the input
outputData[sample] = inputData[sample];
// add noise to each output sample
outputData[sample] += ((Math.random() * 2) - 1) * 0.2;
}
}
}
// Give the node a function to process audio events
scriptNode.onaudioprocess = addNoise;
getData();
// wire up play button
playButton.onclick = function() {
source.connect(scriptNode);
scriptNode.connect(audioCtx.destination);
source.start();
}
// When the buffer source stops playing, disconnect everything
source.onended = function() {
source.disconnect(scriptNode);
scriptNode.disconnect(audioCtx.destination);
}
// When the buffer source stops playing, disconnect everything
// wire up play button
playButtonOffline.onclick = function() {
var offlineCtx = new(window.OfflineAudioContext || window.webkitOfflineAudioContext)(2, myBuffer.length, myBuffer.sampleRate);
var scriptNodeOffline = offlineCtx.createScriptProcessor(4096, 1, 1);
var sourceOffline = offlineCtx.createBufferSource();
sourceOffline.buffer = myBuffer;
sourceOffline.onended = function() {
console.log('sourceOffline.onended');
sourceOffline.disconnect(scriptNodeOffline);
scriptNodeOffline.disconnect(offlineCtx.destination);
}
scriptNodeOffline.onaudioprocess = addNoise;
sourceOffline.connect(scriptNodeOffline);
scriptNodeOffline.connect(offlineCtx.destination);
sourceOffline.start();
offlineCtx.oncomplete = function(e) {
console.log('renderedBuffer', e.renderedBuffer.getChannelData(0).filter(f => f != 0).length);
listenRendered(e.renderedBuffer);
};
offlineCtx.startRendering();
}
var _audioCtx = new(window.AudioContext || window.webkitAudioContext)();
function listenRendered(buffer) {
var _source = _audioCtx.createBufferSource();
_source.buffer = buffer;
_source.connect(_audioCtx.destination);
_source.start();
}
<button class="play">
play
</button>
<button class="play-offline">
Render offline
</button>
ScriptProcessorNode不适用于OfflineContext。它适用于Chrome,Mozilla Firefox。它在Safari 10的Edge 25中不起作用。问题是,当上下文...