cdxJava
cdxJava

Reputation: 27

Toggle Mute/Unmute video's Audio progressively

With this code I want to toggle mute/unmute a playing video's Audio with a fadeIn fadeOut effect:

const btn = document.getElementById('mute'),
      video = document.querySelector('#video_mainhub');

btn.addEventListener('click', () => {
  if (btn.value === 'unmuted') {
    btn.value = 'muted';
    btn.innerHTML = '<i class="fas fa-volume-mute"></i>';
    $('#video_mainhub').animate({volume: 0}, 1000);
    video.muted = true;
  } else {
    btn.value = 'unmuted';
    btn.innerHTML = '<i class="fas fa-volume-up"></i>';
    $('#video_mainhub').animate({volume: 1}, 1000);
    video.muted = false;
  }
});

<a id="mute" value="muted"><i class="fas fa-volume-mute"></i></a>

However, it is not working, anything I'm doing wrong?

Thanks.

Upvotes: 0

Views: 507

Answers (1)

Cue
Cue

Reputation: 2759

A few things we can identify and improve.

  • Anchor elements do not have a value attribute so btn.value = 'muted' amounts to nothing
  • Make use of jQuery to simplify matters at hand.
  • We can toggle the icon class rather than replace the innerHTML which can be expensive in the grand scheme of things.
  • I wouldn't rely on .animate() to modify the volume. But that opens another avenue and for demonstration purposes we'll stick to what you know.

Try this.

const $btn = $('#mute'),
      $video = $('#video_mainhub')

let isAnimating = false

$btn.on('click', () => {
  if (isAnimating) return

  let video = $video[0]
  let volumeTo;

  if (video.muted) {
    video.muted = false
    video.volume = 0
  }
  if (video.volume > 0) volumeTo = 0
  else if (video.volume < 1) volumeTo = 1

  // Toggle icon
  $btn.find('.fas')
    .removeClass(volumeTo === 1 ? 'fa-volume-mute' : 'fa-volume-up')
    .addClass(volumeTo !== 1 ? 'fa-volume-mute' : 'fa-volume-up')
  
  // Toggle volume
  isAnimating = true
  $video.stop(true, true).animate(
    {volume: volumeTo},
    1000,
    () => isAnimating = false
  )
})
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<video id="video_mainhub" playsinline autoplay muted controls width="400" src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-576p.mp4"></video>

<a id="mute"><i class="fas fa-volume-mute"></i></a>

Upvotes: 2

Related Questions