'Chrome not respecting video source inline media queries

Using the below, Chrome is not respecting the media queries to display the correct video source based on the device width. Chrome is just playing the first source it finds as you can see here: http://homeglobal.ch/. How can I fix this?

    <video id="intro-video" poster="img/poster.png" controls>
        <source src="videos/intro.mp4" type="video/mp4" media="all and (min-device-width:1600px)">
        <source src="videos/intro.webm" type="video/webm" media="all and (min-device-width:1600px)">
        <source src="videos/intro-1600.mp4" type="video/mp4" media="all and (min-device-width:1100px)">
        <source src="videos/intro-1600.webm" type="video/webm" media="all and (min-device-width:1100px)">
        <source src="videos/intro-1100.mp4" type="video/mp4" media="all and (min-device-width:481px)">
        <source src="videos/intro-1100.webm" type="video/webm" media="all and (min-device-width:481px)">
        <source src="videos/intro-480.mp4" type="video/mp4">
        <source src="videos/intro-480.webm" type="video/webm">
    </video>


Solution 1:[1]

Unfortunally, Chrome is not supporting media queries for video html 5 tag. A work around for this is to use plain Javascript or Jquery. It is no pretty, but works even in chrome.

var video = $('#myvideo');

var WindowWidth = $(window).width();

if (WindowWidth < 1200) {
    //It is a small screen
    video.append("<source src='/img/homepage/640/splash.m4v' type='video/mp4' >");
} else {
    //It is a big screen or desktop
    video.append("<source src='/img/homepage/1080/uimain-1080.mp4' type='video/mp4' >");
}

Solution 2:[2]

My implementation on Vanilla JS.

In the video tag, as the data-src attribute, specify the path to the default video. Inside the video tag, in the source tags, we specify the value of the two attributes data-src and data-mw.

data-src - is the path to the video file.

data-mw - is the maximum screen width at which this video should be shown.

This solution works automatically when the screen width changes. This is done using the resize() function.

<video id="intro-video" data-src="/path/default.mp4" poster="img/poster.png" controls>
    <source data-src="/path/1600.mp4" data-mw="1600">
    <source data-src="/path/900.mp4" data-mw="900">
    <source data-src="/path/480.mp4" data-mw="480">
</video>
class VideoResponser {
    constructor(selector) {
        const $video = document.querySelector(selector);
        this.options = { 
            selector, 
            breakpoints: { default: { src: $video.getAttribute('data-src') } } 
        };

        // get a list of video switching points and links to the videos themselves 
        $video.querySelectorAll('[data-src]').forEach(element => this.options.breakpoints[element.getAttribute('data-mw')] = { src: element.getAttribute('data-src') });
        $video.innerHTML = ''; // we clean up so that there is nothing superfluous 
        
        // run the handler and track the change in screen width
        this.responseVideo(this.options);
        this.resizer();
    }

    /** Function runs on resize  */
    resizer() {
        window.addEventListener("resize", () => this.responseVideo(this.options));
    }

    /** 
     * Change src value of video link to fit screen width 
     * 
     * @param {Object} options object with options 
     */
    responseVideo(options) {
        const {selector, breakpoints} = options; // get options
        let $video = document.querySelector(selector);
        const widthNow = $video.getAttribute('data-width-now') || null;
        const maxBreakpoint = Math.max.apply(Math, Object.keys(breakpoints).filter(key => key <= document.body.clientWidth).map(Number));
        const nowBreakpoint = maxBreakpoint || 'default'; // choose either the maximum value, if not, then the default 

        if(widthNow && widthNow == nowBreakpoint) return; // check if the video needs to be changed 

        $video.setAttribute('data-width-now', nowBreakpoint);
        $video.src = breakpoints[nowBreakpoint].src;
    }
}

new VideoResponser("#intro-video");

Solution 3:[3]

<video class="desktop-video" autoplay playsinline preload="auto" muted loop width="100%">
    <source src="${pdict.desktop_video}" type="video/mp4">
    <source src="${pdict.desktop_video}" type="video/mov">
    Sorry, your browser doesn't support embedded videos.
</video>
<video class="mobile-video" autoplay playsinline preload="auto" muted loop width="100%">
    <source src="${pdict.mobile_video}" type="video/mp4">
    <source src="${pdict.mobile_video}" type="video/mov">
    Sorry, your browser doesn't support embedded videos.
</video>

Can be done in CSS like

.desktop-video {
    display: grid;

    @include media-breakpoint-down(lg) {
        display: none;
    }
}

.mobile-video {
    display: none;

    @include media-breakpoint-down(lg) {
        display: grid;
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Serkan Sipahi
Solution 2 Rick Kukiela
Solution 3 Andy Oberio Homalayan