Music playlist loop

I am trying to make a soudtrack playlist for my game but i cannot seem to get more than one song to play in a row.

here is my current code:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Soundtracks = ReplicatedStorage:WaitForChild("Audio"):WaitForChild("Soundtracks")
local songs = {}

function playSong(song)
	Soundtracks[song]:Play()
end

function findSongs()
	for i,v in pairs(Soundtracks:GetChildren()) do
		table.insert(songs, v.Name)
	end
end

function getRandomSong()
	local i = math.random(1, #songs)
	return songs[i]
end

findSongs()
wait(1)
local i = getRandomSong()
playSong(i)
9 Likes

Can you not just make a while true do loop?

1 Like

ah, ok. so, how would i make it so it only plays once the current song has finished?
otherwise it would cause mass ear-explosions

To loop the music you should take a look at this:

Here you can do so that when the song has ended it will select a new one.

i.Ended:Connect(function()
    i = getRandomSong()
    playSong(i)
end)
1 Like

how would i get the song that is currently playing tho?

You should be check Sound Objects | Documentation - Roblox Creator Hub @Reset4319806 :wink:

The i variable is the song currently playing. Look at my reply for the code.

[ReplicatedFirst.SoundtrackPlay:25: attempt to index field 'Ended' (a nil value)]

Please include your current code so it’ll be easier to debug it

1 Like

I have not tested this code but would this maybe work?

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Soundtracks = ReplicatedStorage:WaitForChild("Audio"):WaitForChild("Soundtracks"):GetChildren()

function getRandomSong()
	return Soundtracks[math.random(1, #songs)]
end

local song = getRandomSong()
song:Play()

song.Ended:Connect(function()
    song = getRandomSong()
    song:Play()
end)

The issue with the provided code is that it doesn’t loop. The functions work perfectly (although there are some things that can be improved upon), but as soon as the first song ends… Silence.


Solution
Okay, how do we fix this? It’s actually quite simple! The sound class comes with a couple of life-savers too, such as the .Ended event which fires upon the sound ending.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Soundtracks = ReplicatedStorage:WaitForChild("Audio"):WaitForChild("Soundtracks"):GetChildren()
--:GetChildren() returns an array, no need to index it!

function getRandomSong()
	local i = math.random(1, #Soundtracks)
	return Soundtracks[i]
end

function playSong()
    local Song = getRandomSong() --Get a new song.
	Song:Play() --Start the tunes!

    Song.Ended:Wait() --Wait for the song to end
    playSong() --Reinitialize the function.
end

playSong() 

A couple of notes:

  • :GetChildren() returns an array, making the entire findSongs() business unnecessary.
  • Recursion! The playSong() function will now call itself when it finishes a song, which resolves the issue with no new songs playing.

Feel free to ask questions!

5 Likes

I’ve heard some bad stuff about wait() and that specifically using it without any parameters can cause problems with some kind of back-end execution stuff. I like the recursion but isn’t it better to use

song.Ended:Connect(function())

,that plays the next song?

I believe you’re confusing the global function with the wait used with events. Wait:() in the context of an event is ideal, it pauses the thread until the event fires.

Recursion can be an issue when a function calls itself a lot and within a short time frame. The example you provided does the same thing as what I provided - the event will still (although implicitly) call itself, creating recursion.

2 Likes

I suggest u making a “Counter” variable to keep track of your audios. U can easily loop through the script get all the songs table insert them then do Sounds[Count]:Play() wait till it ends and update the counter :+1:

1 Like

Lines of code other than functions will repeat only a time, try do while true do --code-- end