Skip to content

Instantly share code, notes, and snippets.

@parsehex
Last active January 13, 2018 20:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save parsehex/eae6a1b89e81d5f395905cf4fac02937 to your computer and use it in GitHub Desktop.
Save parsehex/eae6a1b89e81d5f395905cf4fac02937 to your computer and use it in GitHub Desktop.
Fix/workaround for PC throttling
// tested working in
// chrome (canary) v65
// chrome v63
// firefox v57
var alertSound = document.getElementById('alert-sound');
var audioFixStarted = false;
// uses the same test that PC uses
var scriptHidden = false;
function detectUnfocus() {
// console.log('checking focus');
var previousTime = (detectUnfocus.savedTime) || new Date().getTime();
detectUnfocus.savedTime = new Date().getTime();
if ((detectUnfocus.savedTime - previousTime) > 900) {
scriptHidden = true;
if (!alertSound) console.log('script hidden');
} else {
scriptHidden = false;
if (!alertSound) console.log('script not hidden');
}
update();
}
function addExternalScriptCheck() {
gExtInterval = setInterval(detectUnfocus, 500);
}
addExternalScriptCheck();
// set up and play a quiet low-frequency sound
// browsers won't throttle tabs playing audio
function setupFixSound() {
// don't need to run this more than once
if (audioFixStarted) return;
audioFixStarted = true;
// this comes from the examples on https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Using_Web_Audio_API
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var oscillator = audioCtx.createOscillator();
var gainNode = audioCtx.createGain();
oscillator.connect(gainNode);
gainNode.connect(audioCtx.destination);
// could try other types besides sine wave
// triangle sounds okay
oscillator.type = 'sine';
// this seems to be about the lowest volume before the browser ignores the sound
// tested it by lowering and checking if the sound icon showed up on the tab
// gainNode.gain.setTargetAtTime(0.1, audioCtx.currentTime, 0.1);
gainNode.gain.setTargetAtTime(0.0004, audioCtx.currentTime, 0);
// picked a low frequency to make it less noticeable
// too low and i noticed some audio 'crackling'
// with 100 there's a slight crackle when the sound starts but that's it
oscillator.frequency.setTargetAtTime(100, audioCtx.currentTime + 1, 0.5);
// oscillator.frequency.setTargetAtTime(100, audioCtx.currentTime + 0.1, 0.5);
oscillator.start();
// debugging:
window.stop = function () {
oscillator.stop();
};
}
// in later chrome versions, there has to be a user gesture on the page before audio is allowed to play
// clicking in the page works, even pressing a key on the page works
// don't need to listen for the event but you may get errors otherwise
// this also works for playing <audio> tags like in update() below
window.addEventListener('click', setupFixSound);
window.addEventListener('keypress', setupFixSound);
// setupFixSound();
function update() {
if (alertSound && scriptHidden) alertSound.play();
else alertSound.pause();
}
<html>
<head>
<meta charset='utf-8'>
</head>
<body>
<!-- nothing special, just an mp3 used as an alert if tab is unfocused -->
<!-- i used one of the beeps from https://www.soundjay.com/beep-sounds-1.html but it doesn't matter -->
<!-- remove element to just use console.log -->
<audio id='alert-sound' src='./beep.mp3'></audio>
<script src='script.js'></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment