Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sugarcube 2 Settings for music and call macros from JS code

edited December 2015 in Help! with 1.x
The question is about controlling audio by means of Settings API
From what i can see in docs there are only audio macros available and after looking at source code i found that it seems these macroses does not use any JS API for it so i assume there is none.

So question is it possible to execute macros from JS?

Of course i could copy-paste macros code from sources, but i would prefer to use up-to-date version of audio macros :)

For now i'm going to stick with following code:
var bgmHandler = function () {
	var cur_track = State.variables["current_track"];

	if (cur_track == null) return;

    if (settings.bgm) {
		 Macro.get("cacheaudio")
			  .tracks[cur_track]
			  .unmute()
    } else {
		 Macro.get("cacheaudio")
			  .tracks[cur_track]
			  .mute()
    }
};
/* Config menu */
Setting.addToggle("bgm", {
    label    : "Music",
    default  : true,
    onInit   : bgmHandler,
    onChange : bgmHandler
});

I'll appreaciate if someone can advise me of any more simple JS variants to interact with audio API

Comments

  • Douman wrote: »
    The question is about controlling audio by means of Settings API
    From what i can see in docs there are only audio macros available and after looking at source code i found that it seems these macroses does not use any JS API for it so i assume there is none.
    By using the mute()/unmute() methods, you're already using the (undocumented) AudioWrapper API. The wrapper mostly exists to smooth over browser inconsistencies and limitations within the HTMLAudioElement API (which is an extension of the HTMLMediaElement API).

    The <<cacheaudio>> macro does the initial setup of each piece of audio, then wraps it within an instance of AudioWrapper. From there, the <<audio>> macro really just uses the wrapper to control playback.

    The playlist is slightly different in that it clones the tracks entered into it, so that they may be controlled separately from the originals used by <<audio>>.

    Douman wrote: »
    So question is it possible to execute macros from JS?
    Yes. There are a couple of ways to do so.

    By instantiating the Wikifier:
    // new Wikifier(null, 'MARKUP HERE');
    
    // e.g.
    new Wikifier(null, '<<audio $current_track play>>');
    

    By using Wikifier.wikifyEval():
    // Wikifier.wikifyEval('MARKUP HERE');
    
    // e.g.
    Wikifier.wikifyEval('<<audio $current_track play>>');
    

    The difference between the two examples shown here is that the former eats errors, while the latter throws an exception upon encountering an error.

    Douman wrote: »
    For now i'm going to stick with following code:
    var bgmHandler = function () {
    	var cur_track = State.variables["current_track"];
    
    	if (cur_track == null) return;
    
        if (settings.bgm) {
    		 Macro.get("cacheaudio")
    			  .tracks[cur_track]
    			  .unmute()
        } else {
    		 Macro.get("cacheaudio")
    			  .tracks[cur_track]
    			  .mute()
        }
    };
    /* Config menu */
    Setting.addToggle("bgm", {
        label    : "Music",
        default  : true,
        onInit   : bgmHandler,
        onChange : bgmHandler
    });
    
    That doesn't mute new non-playlist audio playback, which will likely confuse the player (who probably expected the setting to silence all audio or, at least, all BGMs). It also doesn't affect the playlist, if you ever plan to use that.

    If you wanted to mute all non-playlist audio, you could do it like so:
    /*
    	Setup an audio muting toggle control setting.
    */
    var audioMuteHandler = function () {
    	// (Un)Mute all non-playlist tracks.
    	if (settings.muteAudio) {
    		Macro.get("cacheaudio").tracks.forEach(function (track) {
    			track.mute();
    		});
    	} else {
    		Macro.get("cacheaudio").tracks.forEach(function (track) {
    			track.unmute();
    		});
    	}
    };
    Setting.addToggle("muteAudio", {
    	label    : "Mute audio?",
    	default  : false,
    	onInit   : audioMuteHandler,
    	onChange : audioMuteHandler
    });
    

    If you wanted the setting to only mute BGM, while still allowing you to play other audio here and there, then you'd probably be better off by registering your BGM into the playlist and muting that instead. For example:
    /*
    	Setup a playlist muting toggle control setting.
    */
    var playlistMuteHandler = function () {
    	// (Un)Mute the playlist.
    	var playlist = Macro.get("playlist");
    	if (settings.mutePlaylist) {
    		playlist.muted = true;
    		playlist.mute();
    	} else {
    		playlist.muted = false;
    		playlist.unmute();
    	}
    };
    Setting.addToggle("mutePlaylist", {
    	label    : "Mute background music?",
    	default  : false,
    	onInit   : playlistMuteHandler,
    	onChange : playlistMuteHandler
    });
    
  • edited December 2015
    Thank you for good explanation. I will keep it mind and save this thread for future needs.

    I also wasn't planning to use more than just BGM and variable holds currently active track. Since it is set only via widget i thought it would be ok to do mute only on this current track
  • Douman wrote: »
    I also wasn't planning to use more than just BGM and variable holds currently active track. Since it is set only via widget i thought it would be ok to do mute only on this current track
    The problem with that is that you're only muting that one track, so if you have more than one BGM, then the rest will not be muted—contrary to both the implication of the setting and player expectation. The player would have to cycle the setting every time you played another BGM.
  • Douman wrote: »
    I also wasn't planning to use more than just BGM and variable holds currently active track. Since it is set only via widget i thought it would be ok to do mute only on this current track
    The problem with that is that you're only muting that one track, so if you have more than one BGM, then the rest will not be muted—contrary to both the implication of the setting and player expectation. The player would have to cycle the setting every time you played another BGM.

    Yes, i understand that :)
    The way i'm planning to do it is when track is going to be changed the previous one will be stopped completely

    Though i'll think about using playlist later on when there will be a lot of BGMs

Sign In or Register to comment.