内存泄漏OfflineAudioContext
。
在chrome中启动任务管理器。运行10次后createBuffer
内存使用1.5GB。标签超出RAM限制后,它将中断。
如何避免内存泄漏?
jsfiddle上的示例。
var audioCtx = new(window.AudioContext || window.webkitAudioContext)();
// define variables
var play = document.querySelector('.play');
var stop = document.querySelector('.stop');
var progress = document.querySelector('#progress');
var buffer = document.querySelector('.buffer');
var myBuffer = null;
var rendering = false;
// use XHR to load an audio track, and
// decodeAudioData to decode it and stick it in a buffer.
// Then we put the buffer into the source
function getData() {
request = new XMLHttpRequest();
request.open('GET', 'https://s3-ap-northeast-1.amazonaws.com/storage.cowrite.decodeapps.io/Materials/Media/Audio/5a0aca5f35965-20171114-105007.mp3', true);
request.responseType = 'arraybuffer';
request.onload = function() {
progress.innerText = 'loaded';
var audioData = request.response;
audioCtx.decodeAudioData(audioData, function(buffer) {
myBuffer = buffer;
createBuffer();
}).catch(function(err) {
console.log('Rendering failed: ' + err);
// Note: The promise should reject when startRendering is called a second time on an OfflineAudioContext
});
}
request.send();
}
buffer.setAttribute('disabled', 'disabled');
progress.innerText = 'loading...';
var cntRenfered = 0;
function createBuffer() {
var offlineCtx = new OfflineAudioContext(2, myBuffer.length, myBuffer.sampleRate);
var source = offlineCtx.createBufferSource();
source.buffer = myBuffer;
source.connect(offlineCtx.destination);
source.start();
//source.loop = true;
offlineCtx.oncomplete = function(e) {
progress.innerText = 'completed';
buffer.removeAttribute('disabled');
source.disconnect(offlineCtx.destination);
cntRenfered++;
buffer.innerText = 'reCreateBuffer ' + cntRenfered;
}
offlineCtx.startRendering();
}
buffer.onclick = function() {
progress.innerText = 'rendering...';
buffer.setAttribute('disabled', 'disabled');
createBuffer();
}
getData();

<div id="progress">
loading
</div>
<button class="buffer">
reCreateBuffer
</button>
&#13;
答案 0 :(得分:0)
我找到了解决方法。
jsfiddle上的示例。
var audioCtx = new(window.AudioContext || window.webkitAudioContext)();
// define variables
var play = document.querySelector('.play');
var stop = document.querySelector('.stop');
var progress = document.querySelector('#progress');
var buffer = document.querySelector('.buffer');
var myBuffer = null;
var rendering = false;
// use XHR to load an audio track, and
// decodeAudioData to decode it and stick it in a buffer.
// Then we put the buffer into the source
function getData() {
request = new XMLHttpRequest();
request.open('GET', 'https://s3-ap-northeast-1.amazonaws.com/storage.cowrite.decodeapps.io/Materials/Media/Audio/5a0aca5f35965-20171114-105007.mp3', true);
request.responseType = 'arraybuffer';
request.onload = function() {
progress.innerText = 'loaded';
var audioData = request.response;
audioCtx.decodeAudioData(audioData, function(b) {
myBuffer = b;
buffer.removeAttribute('disabled');
}).catch(function(err) {
console.log('Rendering failed: ' + err);
// Note: The promise should reject when startRendering is called a second time on an OfflineAudioContext
});
}
request.send();
}
buffer.setAttribute('disabled', 'disabled');
progress.innerText = 'loading...';
var cntRenfered = 0;
function createBuffer() {
var offlineCtx = getIFrameOfflineContext(2, myBuffer.length, myBuffer.sampleRate);
var source = offlineCtx.createBufferSource();
source.buffer = myBuffer;
source.connect(offlineCtx.destination);
source.start();
//source.loop = true;
offlineCtx.oncomplete = function(e) {
console.log('Rendering completed successfully');
progress.innerText = 'completed';
buffer.removeAttribute('disabled');
source.disconnect(offlineCtx.destination);
cntRenfered++;
buffer.innerText = 'reCreateBuffer ' + cntRenfered;
setTimeout(function() {
IFrameReload();
});
}
offlineCtx.startRendering();
}
buffer.onclick = function() {
progress.innerText = 'rendering...';
buffer.setAttribute('disabled', 'disabled');
createBuffer();
}
getData();
var iFrame;
function createIframe() {
iFrame = document.createElement('iframe');
iFrame.style.display = 'none';
iFrame.onload = () => {
const script = document.createElement('script');
script.innerHTML =
`
function reload() {
location.reload();
}
function createOfflineContext(NUMBER_OF_CHANNEL, duration, sampleRate) {
return new (window.OfflineAudioContext || window.webkitOfflineAudioContext)(NUMBER_OF_CHANNEL,duration,sampleRate);
}
`;
iFrame.contentDocument.body.appendChild(script);
};
document.body.appendChild(iFrame);
}
function getIFrameOfflineContext(NUMBER_OF_CHANNEL, duration, sampleRate) {
return iFrame.contentWindow.createOfflineContext(NUMBER_OF_CHANNEL, duration, sampleRate);
}
function IFrameReload() {
iFrame.contentWindow.reload();
}
createIframe();
&#13;
<div id="progress">
loading
</div>
<button class="buffer">
reCreateBuffer
</button>
&#13;