简体   繁体   中英

Saving Web Audio API output to local file in Ionic

I'm developing an app using the Ionic Framework. Part of the app is to record audio using the microphone, filter out a range of frequencies, and then playback that sound through the speakers / earphones.

I have that part working using this code

function ListenButtonPressed() 
{           
        context = new (window.AudioContext||window.webkitAudioContext);
        navigator.getUserMedia = (navigator.getUserMedia ||
                                  navigator.webkitGetUserMedia ||
                                  navigator.mozGetUserMedia ||
                                  navigator.msGetUserMedia);
        navigator.getUserMedia(
                            {audio:true},
                            SetupFilters,
                            function(e) {
                                alert("error getting user media " + e);
                            });
}

function SetupFilters(stream)
{       
    input = context.createMediaStreamSource(stream);
    volume = context.createGain();

    volume.gain.value = 10;

    lowPass = context.createBiquadFilter(); 
    lowPass.type = 'lowpass';
    lowPass.frequency.value = 25;       

    highPass = context.createBiquadFilter(); 
    highPass.type = 'highpass';
    highPass.frequency.value = 425;     

    input.connect(lowPass);
    input.connect(highPass);
    input.connect(volume);

    highPass.connect(context.destination);
    lowPass.connect(context.destination);       
    volume.connect(context.destination);

    alert("recording started successfully");   
}

Now, I'd like another button that records that output of the filters, and saves it as a file in the phones storage system.

I've tried using RecorderJS and used this RecorderJS integration in an ionic app, but to no avail.

They work fine in regular browsers, but since it generates a download link instead of just storing the file, they're not much use for a mobile app.

Any suggestions for how to store the file locally, or to use a different approach for filtering out frequencies that allows for file storage are welcome.

Got it working, so posting my solution anybody else has this issue.

Download RecorderJS from the git repo in the question, and add the File plugin to your project.

Change the Recorder.setupDownload function to

Recorder.setupDownload = function(blob, filename)
{
try
{     
  window.requestFileSystem(window.PERSISTENT, 1024*1024, function(filesystem) {
        if(filesystem)
        {
            alert("got file system");
            try
            {
                var src = blob; //3-5mb blob from previously retrieved file
                var starttime = Date.now();
                filesystem.root.getFile("NEWFILE.WAV", { 'create': true }, 
                function (fileEntry) 
                {
                  fileEntry.createWriter(function (fileWriter) 
                  {
                      fileWriter.onwriteend = function (event) 
                      {
                        alert(Date.now()-starttime); //usually 3-6 seconds lockup
                      };
                      fileWriter.write(src);
                  }, 
                  function (fail) 
                  { 
                    alert("failed saving"+fail); 
                  });
                });
            }
            catch(e)
            {
              alert(e.message);
            }


        }
    });

}
catch(e)
{
  alert(e.message);
}

}

This line was added to the bottom of my 'SetupFilters' function

 audioRecorder = new Recorder( input );

I've buttons that trigger these StartRecording and StopRecording functions

function stopRec()
{
    highPass.disconnect();
    lowPass.disconnect();
    volume.disconnect();

    audioRecorder.stop();    
    audioRecorder.getBuffers( gotBuffers );
}
function startRec()
{
    audioRecorder.clear();
    audioRecorder.record();
}

Put these functions in the same class as the start and stop recording functions. I'm not 100% sure on what they do as I'm still learning Javascript, but they were taken from the RecorderJS integration linked in the question.

function saveAudio() {
    audioRecorder.exportWAV( doneEncoding );    
}

function gotBuffers( buffers ) {            
    audioRecorder.exportWAV( doneEncoding );
}

function doneEncoding( blob ) {
    Recorder.setupDownload( blob, "myRecording" + ((recIndex<10)?"0":"") + recIndex + ".wav" );
    recIndex++;
}

After all this, a WAV file is being saved to the phones storage.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM