Music Module Help

I found this Module as a Free Model last month by the user of Bruce and I’ve been trying to figure it out, but it’s just been giving me some issues. The person left a LocalScript which requires the module and calls the StartUp() function.

My issue:

  1. When the module finds a deleted sound it just loops another sound.
  2. When the module is done playing the sounds if it even works, then it just loops the last sound.

I don’t know this Module been giving my issues and I need to start searching for another free module since I’m not super experienced in making a complex module like this.

The Playlist Module:

return {{
	SongArtist = "none1",
	SongName = "deletd",
	ID = 0 --redacted (is number, is actually a deleted sound)
}, {
	SongArtist = "none2",
	SongName = "error sfx",
	ID = 0 --redacted (is number, not deleted sound)
}, {
	SongArtist = "none3",
	SongName = "correct sfx",
	ID = 0 --redacted (is number, not deleted sound)
}, {
	SongArtist = "none4",
	SongName = "place sfx",
	ID = 0 --redacted (is number, not deleted sound)
}}

Music Controller Module:

local MarketplaceService = game:GetService("MarketplaceService")

local function MusicRemover(Sound, ...)
	local Table = {}
	local Value = 0
	while not Table[1] and Value < 3 do
		Table = {pcall(Sound, ...)}
		Value = Value + 1
	end
	return table.remove(Table, 1), unpack(Table)
end

local AudioDetails = {
	Playlist = require(script.DefaultPlaylist), 
	TestAudio = Instance.new("Sound", workspace), 
	Audio = workspace:WaitForChild("Music"), 
	CurrentMusic = 0
}

local function CurrentMusicPlaying(Sound)
	if Sound == nil then return false end
	local ProductInfo = MusicRemover(MarketplaceService.GetProductInfo, MarketplaceService, Sound)
	local SoundName = MarketplaceService:GetProductInfo(Sound)
	if not ProductInfo then
		return false
	end
	if SoundName then
		if string.find(SoundName.Description, "removed") or string.find(SoundName.Description, "Removed") or string.find(SoundName.Name, "removed") or string.find(SoundName.Name, "Removed") then
			return false
		end
	else
		return false
	end
	if not MusicRemover(function()
			AudioDetails.TestAudio:Stop()
			AudioDetails.TestAudio.SoundId = "rbxassetid://"..tostring(Sound)
			AudioDetails.TestAudio:Play()
		end) then
		return false
	end
	task.wait(2)
	return AudioDetails.TestAudio.IsPlaying
end

local function AudioPlaylistDetails(Details)
	local Table = {}
	math.randomseed(os.time())
	for _, Insert in ipairs(Details) do
		table.insert(Table, math.random(1, #Table + 1), Insert)
	end
	return Table
end

local function AudioSetup()
	local MusicDetails = nil
	AudioDetails.Audio:Stop()
	AudioDetails.Audio.TimePosition = 0
	if not AudioDetails.Playlist[AudioDetails.CurrentMusic + 1] then
		AudioDetails.Playlist = AudioPlaylistDetails(AudioDetails.Playlist)
		AudioDetails.CurrentMusic = 0
		AudioSetup()
		return
	end
	MusicDetails = AudioDetails.Playlist[AudioDetails.CurrentMusic + 1]
	if not CurrentMusicPlaying(AudioDetails.Playlist[AudioDetails.CurrentMusic + 1].ID) then
		table.remove(AudioDetails.Playlist, AudioDetails.CurrentMusic + 1)
		AudioSetup()
		return
	end
	AudioDetails.CurrentMusic = AudioDetails.CurrentMusic + 1
	AudioDetails.Audio:SetAttribute("SongName", MusicDetails.SongName)
	AudioDetails.Audio:SetAttribute("SongArtist", MusicDetails.SongArtist)
	AudioDetails.Audio.SoundId = "rbxassetid://" .. MusicDetails.ID
	AudioDetails.Audio:Play()
	return true
end

function AudioDetails.StartUp()
	AudioDetails.TestAudio.Name = "TestMusic"
	AudioDetails.TestAudio.Volume = 0
	AudioDetails.Audio.Ended:Connect(function()
		AudioSetup()
	end)
	AudioDetails.Playlist = AudioPlaylistDetails(AudioDetails.Playlist)
	AudioSetup()
end

return AudioDetails

The Local Script:

require(game.ReplicatedStorage.MusicControllerModule).StartUp()
2 Likes

What exactly are you wanting to do with a “music module”?

I have a Playlist with sound ID’s and I want the Music Module to play music from the Playlist, and once a song is done it just removes it, plays the next song till there are no more songs left to prevent looping of music, and once three’s no more audios left, it resets!

You could always make a script (either client or server sided, depending on if you want everyone to have the same music playing at the same time or not), which has all of the music you’d like to play. To check if an audio is removed from Roblox, you could check if the audio’s TimeLength is 0 (which is the case when an audio is removed). If you have a shuffled playlist, you can just use math.random(1,#audios) (or whatever the table containing the IDs is), but if you have an ordered playlist, you can loop through all audios using a for loop, keeping track of the index of the current audio, and if the index of the for loop is the index of the final audio, the next iteration we can reset the index to 1.

Sorry I really am not that advanced and so this kind of coding would be out of my range. If you could show me some code that would be a really good push.

Well i am not home right now so I cant make any code, but once I get home I will make sure to make some example codes

1 Like

If anyone has any ideas please let me know. Been trying to find this guy who posted the module but I can’t see to find anything now…

Here is some code for a music playlist system:

--Name the script MusicScript, and put it in a Frame parented to a ScreenGui. 
--Also, add 2 TextLabels in the frame, one will display the current music name
--The other the time and length of the music
local shuffled = script:FindFirstChild("Shuffled").Value --boolean to toggle shuffled mode on/off
local trackLabel = script.Parent:FindFirstChild("TrackLabel") --displays the current music
local timeLabel = script.Parent:FindFirstChild("TimeLabel") --displays the time and length of the track

local c = nil

local function formatTime(t)
	local m = math.floor(t/60)
	local s = t % 60 < 10 and "0"..t % 60 or t % 60
	return m,s
end

local function updateText(sound)
	local cm, cs = formatTime(math.floor(sound.TimePosition))
	local lm, ls = formatTime(math.floor(sound.TimeLength))
	timeLabel.Text = cm..":"..cs.."/"..lm..":"..ls
end

local playlist =
	{
		--put all of your music IDs here. Put them as numbers, separated by commas. Optionally add each into a separate line, and add comments as the track titles.
	}

local lastTrack = 0 --the index of the last track played. Used to stop tracks from playing twice in a row in shuffle mode.
while wait() do
	local soundId = 0
	local sound = Instance.new("Sound",script)
	if shuffled then
		local rand = 0
		repeat rand = math.random(1,#playlist) until rand ~= lastTrack --makes a new random until it isn't equal to the last track
		sound.SoundId = "rbxassetid://"..playlist[rand] --chooses random music
		soundId = playlist[rand]
		sound:Play()
		--Getting info about the music
		local mps = game:GetService("MarketplaceService")
		local info = mps:GetProductInfo(soundId,Enum.InfoType.Asset)
		local name = info.Name
		local creator = info.Creator --Optional, you can add this in a TextLabel similar to the name
		trackLabel.Text = name
		c = game:GetService("RunService").Stepped:Connect(function()
			updateText(sound)
		end)
		sound.Ended:Wait()
		c:Disconnect()
		sound:Destroy()
		lastTrack = rand
	else
		local currentTrack = lastTrack + 1

		sound.SoundId = "rbxassetid://"..playlist[currentTrack]
		soundId = playlist[currentTrack]
		sound:Play()
		--Getting info about the music
		local mps = game:GetService("MarketplaceService")
		local info = mps:GetProductInfo(soundId,Enum.InfoType.Asset)
		local name = info.Name
		local creator = info.Creator --Optional, you can add this in a TextLabel similar to the name
		trackLabel.Text = name
		c = game:GetService("RunService").Stepped:Connect(function()
			updateText(sound)
		end)
		sound.Ended:Wait()
		c:Disconnect()
		sound:Destroy()
	end
end

BTW I totally didn’t test this if it works, so tell if anything is not working. Make sure to set up the GUI correctly, and that the script is indeed a LocalScript.

Was it solved? (character limit)

I’m sorry I haven’t had enough time recently to try this out, but when I do I will update you, and thank you for the script!