Why is my music script playing multiple songs at the same time?

So I’ve been making a script to play music, but with the options for the player to ‘mute’ or ‘mute copyrighted’ songs within a moduleScript.

When the script starts, it generates a number for each of the songs, and then shuffles them in the appropriate order.

The ‘Mute Copyrighted’ setting is merely used for songs that I’m unsure would get content creators videos flagged or not. Just a safety precaution basically.

The problem that I’m running into is that when you uncheck/enable this setting multiple times, especially in quick succession, the songs seem to overlap for some reason.

I’ve tried yielding the script until the song had Ended/Stopped via Sound.Ended and Sound.Stopped, but no success there.

The ‘Mute’ setting works fine, but the ‘mute copyrighted’ is the issue here.

Here is the place file, as it is a module script.

Place2.rbxl (62.7 KB)

The moduleScript is located within ReplicatedFirst and is inside of the localScript.

The script listens to the attribute changes of the players playerObject. So to test, simply just check/uncheck those attributes.

I don’t know if I’m just tired, but it’s driving me insane, as I’ve been trying to problem-solve for the past few hours. I need a hero!!!

1 Like


This seems rather overcomplicated, what are you trying to do here?

You can’t upload or use copyrighted songs on roblox, if you do that’s against TOS

You may use them if you have the license(s) required, problem is those licenses might not cover recordings of your game, or more commonly, automated systems (Content ID) claiming videos regardless, which is a major headache for content creators.

Doubt he got permission to use a song, if he doesn’t even know if any of them are copyrighted

Well they’re probably from the creator marketplace; post audio update, it’s more likely they do have the license required. Still, automated systems can’t really tell (AFAIK) the difference, so they still get claims.

But back to solving OP’s problem:
High chance they’re running into a race condition, but I can’t tell exactly what it is, might want to consider rewriting it to be simpler, you don’t need to make everything a complicated OOP module!

It’s as Nowoshire stated. Basically even though some of the audio’s that have been uploaded to Roblox via those sound libraries are licensed for game-use, it doesn’t necessarily mean that we have the license to use those in videos on Youtube and the like.

Had a friend get a video claimed due to this :sweat_smile:

The ‘Sound’ object doesn’t seem to have a definitive “The sound has finished, whether it was done via :Stop() or it’s playback concluded”, so I’ve had to account for both scenarios, which is why I am using a boolean value to yield until one of those conditions is met.

@nowodev Hey I managed to fix it finally. The issue was that I had been relying on a “Holding” variable at the top of the script. At times, especially when switching the flag on and off, the while holding do loop wouldn’t always turn off.

I solved it by instead of relying on said loop, I created a bool each time the start function is called, and when it is destroyed, the loop breaks.

Nevertheless, I really appreciate you for taking the time to look over the script :grin:

--// Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

--// Variables
local Player : Player = Players.LocalPlayer

local Shared = ReplicatedStorage.Shared

--// Tables
local OST = script.OST:GetChildren()

--// Modules
local Assistant = require(Shared.Assistant)
local Music = {}

--// Functions
function Music:Start()
	Music:StopAll()
	
	local Listener = Instance.new("BoolValue")
	Listener:SetAttribute("Start", DateTime.now().UnixTimestampMillis)
	Listener.Parent = script.Holder
	
	local Holding = true
	
	Listener.Destroying:Once(function()
		Holding = false
	end)
	
	task.spawn(function()
		while Holding do
			if not Holding then
				break
			end

			Music:Shuffle()
			
			for _, sound : Sound in OST do
				if not Holding then
					break
				end
				
				if Player:GetAttribute("Video") then
					if sound:GetAttribute("IsCopyright") then
						continue
					end
				end

				sound:Play()
				
				local _Ended = coroutine.create(function() -- For when the song finishes playback, open val 'gate'
					sound.Ended:Wait()
					print("ENDED")
					
					Music.OnFinished()
				end)
				
				local _Stopped = coroutine.create(function() -- For when the song is forcefully stopped, open val 'gate'
					sound.Stopped:Wait()
					print("STOPPED")
					
					Music.OnFinished()
				end)
				
				coroutine.resume(_Ended)
				coroutine.resume(_Stopped)

				script:GetAttributeChangedSignal("SongFinished"):Wait() -- Value to wait for. i.e. the 'gate'
				

				sound:Stop()
				
				if coroutine.running(_Ended) then
					coroutine.close(_Ended)
				end
				
				if coroutine.running(_Stopped) then
					coroutine.close(_Stopped)
				end
				
			end
			
			task.wait(1)
		end
	end)
end

function Music.OnFinished()
	Assistant:SwitchFlag(script, "SongFinished")
end

function Music:StopAll()
	for _, sound in OST do
		if sound:IsA("Sound") then
			sound:Stop()
			sound.TimePosition = 0
		end
	end
end

function Music:Stop()
	Music:StopAll()
	
	for _, v in pairs(script.Holder:GetChildren()) do
		local started = v:GetAttribute("Start") or 0
		
		if DateTime.now().UnixTimestampMillis > started then
			v:Destroy()
		end
	end
end

function Music:Shuffle()
	local Places = {}
	
	for looping = 1, #OST do
		table.insert(Places, looping)
	end
	
	for _, sound in OST do
		if sound:IsA("Sound") then
			local randomIndex = math.random(1, #Places)
			sound:SetAttribute("Order", Places[randomIndex])
			
			table.remove(Places, randomIndex)
		end
	end
	
	table.sort(OST, function(a, b)
		return a:GetAttribute("Order") < b:GetAttribute("Order")
	end)
	
	Places = nil
end



--// Script
return Music

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.