5

Let's start with an example:

  1. You visit youtube.com, which uses Media Source Extension (MSE) with HTML5 for certain devices.
  2. MSE injects the <video> tag with a blob URL. It looks something like this: blob:https://www.youtube.com/blahblahblah"
  3. Throughout streaming the entire video, your browser makes multiple network calls to download the various chunks of video, and appends them to the MSE's SourceBuffer
  4. Therefore, the Meda Source object as a whole is updated throughout the video stream
  5. However, the blob URL that was initially attached to the <video> element, which is suppose to represent the Media Source object, remains constant.

To me, this doesn't seem to make much sense. Blob URLs are suppose to represent chunks of immutable data that never changes. But it seems like MSE is able to make them represent a mutable buffer of memory.

How does this work under the hood? And if we also want to make blob URLs represent some mutable buffer of memory, how can we do this ourselves with javascript?

user3667125
  • 725
  • 1
  • 7
  • 17

2 Answers2

2

You need to understand that BlobURIs do not represent any data. They are just links, pointing to some resource in memory, just like the string https://stackoverflow.com/questions/54613972 doesn't contain any of what you are reading per se, it just points to a server instruction which will then generate the page.

Their link can be said to be immutable, once you generated it using URL.createObjectURL(target), you can not change its target, just like if you used the const keyword.

Take for instance const foo = {} now foo can't be set to something else than this object. But the object that is pointed by foo address is still mutable. foo.bar = 'baz' can still be done.

const foo = {};
try{
  foo = 'fails';
}
catch(e) {
  console.error(e);
}
foo.mutable = true;

console.log(foo);

Well for blobURIs it's just the same. The blobURI points to a target object, this link can't be changed, but the target is still mutable. This is true for MediaSource objects but also others.

If you remember a few years ago, we were still able to use blobURIs for MediaStreams (was a bad idea), it was the same process, the blobURI was pointing to the MediaStream object, in an un-mutable manner, but the media-data was in constant mutation (a stream).

And even for Files, you can very well have a blobURI that points to a File on your hard-drive, this won't block you from removing it from your HDD, even though the blobURI now points to nowhere anymore.

The one particular case with this regard is the case of a Blob, generated from data in memory (i.e not just a pointer to a file on disk). Here the data held by the Blob is immutable, so in this case, the blobURI indeed points to an object that does hold immutable data.

And for you request to have a blobURI pointing to some data stored in memory, but still be able to modify this data, this can't be done...
That is because this scenario implies that you created your blobURI from a Blob object using data in memory, which once again does hold data in an immutable state.

Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • _"this can't be done."_ Technically, it can be done [Where is Blob binary data stored?](https://stackoverflow.com/questions/38239361/) – guest271314 Feb 10 '19 at 07:00
  • 2
    @guest271314 "This can't be done" from web APIs... Obviously you can throw your computer in the fire... – Kaiido Feb 10 '19 at 07:02
  • Yes, have burned several experimenting. [Capturing MediaStream from HTMLMediaElement where src is set to MediaSource crashes tab #207](https://github.com/w3c/media-source/issues/207) is one example of the bugs in `MediaSource`. It is a special case that has observable difference in behaviour between Mozilla and Chromium implementations. Perhaps due to the underlying media player written in C++ which plays the media though definitely observable as a bug in the implementation nonetheless. – guest271314 Feb 10 '19 at 07:03
  • Of course this object is special and may have special bugs, but this is not related to current question at all, and neither to blobURIs... – Kaiido Feb 10 '19 at 07:17
  • Disagree. The question is essentially how `MediaSource` works. That requires a fair amount of effort to gather. It is not as simple as explaning how `Blob URL`s are different or the same as `Blob URI`s. Reading the previous and current specifications, open and closed issues, mailing lists. History of the project. Actually running the code at different browsers, which is "where the rubber meets the road", as it were. In a bug-free implementation bugs would not matter. When bugs crash browser tabs and is not fixed, there are systemic issues that may not be immediately evident without testing. – guest271314 Feb 10 '19 at 07:24
  • @guest271314 no, MediaSource in question is just an example. The question is more about what is a blobURI, and a misconception as to why it is said to be immutable. A blobURI is really just an URI, a string that points to some resource. Nothing more nothing less. That it points to a MediaSource, a Blob, a File or any other exotic object that doesn't exist yet has no importance as to how a blobURI works. – Kaiido Feb 10 '19 at 09:31
  • Thanks @Kaiido and guest271314. Kaiido is correct, I was confused about the concept, and this question is really about the behavior of blobURIs. Just a followup question -- if a blobURI points to a file on disk, would it be possible to use that file as a mutable data buffer? Change the file, and it changes the underlying data pointed by the blobURI? Or once the file has been read to memory, that result is saved, making it effectively immutable? – user3667125 Feb 10 '19 at 09:50
  • @user3667125 once fetched it is in memory, so you'd have to fetch it again to see the changes. Now, IIRC some browsers will allow you to do this, but others (at least Safari) will throw an error, even with the slightest modification of the file. – Kaiido Feb 10 '19 at 09:56
  • so final answer is no, we can not change the resource pointed by blob url ! – Ashish Saini Oct 26 '21 at 16:36
1

The Blob URL used for MediaSource is a special case. MediaSource is a special case.

The conception that

Blob URLs are suppose to represent chunks of immutable data that never changes.

is not necessarily true. Consider a Blob URL that contains, for example, HTML and JavaScript. Further data can be generated from that original Blob URL, including additional Blob URLs.

guest271314
  • 1
  • 15
  • 104
  • 177
  • Actually Blobs are special for blobURIs with OP's regard. And I'm not sure what you mean with `Further data can be generated from that original Blob URL, including additional Blob URLs`. The blobURI only points to some resource, anything that is done with it later can't be said to be the fact of the blobURI. It is not the blobURI that sings in my computer when I load an mp3 from a blobURI, just like it is not an url that does it either. – Kaiido Feb 10 '19 at 06:49
  • @Kaiido Yes, a special case. If the source code and the strict parameters of the group which developed `MediaSource`, and issues relating to `Blob` usage, and the specification is reviewed that can become clearer. Yes, it can be said to be fact that the origin of further process is in the initial `Blob URL` or `Blob URI`. – guest271314 Feb 10 '19 at 06:52
  • Sorry I don't understand your comment... My point is that Blobs are special here because only Blobs do hold immutable data. Neither a File on a disk, a MediaStream or a MediaSource have this particularity. So Blobs are the special case here. – Kaiido Feb 10 '19 at 06:54
  • @Kaiido Not sure what you are trying to convey. The data is not "immutable". The data which `Blob URL`s point to can be modified at the disk, given adequate motivation to do so. Also, additional processes can be spawned by the `Blob URL` dynamically where the processes derived therefrom are not immutable, thus the `Blob URL` itself is not immutable. In the case of `MediaSource` the `Blob URL` or `Blob URI` particularly behaves differently that with a `Blob URL` which is not associated with a `MediaSource`, especially at Chromium/Chrome browsers implementation. – guest271314 Feb 10 '19 at 06:57
  • The blob URL itself is just a string... This string points to some object in memory and this link can't be modified => it is "immutable". Now Blobs made from data in memory (like `new Blob(['foo bar'])`) have their data stuck in memory in an immutable manner: There is no way in any web API to modify this data after the Blob has been generated (whereas e.g ArrayBuffers are mutable). And I stay in the realm of web APIs, the question is tagged js and browser. – Kaiido Feb 10 '19 at 07:14
  • @Kaiido Am hesitant to state what is not possible in any field of endeavor. One example of the possibility to modify the underlying data using a "web API" is Native Messaging allows direct communication with a one or more shells. In any event, the specification [MediaSource object URL](https://w3c.github.io/media-source/#mediasource-object-url); 2.4.1 Attaching to a media element; et al. – guest271314 Feb 10 '19 at 07:16
  • Thanks @guest271314 and Kaiido for your insights. So if I am understanding it correctly, it is impossible for us to write a javascript client-side that make a blob URL point to a mutable buffer of memory? Because we would have to turn that memory buffer (likely a Uint8Array) into a blob, therefore making it immutable? The exception, of course, is if the blob URL points to a File, MediaSource, or MediaStream? – user3667125 Feb 10 '19 at 09:32
  • @user3667125 Here the term impossible is reserved for after exhausting all known possibilities to create a new approach or tangible item or solve a technical issue, not before trying all possibilities to resolve the inquiry. `Blob` can also be added to the list. It depends on how the parameters of the subject matter are defined and what you are actually trying to achieve. – guest271314 Feb 10 '19 at 14:33