TURN THAT DOWN! Pausing or changing the volume of media when you leave the page

Looking through customer comments on my topic, Getting Started with the HTML5 Audio Element, I found a question that was similar to another comment; how to lower the volume or stop a video when you go to another page on a website.

I hadn't tried that before, so I experimented with the focus and blur events. It turned out to be relatively easy, as long as I watched for events that called other events.

Using the focus and blur events

The focus and blur events aren't directly related to the media (audio or video) object, they're actually on the window object. The focus event fires when a webpage gets focus (that is, ready to interact with you). The blur event fires when you lose focus. Using them is pretty straight forward:

// when you leave a page

window.addEventListener("blur", function(){
//do something here
}, false);

// when you return (or open) to a page

window.addEventListener("focus",function(){
// do something else here
}

Now you need to add code to the "do something part.

To test the examples here open two tabs, one with the sample, and another page (anything will do).

Pause video on leaving, pickup when you come back

For simplicity, I'm using an audio element, but you can do this as well with video. This example plays a clip of audio and pauses when you go to another tab or even switch to another app. The "wasPlaying" flag tracks whether the audio was playing or not when you lost focus.

The one issue I had is how to keep the "wasPlaying" flag current. The best way is to use the "play" or "pause" events to set the flag. We've used this technique in previous media posts where we change the Play button text. In the "play" event handler, we set "wasPlaying" to true. In the "pause" event handler, we set it to false.

In addition to setting the "wasPlaying" flag, we need an additional flag to tell us that we are leaving when we call pause. I did this because when you call pause, it fires the pause event, which in turn sets the "wasPlaying" flag to false. If we didn't track that we were leaving, we'd pause the audio when we lost focus. However, when we return, the "wasPlaying" flag is set to false in the "pause" event, and we wouldn't call play() to get started again.

Confused? Try commenting out the "leaving" flag and you'll see what happens. We also always initialize the leaving flag, because an uninitialized flag can be unpredictable. Try this example online.

<!doctype html>
< html>
< head>
<title>Audio Element Sample</title>
< /head>
< body>
<h1>Audio Element Sample</h1>
<!-- Display the audio player with control buttons. -->
<audio id="myaudio" src="https://testdriveie9.wise.glbdns.microsoft.com/ietestdrivecontent/Musopen.Com Symphony No. 5 in C Minor, Op. 67 - I. Allegro con brio.mp3" controls autoplay loop>
HTML5 audio not supported
</audio>
<script>
var audio =document.getElementById("myaudio");

      var wasPlaying; // set this to true sometime if playing
var leaving = false;

      window.addEventListener("blur", function () {
leaving = true;
if (wasPlaying) {
audio.pause();
}
}, false);

      window.addEventListener("focus", function () {
if (wasPlaying == true) {
audio.play();
}
leaving = false;
}, false);

      audio.addEventListener("play", function () {
wasPlaying = true;
}, false);

      audio.addEventListener("pause", function () {
if (!leaving) {
wasPlaying = false;
}
}, false);

    </script>
< /body>
< /html>

Cut the volume when you leave

Sometimes you don't want to stop the music when you leave a page, just turn it down a little. This example is actually simpler than pausing the music, because we don't need to worry about setting a special flag when we fire pause/play events.

To adjust the volume, we set the volume property on the media object. Volume is set between 0 and 1. When we lose focus, we're setting the volume to 1/3 what it was. You can set it to anything (even full volume to get users back to your page if you want). We stash the current volume in a global variable when we lose focus so we can reset it when we come back.

Try this example online.

<!doctype html>
< html>
< head>
<title>Audio Element Sample</title>
< /head>
< body>
<h1>Audio Element Sample</h1>
<!-- Display the audio player with control buttons. -->
<audio id="myaudio" src="https://testdriveie9.wise.glbdns.microsoft.com/ietestdrivecontent/Musopen.Com Symphony No. 5 in C Minor, Op. 67 - I. Allegro con brio.mp3" controls autoplay loop>
HTML5 audio not supported
</audio>
<script>

      var wasPlaying = false; // set this to true sometime if playing
var wasVolume; // save the current volume when we lose focus
var audio = document.getElementById("myaudio");

      window.addEventListener("blur", function () {
if (wasPlaying) {
wasVolume = audio.volume; // save the current volume
audio.volume = wasVolume / 3; // or any volume setting
}
}, false);

      window.addEventListener("focus", function () {
// if we were playing when we lost focus, reset volume when we come back
if (wasPlaying == true) {
audio.volume = wasVolume;
}
}, false);

      audio.addEventListener("play", function () {
wasPlaying = true;
}, false);

      audio.addEventListener("pause", function () {
wasPlaying = false;
}, false);

    </script>
< /body>
< /html>