CreateIT
CreateIT
BLOG

React – muted video in a loop

Laptop with a video of a sitting ninja

React – muted video in a loop

SHARE

Challenge:
disable audio in a video file and enable loop
Solution:
use dangerouslySetInnerHTML to set the mute parameter

The muted parameter has been forbidden to use in React since 2017. It was reported on Facebook’s github -> https://github.com/facebook/react/issues/10389 , but never resolved. Autoplayed video with audio can be annoying for website visitors, so the ability to mute is a must have, especially when adding a video as a background or a slider item.

Would you like to embed a muted video in a loop, and also have the ability to set the video ratio display? In this article, you will see how to achieve this!

Big white cartoon bunny standing in a green valley

Add muted param

If we are going to add the muted param directly to the video tag, it will be stripped in the browser window. One workaround for this is to apply dangerouslySetInnerHTML, which will keep the forbidden attribute.

Pay attention to adding className to div, it contains a string and a variable. To make it work properly we use backtick apostrophes ( ` ). On your keyboard, you will find it just left to number 1 or above the TAB key.

Video ratio

Our video is fullwidth, with the predefined ratio: 4/3 or 16/9. By using object-fit: cover – the video will cover the entire available space. “padding-top percentage hack” is used to render proper ratio. It nicely maintains the proper width and height ratio. The magic values are: 75% and 56.25%.

Mute workaround

That’s it for theory, now let’s look at a working example. The clip is using an mp4 file to render video, we have 2 buttons which we can use to make live changes to the ratios. Here is the source code:

// src/Video.jsx
import React from 'react';
export const Video = (props) => {
    const {src, id, muted, autoplay, ratio, loop} = props;
    let mutedParam = '';
    if(muted){
        mutedParam = 'muted';
    }
    let autoplayParam = '';
    if(autoplay){
        autoplayParam = 'autoplay';
    }
    let loopParam = '';
    if(loop){
        loopParam = 'loop';
    }
    return (
        <div className={`videoContainer ratio-${ratio}`} dangerouslySetInnerHTML={{
            __html: `
          <video
            ${mutedParam}
            ${autoplayParam}
            ${loopParam}           
            playsinline
            src="${src}"   
            id="${id}"
          />`
        }}
        />
    );
}

Styles to apply special ratio and make video 100% width:

.App {
  text-align: center;
}
.videoContainer {
  width: 100%;
  padding-top: 56.25%;
  height: 0;
  position: relative;
}
video {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  object-fit: cover;
}
.videoContainer.ratio-16_9{
  padding-top: 56.25%;
}
.videoContainer.ratio-4_3{
  padding-top: 75%;
}
button {
  padding:5px 10px;
  border:0;
  border-radius:5px;
  background:#ccc;
  color:#333;
  font-size:1rem;
  margin:1rem;
}
button.active {
  background:orangered;
  color:#fff;
}

And using the Video Component in the main App view:

// src/App.jsx
import React, {useState} from 'react';
import './App.css';
import {Video} from "./Video";
function App() {
    const [videoRatio, setVideoRatio] = useState("4_3");
    return (
        <div className="App">
            <button onClick={() => setVideoRatio("16_9")} className={(videoRatio === "16_9" ? "active" : "")}>
                Ratio 16/9
            </button>
            <button onClick={() => setVideoRatio("4_3")} className={(videoRatio === "4_3" ? "active" : "")}>
                Ratio 4/3
            </button>
            <Video src="https://www.w3schools.com/html/mov_bbb.mp4"
                   id="myVideo1"
                   muted={true}
                   autoplay={true}
                   ratio={videoRatio}
                   loop={true}
            />
        </div>
    );
}
export default App;

Big white bunny standing in a green glade

Mute / unmute button

We can easily add special buttons that will enable or disable audio in the played video. Only a couple additions are needed to our code in the App.jsx file:

// src/App.jsx
import React, {useState} from 'react';
import './App.css';
import {Video} from "./Video";
function App() {
    const [videoRatio, setVideoRatio] = useState("4_3");
    const [mutedVideo, setMutedVideo] = useState(true);
    return (
        <div className="App">
            <button onClick={() => setMutedVideo(true)} className={( mutedVideo ? "active" : "")}>
                Mute
            </button>
            <button onClick={() => setMutedVideo(false)} className={(! mutedVideo ? "active" : "")}>
                Unmute
            </button>
            <button onClick={() => setVideoRatio("16_9")} className={(videoRatio === "16_9" ? "active" : "")}>
                Ratio 16/9
            </button>
            <button onClick={() => setVideoRatio("4_3")} className={(videoRatio === "4_3" ? "active" : "")}>
                Ratio 4/3
            </button>
            <Video src="https://www.w3schools.com/html/mov_bbb.mp4"
                   id="myVideo1"
                   muted={mutedVideo}
                   autoplay={true}
                   ratio={videoRatio}
                   loop={true}
            />
        </div>
    );
}
export default App;

Big white bunny standing in a green glade

Video ratios

It is really easy to enable additional aspect ratios for a video. It’s just a matter of extra CSS class name. Here are the padding values for popular video formats:

aspect ratiopadding-top value
16:956.25%
4:375%
3:266.66%
8:5 / 16:1062.5%

That’s it for today’s tutorial. Be sure to follow us for other tips and guidelines, and don’t forget to sign up for our newsletter.

 

Need help?

  • Looking for support from experienced programmers?

  • Need to fix a bug in the code?

  • Want to customize your webste/application?

ADD COMMENT

Your email address will not be published.

createIT Contact