Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Video mediaDevices Assign a Blob To 'videoRef.srcObject' In Place of 'src'

I am trying to make a blob the src of a video element. My code is working fine when:

videoRef.src = URL.createObjectURL(blob)

but using 'src' and 'URL.createObjectURL' is deprecated in place of using 'srcObject' https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL

enter image description here

and https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia

enter image description here

My question is how can I simply add a blob file to the srcObject like so:

videoRef.srcObject = blob

When I try the above code I get the error: "TypeError: Failed to set the 'srcObject' property on 'HTMLMediaElement': The provided value is not of type 'MediaStream'."

How can I not use the deprecated videoRef.src and apply a blob directly to videoRef.srcObject ? Or is it ok for blob type to use src, and only streams can't use src ?

like image 641
Will Avatar asked Jun 03 '18 18:06

Will


3 Answers

URL.createObjectURL is only deprecated for streams, not blobs and mediasources.

The MDN warning you reference is under the section titled Using object URLs for media streams. The warning itself says:

If you still have code that relies on createObjectURL() to attach streams to media elements

There's an effort to deprecate URL.createObjectURL specifically around streams, because streams are inherently local objects.

TypeError: Failed to set the 'srcObject' property on 'HTMLMediaElement

Looks like your browser hasn't implemented srcObject for blobs yet. This is common atm.

E.g. both Chrome and Firefox have partial support for srcObject for streams only, but not blob, file, or mediasource.

MDN on srcObject echoes this:

As of November 2017, browsers only support MediaStream. For MediaSource, Blob and File, you have to create a URL with URL.createObjectURL() and assign it to HTMLMediaElement.src.

like image 84
jib Avatar answered Nov 04 '22 07:11

jib


Adding on to jib's answer, here's a code snippet from MDN detailing a fallback for supporting older browsers:

const mediaSource = new MediaSource();
const video = document.createElement('video');
try {
  video.srcObject = mediaSource;
} catch (error) {
  video.src = URL.createObjectURL(mediaSource);
}
like image 38
ZMil Avatar answered Nov 04 '22 06:11

ZMil


Just adding my recent 'fun' experience with Safari on iOS and MacOS here. I finally figured out that the latest versions need a bit more love to get blob videos to play back, namely the use of the new video.srcObject (not .src) needing to be provided with a new Blob that includes type information about the video being played. Eg:

var fileInfo = {type: "video/mp4"}
video.srcObject = new Blob([blob], fileInfo);

Using the basic structure from another post the following code worked for me:

function setVideoFromBlob(blob, fileInfo = {type: "video/mp4"}) {
    // Older browsers may not have srcObject
    if ('srcObject' in video) {
        try {
           //fileInfo (type) required by safari, but not by chrome..
           video.srcObject = new Blob([blob], fileInfo);
        } catch (err) {
            if (err.name != "TypeError") {
                throw err;
            }
            // Even if they do, they may only support MediaStream
            video.src = URL.createObjectURL(blob);
        }
    } else {
        video.src = URL.createObjectURL(blob);
    }
}

Hope this helps some people out.

like image 1
Mann1ng Avatar answered Nov 04 '22 07:11

Mann1ng