00:00
00:00
3p0ch
If you like hard games try my Daxolissian System series

plasmid @3p0ch

Cat

Scientist

Read the manual & try stuff

So Cal

Joined on 2/13/10

Level:
13
Exp Points:
1,708 / 1,880
Exp Rank:
38,051
Vote Power:
5.50 votes
Audio Scouts
1
Rank:
Portal Security
Global Rank:
23,483
Blams:
50
Saves:
377
B/P Bonus:
8%
Whistle:
Normal
Medals:
4,732
Supporter:
3y 10m 5d

Running music in Godot through Howler.js if it plays horribly in Chrome from Audio nodes

Posted by 3p0ch - March 10th, 2021


I'm about to publish Daxolissian System: Espionage tomorrow, and last night I went back to play the game again and had a pretty bad surprise: the music that had been playing just fine was now so choppy and slowed down that the game was at best an unpleasant experience if not outright unplayable without muting it. And seeing as how I invited a bunch of participants in the NewGrounds Video Game Music Challenge to have their music showcased in the game, that simply wouldn't do. I managed to get a solution working and it was more complex than I would've liked, so I'ma write out the approach here while it's still fresh in memory in case anyone else runs into the same problem with music in Godot (or in case I need to do it again and can't remember how).


The solution was to use howler.js which can be gotten from github. I credit FernandoValcazara with coming up with the idea, and he posted a link to an implementation here but I couldn't get that implementation to work in my game. Instead I took the howler.core.js file from github and put it in the game's build directory (not the Godot project directory, but the directory where the index.html file will be made). I had a custom html template set up to add the background image during the loading screen (I'll add a note at the end on how to do that), and I added the following line to load howler.js just after the line where it loads your Godot js file.

  <script type='text/javascript' src='$GODOT_BASENAME.js'></script>
  <script type='text/javascript' src='howler.core.js'></script>

and soon after that in the JavaScript code, I added variables for each song like so

    var engine = new Engine;
    var setStatusMode;
    var setStatusNotice;
    
    var binary_lightning_strike = new Howl({src: ['binary_lightning_strike.ogg'], loop: true});
    var class_s_debris          = new Howl({src: ['class_s_debris.ogg'],          loop: true});

etc with one Howl variable for each song. Then I moved the actual music files to the game's build directory too and deleted them from the Godot project. In retrospect, instead of deleting the music files from the Godot project, it would've been better to just exclude them from the build by going to the Export screen, Resources tab, and excluding all .ogg files.


Then in the GDScript code, I previously had an AutoLoad set up to be a music player, and I just changed its functions to

func start_playing(track_name):
	JavaScript.eval("if (!" + track_name + ".playing()) {" + track_name + ".play();}")

func stop_playing():
	JavaScript.eval("Howler.stop();")

func _physics_process(delta):
	if Input.is_action_just_pressed("ui_mute"):
		muted = not(muted)
		JavaScript.eval("Howler.mute(" + str(muted) + ");")

Again, I did this because I'm ready to publish, but if you're not in the same situation then you might want to do

func whatever():
	if OS.has_feature('JavaScript'):
		# This implementation
	else:
		# Normal implementation


And now the music plays great on Chrome, Edge, and Firefox. I'm still not sure what made the music suddenly play like crap in the first place, and why it affected Chrome and Edge but not Firefox, and only affected the Godot component of the game and not the HaxeFlixel component. I do know it's probably not because of excessive memory usage in the Godot component of Daxolissian System because I made an empty project with just an AudioStreamPlayer node playing the intro music and it still sounded horrible. So it's weird as all get-out but at least it's fixed now.


Oh yeah, I said I would explain how I added a picture to the Godot loading screen. In the index.html template (you can get the default template from Godot's website) I just changed this block

    body {
      touch-action: none;
      margin: 0;
      border: 0 none;
      padding: 0;
      text-align: center;
      background-color: black;
      background-image: url(boot_splash.png);
      background-repeat: no-repeat;
    }

and put my boot_splash.png file in the build directory right next to the index.html file. Save that html template file somewhere in your Godot project like in res://html/custom.html and in Godot on the Export screen after you pick HTML there's a box for Custom Html Shell where you can pick your html template file.


Tags:

2

Comments

This worked! Thanks a lot!