RockGuitarist1
RockGuitarist1

Reputation: 716

Saving Audio to localStorage for Playback

I am trying to create a function in which an mp3 file is pulled from

<input type="file" id="sound" accept="audio/*"/>

and stored in localStorage within Chrome. (I know localStorage is limited in size, but the audio files that I will be working with will be under 2mb.) Once this audio file is stored, it will be played with:

var audio = new Audio('audioFile');
audio.play();

I am still new to web development, so any pointers would be great!

NOTE: This is not a duplicate of HTML5 record audio to file. I am trying to take a preexisting mp3 file from my HDD and storing it into localStorage so that it can be played back.

Upvotes: 17

Views: 17459

Answers (2)

Soviut
Soviut

Reputation: 91585

This is not what localStorage is meant for. localStorage can only store strings and can only accommodate a small amount of date.

If you're really determined to do this you need to:

Note that Base64 encoding usually increases the size of the source material by about 33%. This is because it can take any kind of data, including binary, and converts it to a string made of a 64 character set that's compatible with standard ASCII strings.

To play it back, you need to the opposite

  • retrieve the Base64 encoded string from localStorage
  • decode the Base64 string into an ArrayBuffer
  • load the ArrayBuffer into an Audio object
  • assign the Audio object to an <audio> element

It should also be noted that localStorage is often only given 5-10MB of storage space, depending on the browser. This can be tested here, but generally, keep your mp3 files small by encoding them with lower bit rates, use mono instead of stereo channels where possible, and reduce sample rate if the audio is just spoken words and not music.

Upvotes: 10

Kaiido
Kaiido

Reputation: 136986

localStorage is not meant to store such data. Instead, you should use the IndexedDB API, which is made for storing this kind of data.

Dealing with the indexedDB is highly simplified with the Mozilla's localForage lib, which provides a syntax similar to the one of localStorage.

Fiddle since StackSnippets® doesn't allow access to indexedDB nor localStorage.


But to convert a File (or a Blob) to a String, as needed by the localStorage API, you can use an FileReader and its readAsDataURL() method, which will provide an dataURI, directly playable by MediaElements.

f.onchange = e =>{
  if(f.files[0].type.indexOf('audio/') !== 0){
    console.warn('not an audio file');
    return;
    }
  const reader = new FileReader();
  reader.onload = function(){
    var str = this.result;
    // this is a string, so you can store it in localStorage, even if it's really not a good idea
    console.log(str);
    const aud = new Audio(str);
    aud.play();
    };
  reader.readAsDataURL(f.files[0]);
  }
<input type="file" id="f">

Upvotes: 21

Related Questions