Detect if <iframe> is playing audio

Viewed 1231

Question

I'd like to know whether an <iframe> that is embedded in my website is playing audio.

Ideally as well how "loud" the <iframe> is playing the audio but that's optional.

Note that the <iframe> is not on the same origin, hence inspecting the <iframe> is not an option.

My Concrete Use Case

I'm the developer of https://www.timer-tab.com/ and when the time is up a YouTube video starts playing. The YouTube video is playing in an <iframe>. I'd like to know whether the YouTube <iframe> is emitting any sound. If it doesn't emit any sound, a fallback sound is played using the Web Audio API. (The YouTube <iframe> sometimes doesn't emit sound. For example, when the user has set his YouTube volume setting to mute. Unfortunately, it is not possible to get that information by postMessageing the YouTube <iframe>.)

Related Question

Detect if audio is playing in browser Javascript.

This is not a duplicated; my question asks specifically for <iframe> audio detection whereas the related questions asks for all audio detection.

2 Answers

Unless the API allows it. For security reasons, you cannot.

This may not answer your question by the title (which I don't think is even possible), but it may solve your underlying problem. You could use YouTube's JavaScript API to detect if the audio is muted or just unmute it if desired:

var tag = document.createElement('script');

tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

var player;

function onYouTubeIframeAPIReady() {
  player = new YT.Player('ytplayer', {
    events: {
      'onReady': onPlayerReady,
      'onStateChange': onPlayerStateChange
    }
  });
}

function onPlayerReady(event) {
  event.target.playVideo();
}

function onPlayerStateChange(event) {
  if (event.data == YT.PlayerState.PLAYING) {
    console.log("isMuted = " + event.target.isMuted());
    event.target.unMute();
    event.target.setVolume(100);
  }
}
<iframe id="ytplayer" type="text/html" src="https://www.youtube.com/embed/dQw4w9WgXcQ?controls=0&showinfo=0&rel=0&enablejsapi=1" frameborder="0"></iframe>

Note that this snippet won't run properly on StackOverflow because it does not allow iframe elements. I tested it locally and it worked though.

You can find more information in the documentation (YouTube Player API Reference for iframe Embeds), such as configuration properties and all the functions available.

Related