adrian
adrian

Reputation: 1457

How to force HTML <video> to skip sources which can't be displayed as video?

I have an MP4 video encoded using a codec which Chrome seemingly doesn't support, because when I open the video in my browser it shows up as audio only.

I decided to account for videos like this in my application by generating a low-res H.264 version to be used when the primary codec isn't supported by the browser. I've got my <video> element set up like this:

<video>
    HTML video not supported
    <source src="original.mp4" type="video/mp4">
    <source src="display.mp4" type="video/mp4">
</video>

However, Chrome doesn't ignore the first video despite not supporting the codec; it continues to display the entire <video> as audio only.

Is there a way to force browsers to skip <source>s which cannot be displayed as video?

If there's isn't a built-in way, how can I use JS to accomplish the same thing? I don't want to simply put display.mp4 first because it is lower-resolution, which would not be optimal in cases where the browser can actually display the original. Would including the codecs portion of the content type fix this issue?

Upvotes: 0

Views: 3605

Answers (2)

Kaiido
Kaiido

Reputation: 136678

If you know the codecs, you can call video.canPlayType():

const supported = !!document.createElement("video")
  .canPlayType('video/mp4; codecs="mp4v"');
console.log({ supported });

If you don't know that codec and have fixed files, you can check this website: https://nickdesaulniers.github.io/mp4info/

If you don't have fixed files you can either retrieve the codecs with this library: https://github.com/gpac/mp4box.js, or if you don't want to load this quite big amount of code, you can wait for the source to load and check that the videoWidth and videoHeight are zero:

const video = document.querySelector("video");
video.play().then(() => {
  if(video.videoWidth + video.videoHeight === 0) {
    unsupported("video");
  }
}).catch(unsupported);

function unsupported(err) {
  console.error("unsupported", err);
}
<video src="https://dl.dropboxusercontent.com/s/dj8g1oqu29zv8eh/mp4v.mp4" controls muted></video>

Upvotes: 2

Taurz
Taurz

Reputation: 390

I'm not sure HTMLVideoElement.getVideoPlaybackQuality() would help to judge whether the source has images or not, give it a try.

const isVideoSupport = yourVideoElement.getVideoPlaybackQuality().totalVideoFrames > 0;

Besides, if you already know which broswer can't play the 'origin' video, you can skip the video by checking out whether current browser is chrome/firefox/etc.

Upvotes: 1

Related Questions