Joel Nash
Joel Nash

Reputation: 31

Web Audio Session API to trigger method calls in app rather than playing media

I'm having a hard time getting the Web Audio API to do what I want. My goal is to eventually trigger voice recognition in a PWA on mobile, but first I decided to do a test case of incrementing a counter whenever play or pause was pressed. I am using the Vue framework.

Here is an abbreviated version of my code along with the GUI is creates on the screen.

<template>
  <v-app>
    <v-btn @click="activateMediaButton">Start</v-btn>
    <div>{{counter}}</div>
    <v-btn @click="increment">Increment</v-btn>
  </v-app>
</template>

<script>

export default {
  name: 'App',
  data(){
    return {
      counter: 0
    };
  },

  methods: {
    increment(){
      console.log('ssedfr');
      this.counter++;
    },

    activateMediaButton(){
      navigator.mediaSession.metadata =  new window.MediaMetadata({})
      navigator.mediaSession.playbackState = 'playing';
      try{
        navigator.mediaSession.setActionHandler('play', this.increment)
        navigator.mediaSession.setActionHandler('pause',this.increment)
      }
      catch(error){console.log(error);}


  }
  }
}
</script>

GUI Here

As you can see, the action handlers are registered when I click the start button on the GUI, and the counter value is supposed to go up whenever I press the media buttons. I have tested this counter using the Increment button element on the GUI and it works fine, but the calls to increment aren't even being fired when the media keys are pressed as confirmed by console.log statements. No errors are thrown when the try block is executed to register the actions.

I am testing this functionality by using the Media keys on my laptop, which otherwise do play and pause media available in any open tabs. I have closed all other media tabs so that nothing is intercepting the keystrokes. I do notice that whenever I press the media button after the actions are registered, the focus goes to the Start button element that triggered the registration in such a way that it looks like a click is being held on it. Whenever Media button is pressed I have also tested this on my phone through a Netlify hosted PWA and bluetooth earphones and it doesn't work there either.

Upvotes: 1

Views: 711

Answers (1)

Obaydur Rahman
Obaydur Rahman

Reputation: 848

To work with Web Media Session API, the page must have to be playing a media file (video or audio).

Here is a working example:

<template>
  <div>
    <button @click="activateMediaButton">Start</button>
    <div>{{ counter }}</div>
    <button @click="increment">Increment</button>

    <audio
      src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
      controls
    ></audio>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      counter: 0,
    };
  },

  mounted() {
    navigator.mediaSession.metadata = new window.MediaMetadata({
      title: "Unforgettable",
      artist: "Nat King Cole",
      album: "The Ultimate Collection (Remastered)",
      artwork: [
        {
          src: "https://dummyimage.com/512x512",
          sizes: "512x512",
          type: "image/png",
        },
      ],
    });

    navigator.mediaSession.setActionHandler("play", this.increment);
    navigator.mediaSession.setActionHandler("pause", this.increment);
  },

  methods: {
    increment() {
      this.counter++;
      // handle action from here
    },

    activateMediaButton() {
      if (navigator.mediaSession.playbackState === "playing") {
        navigator.mediaSession.playbackState = "pause";
        document.querySelector("audio").pause();
      } else {
        navigator.mediaSession.playbackState = "playing";
        document.querySelector("audio").play();
      }
    },
  },
};
</script>

To understand how it works try pausing the audio manually from the page and then try using the media keys.

Upvotes: 0

Related Questions