HTML video tag - change source on viewport without media attribute

HTML video tag - change source on viewport without media attribute

I'm trying to implement a video in HTML with react. So if the viewport is under 750px width, I would like to change the video source to a smaller resolution/ smaller file (because of high data transfer and so on).

I'm trying to implement a video in HTML with react. So if the viewport is under 750px width, I would like to change the video source to a smaller resolution/ smaller file (because of high data transfer and so on).

So in a perfect HTML world, you would build this:

<video controls> 
   <source src="video-small.mp4" type="video/mp4" media="all and (max-width: 750px)"> 
   <source src="video.mp4" type="video/mp4"> 
</video>

Since media is not (or no more) specified in the source tag if it's inside of a video tag, I can't use this anymore. Because Chrome is displaying the first source, which is the mobile video. No matter if desktop or mobile.

Second solution was to wrap a container around and set display: none; to the not visible video:

import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import LazyLoad from 'react-lazyload'

const MobileVideo = styled.divwidth: 100%; height: 100%; object-fit: cover; display: none; ${({theme}) =&gt; theme.media.mobile display: block; }

const DesktopVideo = styled.divwidth: 100%; height: 100%; object-fit: cover; display: block; ${({theme}) =&gt; theme.media.mobile display: none; }

const VideoComponent = ({ srcWebm, srcMp4, mobileSrcWebm, mobileSrcMp4, poster, className, forwardedRef, ...rest }) => ( <React.Fragment> <MobileVideo> <video playsInline poster={poster.url} className={className} ref={forwardedRef} {...rest} > {mobileSrcWebm.url !== '' && ( <source src={mobileSrcWebm.url} type="video/webm" /> )} {mobileSrcMp4.url !== '' && ( <source src={mobileSrcMp4.url} type="video/mp4" /> )} </video> </MobileVideo> <DesktopVideo> <video playsInline poster={poster.url} className={className} ref={forwardedRef} {...rest} > {srcWebm.url !== '' && <source src={srcWebm.url} type="video/webm" />} {srcMp4.url !== '' && <source src={srcMp4.url} type="video/mp4" />} </video> </DesktopVideo> </React.Fragment> )

In this case the correct video is displayed, but both videos are downloaded (in Chrome). Hiding doesn't prevent the browser from downloading. SAD!

Third solution was to use the second solution and remove the invisible component from the DOM:

import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import LazyLoad from 'react-lazyload'

import {sizes} from '../../lib/ThemeProvider/media'

const MobileVideo = styled.divwidth: 100%; height: 100%; object-fit: cover; display: none; ${({ theme }) =&gt; theme.media.mobile display: block; }

const DesktopVideo = styled.divwidth: 100%; height: 100%; object-fit: cover; display: block; ${({ theme }) =&gt; theme.media.mobile display: none; }

class VideoComponent extends React.Component { state = { showMobileSrc: true }

componentDidMount() { this.resize() window.addEventListener('resize', this.resize) }

componentWillUnmount() { window.removeEventListener('resize', this.resize) }

resize = () => { if (window.innerWidth >= sizes.mobile) { this.setState({ showMobileSrc: false }) } else { this.setState({ showMobileSrc: true }) } }

render() { const { srcWebm, srcMp4, mobileSrcWebm, mobileSrcMp4, poster, className, forwardedRef, ...rest } = this.props const {showMobileSrc} = this.state return ( <React.Fragment> {showMobileSrc && <MobileVideo> <video playsInline poster={poster.url} className={className} ref={forwardedRef} {...rest} > {mobileSrcWebm.url !== '' && ( <source src={mobileSrcWebm.url} type="video/webm" /> )} {mobileSrcMp4.url !== '' && ( <source src={mobileSrcMp4.url} type="video/mp4" /> )} </video> </MobileVideo>} {!showMobileSrc && <DesktopVideo> <video playsInline poster={poster.url} className={className} ref={forwardedRef} {...rest} > {srcWebm.url !== '' && <source src={srcWebm.url} type="video/webm" />} {srcMp4.url !== '' && <source src={srcMp4.url} type="video/mp4" />} </video> </DesktopVideo>} </React.Fragment> ) } }

But chrome is downloading both videos anyway. HTML seems to be correct. No idea what chrome is doing there..

First i really don"t understand why they removed the media attribute from the source tag inside of a video tag. Thats not consistently implemented.

Anyway: How can I change the source at a defined viewport width and prevent downloading both videos?

Angular 9 Tutorial: Learn to Build a CRUD Angular App Quickly

What's new in Bootstrap 5 and when Bootstrap 5 release date?

Brave, Chrome, Firefox, Opera or Edge: Which is Better and Faster?

How to Build Progressive Web Apps (PWA) using Angular 9

What is new features in Javascript ES2020 ECMAScript 2020

Why ReactJS is better for Web Application Development?

Web Application Development is the point of contact for a business in today's digital era. It is important to choose the right platform for Web Application Development to build a high end Web

Download Instagram videos and photos using HTML, CSS and JavaScript

How can we download Instagram videos and photos using the HTML CSS JavaScript program? Solution: See this JavaScript Instagram Media Downloader. In other words, Program For Save Instagram Photos & Videos