0 votes
by (960 points)

I have a macro set up that will stop all audio and then play a supplied song.

<<widget "ChangeMusic">>
    <<masteraudio stop>>
    <<audio $args[0] play loop volume 0.25>>
<</widget>>

I would like to check if the song in $arg[0] is already playing so that I can't cut the song off and play it from the beginning.

Kinda like (pseudo-code)

<<widget "ChangeMusic">>
    <<if $args[0] != CurrentlyPlaying>>
        <<masteraudio stop>>
        <<audio $args[0] play loop volume 0.25>>
    <</if>>
<</widget>>

 

1 Answer

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

If you add the following code to your JavaScript section:

// Check to see if trackID is the currently playing track
window.isPlaying = function (trackID) {
	var track = SimpleAudio.tracks.get(trackID);
	return track !== null && track.isPlaying();
};

or, if you're using an older version of SugarCube, prior to v2.28.0, use this JavaScript instead:

// Check to see if trackID is the currently playing track
window.isPlaying = function (trackID) {
	var tracks = Macro.get("cacheaudio").tracks;
	if (tracks.hasOwnProperty(trackID)) {
		var currentTrack = tracks[trackID];
		if (!currentTrack.audio.paused && currentTrack.audio.duration) {
			return true;
		}
	}
	return false;
};

Then you could do:

<<widget "ChangeMusic">>
    <<if !isPlaying($args[0])>>
        <<masteraudio stop>>
        <<audio $args[0] play loop volume 0.25>>
    <</if>>
<</widget>>

You can see other Twine/SugarCube audio sample code here, including a more advanced "PlayTrack" widget which you can use to make sure that the audio is cached as well (click "Jump to Start" in the UI bar to see a variety of other sample code there).

Hope that helps!  :-)

by (960 points)

Thanks for the answer! Unfortunately no matter how much I fiddle with it, I always get this error

Error: <<ChangeMusic>>: error within widget contents (Error: <<if>>: bad conditional expression in <<if>> clause: tracks is undefined)

I don't know if it's due to API changes or if I'm just not doing it correctly.

by (44.7k points)

Yup, sorry about that.  The SugarCube audio API changed in v2.28.0, so for that version or later you'll have to use this code instead:

// Check to see if BGM is the currently playing background music
window.isPlaying = function (BGM) {
	var track = SimpleAudio.tracks.get(BGM);
	if (track != null) {
		if (!track.audio.paused && track.audio.duration) {
			return true;
		}
	}
	return false;
};

I updated the other audio sample code as well.

Enjoy!  :-)

by (68.6k points)

If you're going to use the, as yet undocumented, new SimpleAudio API, then you're better off just using it, rather than depending on its implementation details.  For example, that would be better as:

window.isPlaying = function (trackId) {
	var track = SimpleAudio.tracks.get(trackId);
	return track !== null && track.isPlaying();
};

 

by (960 points)
Oh, this is great! Thank you guys so much! I was digging around in the Sugarcube 2 repo trying to figure this out but I think I was in over my head, sadly.

Would one of you either append that to the answer or submit it as a new one so I can mark it as the solution for anyone who stumbles in via Google?
by (44.7k points)
Edited the original answer to include the code that works with the current version of SugarCube.
by (960 points)
Thank you again!
...