3

I have a webpage which has a continuous(ish) livestream playing on it, but I want users only to be able to see and hear it at specific, exact times. I don't want them to have to keep disconnecting and reconnecting as this takes an unpredictable amount of time.

When the user loads the page, the livestream will autostart (muted and hidden - see below) and the user will have to unmute the video (even though they can't see it yet), but I don't want them to actually hear the livestream until the allocated time. I don't want them to have to manually unmute the video at the allocated times - My goal is to have everyone connected and stable so that (for example) at 10:04:30 precisely everyone can see and hear the livestream for 30 seconds, then it disappears (and mutes) until the next time at (say) 10:07:15 and so on. The process should happen in a way that allows the user to sit back in their armchair and not have to use their mouse or keyboard after the inital page load and unmuting of the livestream.

Dealing with the video side is easy - I can just show/hide a div with a black background that covers the video, but I'm not sure how to deal with the audio side of things. Is it possible to mute/unmute the webpage as a whole? Are there other ways to achieve this goal?

Another possible perspective is to have this done at the source somehow, by having the publisher connect and start publishing, but send blank video/audio until the right time, then switch over what is being sent. Again this needs to be done without the publisher having to keep reconnecting or do anything manually.

The publisher and viewers are all connecting using WebRTC.

Ben Holness
  • 2,457
  • 3
  • 28
  • 49

1 Answers1

0

Assuming something like the following:

<video id="vid" ...></video>
<div id="controls" ...>
  <button id="mute-btn">Mute</button>
</div>

Then you need something like this:

const vid = document.querySelector('#vid')
const muteBtn = document.querySelector('#mute-btn')

vid.muted = true

window.userHasUnmuted = false
window.liveStreamStarted = false

muteBtn.addEventListener('click', () => {
  window.userHasUnmuted = true

  if (window.liveStreamStarted) {
    vid.muted = false
  }
}

// then, in callback for whenever live-stream starts...

if (window.userHasUnmuted) {
  vid.muted = false
}

Original answer below

To mute a single audio or video element:

audioOrVideoElement.muted = true

To mute all audio or video elements on a page:

document.querySelectorAll('audio, video').forEach(el => el.muted = true)

Conversely, setting muted to false re-enables sound from that element.

For finer-tuned audio controls, you can also set the element's volume (in the range 0..1), for example:

document.querySelectorAll('audio, video').forEach(el => el.volume = 0.3)
Lionel Rowe
  • 5,164
  • 1
  • 14
  • 27
  • 1
    I'm mainly wondering if there is a way to unmute the page overall, not the individual element (or every individual element in a `forEach` loop), so that when the user does the inital unmute, there is no possibility of a brief snippet of sound before I mute it. – Ben Holness Sep 04 '20 at 18:43
  • @BenHolness Edited my answer - does this cover your use case? If not, you'll need to give more details. – Lionel Rowe Sep 04 '20 at 18:54
  • Possibly - I need to implement and try to be sure. My biggest concern is that (from what I understand) you can't auto-unmute an initially muted auto played video - it has to come from a user initiated button action, so I'm not sure if the unmute callback will be accepted. – Ben Holness Sep 04 '20 at 18:58
  • You could make all videos non autoplayed, and on video/audio load start playing them. you can add a 'data-autoload' on those elements and attach the proper load listener on elements with that attribute. – Brenden Sep 04 '20 at 19:02
  • @BenHolness Not at all. Try adding a Tampermonkey script for YouTube containing `setTimeout(() => { document.querySelector('video').muted = false }, 5000)`. Mute your YouTube video, refresh the page, and it works perfectly. – Lionel Rowe Sep 04 '20 at 19:05