How to extract MediaStream from blob url?

You could get the URL using window.URL.createObjectURL() from the stream, like window.URL.createObjectURL() in the code below.

 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); } ); 

The problem is that now I have the blob url:

blob: HTTP% 3A // local% 3A1560 / f43bed15-da6c-4ff1-b73c-5640ed94e8ee

Is there a way to extract a MediaStream object from this?

+8
source share
3 answers

If you are using angular2, you can use the DOMSanitizer provided in the platform-browser-package:

 import { DomSanitizer } from '@angular/platform-browser'; constructor( private sanitizer: DomSanitizer) { } 

and then use your stream as follows:

 //your code comes here... video.src = this.sanitizer.bypassSecurityTrustUrl(window.URL.createObjectURL(stream)); 

It should only be

0
source

video.src is NOT video.srcObject

And yes, they will conflict ;)!

video.src accepts the source URL

video.srcObject accepts the original video.srcObject OBJECT (currently only MediaStream safely supported since 2019, maybe in the future you can place Blob right here, but not now ...)

So it depends on what you really want to do:

A) Show what is being recorded

You should have a MediaStream object (what you do) and just put it in video.srcObject

 navigator.getUserMedia({ video: true, audio: true }, function (localMediaStream) { var video = document.querySelector('video'); video.src = ''; // just to be sure src does not conflict with us video.srcObject = localMediaStream; } 

B) Show existing video / just recorded video

 video.srcObject = null; // make sure srcObject is empty and does not overlay our src video.src = window.URL.createObjectURL(THE_BLOB_OBJECT); 

THE_BLOB_OBJECT - you already have a file created using the File API, or, as a rule, if you have any recorder, let's say that the variable recorder usually has getBlob() or something similar, such as a recorder.getBlob() I highly recommend using some existing recorder library for this, but there is an official MediaRecorder API to complete it - https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder.

So, you see that you just combined 2 things together, you just need to separate them and make sure that they do not conflict :)

0
source

Remarks:

URL.createObjectURL (MediaStream) is deprecated. Do not use it in code anymore, it will add to any of the latest browsers.
The premise of the question remains valid, though.



There is no built-in way to retrieve the source object pointed to by the URL of the blob.

With blobs, we can still get this blob url, and we get a copy of the original 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)); }) 

However, this will not work with other objects ...

 const source = new MediaSource(); const url = URL.createObjectURL(source); fetch(url) .then(r => r.blob()) .then(console.log) .catch(console.error); 

Then the only way is to track your original objects.

To do this, we can create simple wrappers around createObjectURL and revokeObjectURL to update the dictionary of objects accessible by 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 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); } 
0
source

Source: https://habr.com/ru/post/952024/


All Articles