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?
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>
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.