admin管理员组

文章数量:1327843

I have two audio files which have to be played one after the other. In order to do this, I downloaded the two files using XHR

var xhr = new XMLHttpRequest();
xhr.open('GET', fileURL, true);
xhr.responseType = 'arraybuffer';

xhr.onload = function () {
  data = new Uint8Array(xhr.response);
  //... other handling code
};

and constructed a Blob from them

var blob = new Blob([data], {type: 'video/mp4'})

These I used to construct Blob URLs

var url = URL.createObjectURL(blob)

which are then injected into <audio> tags. (audioDOM.src = url;)

This procedure works in Chrome and Firefox. However IE11 sometimes gives me a problem, it displays following notice:

One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed.

However, the weirdest part is that it does work (in IE) for the first file, but not for the second one. They both use the same code for the entire procedure, which is simply called using a different fileURL. Both files exist, are downloaded properly and have been logged to console for verification.

I attempted copying the data before constructing the blobs, but it does not seem to matter: the error remains.

Does anyone have an idea what causes the problem and how it could be fixed?

EDIT after sbgoran: The entire script runs on a single document, which is not being reloaded. I am still confused why it is the case. I did manage to create a workaround by looping and creating a new URL when the audio fails to load, but this is not a workable solution. The weird part is that the method described above fails at random: sometimes the URL is available when loaded into the <audio> tag, sometimes it isn't.

I have two audio files which have to be played one after the other. In order to do this, I downloaded the two files using XHR

var xhr = new XMLHttpRequest();
xhr.open('GET', fileURL, true);
xhr.responseType = 'arraybuffer';

xhr.onload = function () {
  data = new Uint8Array(xhr.response);
  //... other handling code
};

and constructed a Blob from them

var blob = new Blob([data], {type: 'video/mp4'})

These I used to construct Blob URLs

var url = URL.createObjectURL(blob)

which are then injected into <audio> tags. (audioDOM.src = url;)

This procedure works in Chrome and Firefox. However IE11 sometimes gives me a problem, it displays following notice:

One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed.

However, the weirdest part is that it does work (in IE) for the first file, but not for the second one. They both use the same code for the entire procedure, which is simply called using a different fileURL. Both files exist, are downloaded properly and have been logged to console for verification.

I attempted copying the data before constructing the blobs, but it does not seem to matter: the error remains.

Does anyone have an idea what causes the problem and how it could be fixed?

EDIT after sbgoran: The entire script runs on a single document, which is not being reloaded. I am still confused why it is the case. I did manage to create a workaround by looping and creating a new URL when the audio fails to load, but this is not a workable solution. The weird part is that the method described above fails at random: sometimes the URL is available when loaded into the <audio> tag, sometimes it isn't.

Share Improve this question edited Dec 27, 2013 at 14:23 MrP asked Dec 18, 2013 at 9:43 MrPMrP 1,3691 gold badge9 silver badges18 bronze badges 2
  • 1 Is there a reason you cannot use src=whatever and onended=playsecond() for the 1st or as in this: stackoverflow./questions/9326288 ?... using blobs like this seems inefficient and unnecessary. – technosaurus Commented Dec 23, 2013 at 8:20
  • Yes, I have very good reasons for this. One of which is that the data from the original two files is edited to form two new files in my final implementation. This however has no effect on the failure rate: I did tests where the blobs were simply copied as described above and the problem still occurred. (So the manipulation has no effect on the problem stated here) – MrP Commented Dec 23, 2013 at 15:43
Add a ment  | 

3 Answers 3

Reset to default 6

Apart from sbgoran's answer, I have another possible cause - as discussed on WhatWG mailing list, there's a bug in IE that causes a Blob to be garbage collected when the variable that points to it goes out of scope - even when there are still object URLs pointing to the Blob that haven't been revoked.

A workaround could rely on holding on to the original Blob object in a variable as long as the object URL is needed, then nullifying the variable and revoking its object URL afterwards.

Based on Remarks section of MSDN createObjectURL method page it could be plenty of things that IE might plain about. I'm not sure if you read this MSDN page before but maybe it can help in some way.

I would especially check note about blob urls origin policy

Blob urls are subject to an origin policy. This means that they can only be used in documents that have the same site-of-origin as the document running the script that created the url. If you need to use the blob object from an that is running in a different domain, you must use the postMessage API to send the blob data to the frame and then create the blob: url there.

and

URL returned by createObjectURL is valid for the lifetime of the creating document,

which are then injected into <audio> tags.

Can you please give this code ?

Maybe IE has some kind of garbage collector, which frees the blob url as soon as there is no DOMString instance containing the blob url.

With this theory, creating your audio tag with innerHTML (and maybe setAttribute ?), I mean by concatenation of the url (foo.innerHTML = '<audio src="' + url + '" />';) implies that the only DOMString containing the blob url (the one returned by URL.createObjectURL) will be garbage collected some time after the end of your function.

本文标签: javascriptIE frees blob urlsStack Overflow