(TL;DR; Below)
I know this is an old post, but I needed help with a very similar issue. I had an AudioStreamPlayer2D
node with an imported OGG Vorbis resource. I imported it with looping (the default) and during the game I did want it to loop repeatedly in the scene it was playing in (an animated shop dialog scene), but after the dialog ended, I didn't want the loop to end abruptly with the stop function call and when the audio is looping it won't trigger the finished()
signal, so how could I get access to stop looping (after the animation and dialog finished), but let the sound play to completion first? After scrubbing the internet I found no answers, but trying a bunch of things, I finally found a simple two line solution:
var strm = $Music.stream as AudioStreamOGGVorbis
strm.set_loop(false)
Simply cast the stream resource as the class AudioStreamOGGVorbis
and then you have access to the set_loop
function. Then just set up the finished
signal code to do what you need when the sound finishes (in my case loading the next scene after finishing the shop keepers dialog and animations - either canceling or opening the shop menu). Not sure if this will work forever, but it does work with version 3.2.
For completeness, you can also access the similar option for a WAV resource by casting the stream as AudioStreamSample
and setting the loop_mode
property to one of the LoopMode
Constants called AudioStreamSample.LOOP_DISABLED
.
var strm2 = $Sound.stream as AudioStreamSample
strm2.loop_mode = AudioStreamSample.LOOP_DISABLED
But not looping is the default. What about starting a WAV sound looping from GDScript? It is a little more complicated as you need to not only set the loop_mode
with a constant, but you have to specify a starting point loop_begin
(in bytes) and a loop ending point loop_end
(also in bytes). This means you have to do a little math. You need to multiply the starting point and ending point in seconds by the mix_rate
property to get the bytes. The simplest case is below, looping the entire clip.
var strm2 = $Sound.stream as AudioStreamSample
strm2.loop_mode = AudioStreamSample.LOOP_FORWARD
strm2.loop_begin = 0
strm2.loop_end = strm2.get_length() * strm2.mix_rate
And finally, you can start an OGG resource looping (if it were imported without looping, or looping was previously disabled):
var strm = $Music.stream as AudioStreamOGGVorbis
strm.set_loop(true)
You can even have that sweet battle scene intro slide right into a battle loop by setting a loop offset with the property loop_offset
in seconds from the start. (Sorry, but no loop end for OGG Vorbis, but you can start a timer and then just use the stop()
function.)
strm.loop_offset = 10
TL;DR;
You can access the loop boolean on an AudioStreamPlayer2D
node playing an OGG Vorbis resource by simply casting the stream resource member on the node to AudioStreamOGGVorbis
and calling the set_loop
function. (At least in version 3.2) There is a similar cast for WAV, AudioStreamSample
, but it is slightly more complicated. See Above for details on both.
Reference: https://docs.godotengine.org/en/3.2/classes/class_audiostream.html#class-audiostream