2

Web Audio Api を使用してアプリを開発しています。私は、Safari がオーディオを処理し、オーディオ コンテキストを正しくガベージ カレッジしない方法にメモリ リークがあることを発見しました。このため、新しいページをロードしたいと考えています。そのページでオーディオ コンテキストを作成し、操作を完了してからウィンドウを閉じて、メモリを解放します。

これを達成するために、次のことを行いました。

ref = window.open('record.html', '_self');これにより、 https: //wiki.apache.org/cordova/InAppBrowser に従って、Cordova WebView で record.html ページが開きます。

1 window.open('local-url.html');// Cordova WebView にロードします
2 window.open('local-url.html', '_self');
// Cordova WebView にロードします

record.html ページは、実行したい操作を実行する JavaScript ファイルをロードします。これは、ネイティブ操作へのいくつかの呼び出しを行う recordLoad.js ファイルです (ネイティブ API は、Cordova Webview にロードされている場合にのみ使用できます。ご覧のとおり、ファイル システムにアクセスする必要があるため、これが唯一の方法です。やれ。

    window.onload = createAudioContext;
ref = null;

function createAudioContext(){
    console.log('createAudioContext');
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
    window.URL = window.URL || window.webkitURL;
    audioContext = new AudioContext;

    getDirectory();
}

function getDirectory(){
    console.log('getDirectory');
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, getFileSystem, fail);

}

function getFileSystem(directory){
    console.log('getFileSystem');
    var audioPath = localStorage.getItem('audioPath');
    directory.root.getFile(audioPath, null, getVocalFile, fail);

}

function getVocalFile(fileEntry){
    console.log('getVocalFile');
    fileEntry.file(readVocalsToBuffer, fail);

}

function readVocalsToBuffer(file){
    console.log('readVocalsToBuffer');
    var reader = new FileReader();
    reader.onloadend = function(evt){
        var x = audioContext.decodeAudioData(evt.target._result, function(buffer){
            if(!buffer){
                console.log('error decoding file to Audio Buffer');
                return;
            }
            window.voiceBuffer = buffer;
            buffer = null;
            loadBuffers();
        });

    }
    reader.readAsArrayBuffer(file);
}

//web
function loadBuffers(){
    console.log('loadBuffers');
    var srcSong = localStorage.getItem('srcSong');
    try{
        var bufferLoader = new BufferLoader(
            audioContext,
            [
                "."+srcSong
            ],
            createOffLineContext
        );
        bufferLoader.load()
    }
    catch(e){
        console.log(e.message);
    }
}


//
function createOffLineContext(bufferList){
    console.log('createOfflineContext');
    offline = new webkitOfflineAudioContext(2, window.voiceBuffer.length, 44100);
    var vocalSource = offline.createBufferSource();
    vocalSource.buffer = window.voiceBuffer;
    vocalSource.connect(offline.destination);

    var backing = offline.createBufferSource();
    backing.buffer = bufferList[0];
    backing.connect(offline.destination);

    vocalSource.start(0);
    backing.start(0);

    offline.oncomplete = function(ev){
        bufferList = null;
        console.log('audioContext');
        console.log(audioContext);
        audioContext = null;
        console.log(audioContext);
        vocalSource.stop(0);
        backing.stop(0);
        vocalSource.disconnect(0);
        backing.disconnect(0);
        vocalSource = null;
        backing = null;
        window.voiceBuffer = null;
        window.renderedFile = ev.renderedBuffer;
        var bufferR = ev.renderedBuffer.getChannelData(0);
        var bufferL = ev.renderedBuffer.getChannelData(1);
        var interleaved = interleave(bufferL, bufferR);
        var dataview = encodeWAV(interleaved);
        window.audioBlob = new Blob([dataview], {type: 'Wav'});

        saveFile();
    }

    offline.startRendering();

}

// このファイルは非常に長いですが、2 つのオーディオ バッファのミキシングが完了すると、新しいファイルがファイル システムに書き込まれます。そして、その操作が完了したら、私は使用します

function gotFileWriter(writer){
console.log('gotFileWriter');
writer.onwriteend = function(evt){
    console.log('onwriteEnd');
    console.log(window.audioBlob);
    delete window.audioBlob;
    console.log(window.audioBlob);
   // checkDirectory();
    var ref = window.open('index.html', '_self');
   // ref.addEventListener('exit', windowClose);

}
writer.write(audioBlob);

}

元の index.html ファイルに戻ります。これにより、メモリの問題が解決されます。ただし、同じ操作をもう一度実行しようとすると。つまり、record.html ファイルをロードし、recordLoad.js ファイルを実行すると、エラー ReferenceError: Can't find variable: LocalFileSystem が表示されます。

index.html をリロードすると、Cordova API へのリンクの一部が失われているように見えますが、すべてが失われているわけではありません。たとえば、Media API は使用できますが、File API は使用できません。これは、メモリ リークを解決するためのちょっとハックな方法 (ウィンドウの開閉) であることは理解していますが、それ以外の方法は見つかりません。これには本当に助けが必要です。ですから、どんな指針も大歓迎です。

4

0 に答える 0