0 votes
by (160 points)
Hello you wizards, I'm quite twine baby and I've built this great little twine game in Harlow 1.2.4. The game runs background music that runs great throughout my passages and loops perfectly through this Javascript code.

var audio = document.createElement('audio');

    audio.src = 'my source url';

    audio.loop = true;
    
    audio.muted = false;

    audio.play();

The problem is, my game throughout its story links to a few youtube videos and it's kind of distracting to have the background music playing while the external videos are playing while the player is in a different tab.

My question is,

How can I get my audio to stop playing when the player switches to a different window?

I read on stack exchange that I might be able to use the javascript command: document.hasFocus()

So I created an if statement:

if (document.hasFocus()) {
    
    var audio = document.createElement('audio');

    audio.src = 'my source url';

    audio.loop = true;
    
    audio.muted = false;

    audio.play();
}
else{
    document.getElementById('audio').muted = true;
    
}

But it doesn't work... Can anyone inform me of what I'm doing wrong?

Thanks in advance.

Your pal,

J

1 Answer

+1 vote
by (63.1k points)
selected by
 
Best answer

Something like this should work:

(function () {
	window.setup = window.setup || {};
	var sound = $(document.createElement('audio')).attr({
		src : 'http://www.kozco.com/tech/piano2.wav',
		loop : true
	});
	
	setup.audio = {
		$el : sound,
		el : sound[0]
	}
	
	$(window).on('blur', function () {
		sound[0].muted = true;
	});
	$(window).on('focus', function () {
		sound[0].muted = false;
	});
	
 }());

Note: A lot of browsers won't play your music until the user interacts with the page. You may need to create a splash screen of some type to get this to work better. For example:

# Welcome to My Awesome Game!

{
(link: 'Start the Game')[
    (set: _dummy to setup.audio.el.play())
    (goto: 'real first passage')
]
}

You can access you sound's element by setup.audio.el or setup.audio.$el (for a jQuery-wrapped version) and manipulate it in your Harlowe code by abusing (set:) macros as above.

Why your code didn't work. 

  • You weren't listening to any events or anything; your if statement was only ever going to be evaluated once.
  • For some reason you tried to grab the element by ID instead of just using the variable. The element didn't have an ID. And I don't think that would work even if it did, since the audio element was never attached to anything.
by (160 points)
reshown by
Thank you for the help, I really appreciate it!

My game has a title page, and I don't mind that the music starts on the second page (where the game actually starts if that solves the problem).

When I tried the block of code you suggested, my background audio never started playing altogether, even on the second page. I also tried the exact code with the piano audio, and didn't hear anything either :(

Also tried replacing my title page with your splash page including the macro and go:to the name of my second passage, and alas no luck.
by (63.1k points)

Sorry, I tested on Harlowe 2. Change

(set: _dummy to setup.audio.el.play())

To:

<script>setup.audio.el.play()</script>

 

by (160 points)
edited by
Bloody hell, it works perfectly. You're a saint.

I used the document.createElement part because I was just trying things I found on the internet tbh.

I'm gonna get a bit emotional here. You seem to be a huge contributor here and I'd like to say thank you for what you do and taking your time out to really help people. I know I really appreciate it, and your kindness doesn't go unnoticed.
by (63.1k points)
You're very welcome. Thanks for the kind words (and the Reddit gold) :) .
...