google-chrome-extensionblobweb-audio-apigoogle-chrome-storage

How to save state of audio blob in my chrome extension?


I have the following popup.js file in which I capture audio from a tab and store it in a blob and then set my audio tag's src URL to it. I would like to store this blob in chrome's local storage so that the audio data remains even after closing the extension's popup.html window. How do I go about doing this? I tried to serialize the blob to JSON using ArrayBuffer but it seemed to not be the correct method. If there is a better way please let me know. Thanks.

function captureTabAudio() {
  chrome.tabCapture.capture({ audio: true, video: false }, (stream) => {

    context = new AudioContext();
    const chunks = [];
    if (context.state === 'suspended') {
      context.resume();
    }
    var newStream = context.createMediaStreamSource(stream);
    newStream.connect(context.destination);

    const recorder = new MediaRecorder(stream);
    recorder.start();

    setTimeout(() => recorder.stop(), 10000);

    recorder.ondataavailable = (e) => {
      chunks.push(e.data);
    };

    recorder.onstop = (e) => {
      const blob = new Blob(chunks, { type: "audio/ogg; codecs=opus" });
      document.querySelector("audio").src =
        URL.createObjectURL(blob);
    };
  })
}

Solution

  • I assume that when you say "Chrome's local storage" you mean the web's localStorage API. If so, this won't work because, "The keys and the values stored with localStorage are always in the UTF-16 string format, which uses two bytes per character" (MDN). If you meant the extension platform's Storage API, you'll have a similar problem because it only supports JSON-serializable values. While you could potentially convert the ArrayBuffer into a Base64 string, I wouldn't recommend it as you're more likely to run into storage limits.

    For storing binary data locally, currently your best bet is to use IndexedDB. Since this API supports the structured clone algorithm, it supports a much broader set of types including ArrayBuffer. A similar question was asked here: Saving ArrayBuffer in IndexedDB.