How to keep a blobURL from localStorage useful even if browser memory and session expires?
Asked Answered
S

1

-1

I found this article which teaches how to record an mp3 in your computer using ReactJS. So I copied it and refactored it a little here. After refactoring it into a functional component on stackblitz, I copied it on my original code. Afterwards, I implemented Redux to save the state and also persisted the blobURL on localStorage so that even if I refresh, it could still find it and play it.

It worked, but after refreshing in about 30 secs, it cannot be found already (even though it's in LS and even though the whole state is also persisted to LS). I keep on getting this error:

enter image description here

Now, according to the accepted answer on this post, "'the unloading document cleanup steps are executed' ... when the browser session expires, which is why the target of your blobURL can't be accessed in subsequent sessions."

Is this the reason why the browser can't find the blobURL for the recorded mp3 and can't play it anymore? If so, how do I work my way around it?

If this isn't the reason, what is? And how do I work my way around it?

UPDATE: I used localforage just like what @Kaiido said below. But I can't get my code to work. Please take a look at it here. Please help.

Sputter answered 9/4, 2021 at 5:17 Comment(0)
S
-1

For JS and react a blob:// URL is just a string, so what you saved is just a string.

However for the browser this string is actually a real pointer to the object that has been used to create it.
Now, for this relation to work, the browser has to keep the object in memory, so that when it tries to fetch the resource it can find it.

That is, until this blob:// URL is revoked.

The revocation can happen either by explicitly calling URL.revokeObjectURL( blobURL ) or when the Document that did create this blob:// URL is unloaded.

After the link has been revoked, the associated object can finally get Garbage Collected, and it's a very good thing, because we wouldn't want browsers to keep around Blobs that can be GBs big to stay in the memory even after a page reload.
Now, the link becomes a simple string again, just like if you removed the resource from the server.
They can't do otherwise because they can't know what happens to the string URL. You could store it in localStorage, on a server, or even just write it down on a paper — obviously they can't detect when it's safe to remove the data from memory in these conditions.
There is actually a better API in the specs: srcObject. It currently only concerns HTMLMediaElements, but it's planned to extend it to other elements loading resources. But anyway, while in the specs, no browser has implemented it yet for Blobs...


So for a solution, use IndexedDB, which can store Blobs directly on the user's disk.

With a library like localForage it simply becomes

localforage.setItem( "myfile", blob );

to save, and

await localforage.getItem( "myfile" );

to get it back.

Now you can playback that saved file by rebuilding a new blob:// URL.

Shortwave answered 17/4, 2021 at 6:35 Comment(3)
can I do this on Chrome browser or only on Firefox?Sputter
All browsers since a few years ago (not ultra old IEs)Shortwave
I used localforage just like you said @Kaiido. But I can't get it to work here: stackblitz.com/edit/react-recorder?file=src/Recorder.js. Please help.Sputter

© 2022 - 2024 — McMap. All rights reserved.