可以使用 window.URL.createObjectURL()
从流中获取 URL,如下面的代码所示。
navigator.getUserMedia({ video: true, audio: true }, function (localMediaStream) {
var video = document.querySelector('video');
video.src = window.URL.createObjectURL(localMediaStream);
video.onloadedmetadata = function (e) {
// Do something with the video here.
};
},
function (err) {
console.log("The following error occured: " + err);
}
);
问题是现在我有一个像这样的 blob URL:
blob:http%3A//localhost%3A1560/f43bed15-da6c-4ff1-b73c-5640ed94e8ee
有没有办法从中检索 MediaStream 对象?
最佳答案
备注:
URL.createObjectURL(MediaStream) 已被弃用。
不要再在代码中使用它,它会抛出任何最新的浏览器。
不过,问题的前提仍然有效。
没有内置方法来检索 blob URL 指向的原始对象。
使用 Blob,我们仍然可以获取此 Blob URL,并且我们将获得原始 Blob 的副本。
const blob = new Blob(['hello']);
const url = URL.createObjectURL(blob);
fetch(url)
.then(r => r.blob())
.then(async (copy) => {
console.log('same Blobs?', copy === blob);
const blob_arr = new Uint8Array(await new Response(blob).arrayBuffer());
const copy_arr = new Uint8Array(await new Response(copy).arrayBuffer());
console.log("same content?", JSON.stringify(blob_arr) === JSON.stringify(copy_arr))
console.log(JSON.stringify(copy_arr));
})
但是对于其他对象,这将不起作用...
const source = new MediaSource();
const url = URL.createObjectURL(source);
fetch(url)
.then(r => r.blob())
.then(console.log)
.catch(console.error);
唯一的方法就是跟踪您的原始对象。
为此,我们可以想出围绕 createObjectURL
和 revokeObjectURL
的简单包装器来更新可通过 URL 访问的对象字典:
(() => {
// overrides URL methods to be able to retrieve the original blobs later on
const old_create = URL.createObjectURL;
const old_revoke = URL.revokeObjectURL;
Object.defineProperty(URL, 'createObjectURL', {
get: () => storeAndCreate
});
Object.defineProperty(URL, 'revokeObjectURL', {
get: () => forgetAndRevoke
});
Object.defineProperty(URL, 'getFromObjectURL', {
get: () => getBlob
});
const dict = {};
function storeAndCreate(blob) {
var url = old_create(blob); // let it throw if it has to
dict[url] = blob;
return url
}
function forgetAndRevoke(url) {
old_revoke(url);
// some checks just because it's what the question titel asks for, and well to avoid deleting bad things
try {
if(new URL(url).protocol === 'blob:')
delete dict[url];
}catch(e){} // avoided deleting some bad thing ;)
}
function getBlob(url) {
return dict[url];
}
})();
// a few example uses
// first a simple Blob
test(new Blob(['foo bar']));
// A more complicated MediaSource
test(new MediaSource());
function test(original) {
const url = URL.createObjectURL(original);
const retrieved = URL.getFromObjectURL(url);
console.log('retrieved: ', retrieved);
console.log('is same object: ', retrieved === original);
URL.revokeObjectURL(url);
}
关于javascript - 如何从 Blob url 检索 MediaStream?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18312962/