Need help checking songs for a song request system

I am trying to make a function that checks songs that players request. Before a song goes through this function, we have no clue if it will play or if it is appropriate.

Only, I am having some issues. Nothing after the PreloadAsync will run.

Is there some other way to check if a song can load? I also need this to make sure a song is not content deleted. I have labelled the prints in the following code.

I have already tried creating a new sound object, setting the sound ID and waiting to see if the TimeLength will change from zero; this always returned "Failed to load."

Thanks,
Winky.

(I am also looking for more terms to filter, if you have any ideas please let me know in the replies.)

function checkSong(id)
	local loaded = false
	
	local function loadedfunc()
		loaded = true
	end
	
	print("running") -- prints
	
	game:GetService("ContentProvider"):PreloadAsync({"rbxassetid://" .. tostring(id)}, loadedfunc())

	print(loaded) -- does not print
	
	if not loaded then return "Failed to load." end
	
	for _, term in pairs({"loud", "volume", "warning", "bypass", "earrape", "airrape", "troll"}) do
		if string.match(game:GetService("MarketplaceService"):GetProductInfo(id), term) then 
			return "Song is potentially inappropriate."
		end
	end
	return true
end
1 Like

Try adding a wait() between the print and the preload, if that doesn’t work, then try printing out the id you’re trying to preload, to make sure it is valid.

The ID is checked before it goes into the function… what do you mean by valid? You mean like if it is a number? The reason for the preload is to make sure the ID given leads to an asset.

I can try the wait but I do not think it will do anything…

When you preload a song, sometimes it fails because:

  1. Fails to preload unexpectedly.
  2. The song isn’t available.

You can use #2, but it may not give a 100% response.

Valid, as in it is a number and it exists in the Library. The reason why I suggested you print out the id, is because sometimes the way you call a function can mess up the arguments (in my experience).

Another thing, PreloadAsync doesn’t work for me 75% of the time I use it, so I would suggest finding another solution, such as using a sound object, eg.

local loadSound = Instance.new("Sound") -- the new sound
loadSound.SoundId = "rbxassetid://"..id -- put in the sound id

if (not loadSound.IsLoaded) then -- if it isn't already loaded
    loadSound.Loaded:Wait() -- yields until the sound is loaded
    loadSound:Destroy -- clean up the sound, since we don't need it anymore
end
-- do checks

Like I said in the original post… nothing past the preload works.

How would I detect if the song doesn’t load using your method?
I’ve tried using a sound object and it did not work for me.

Whoops, I didn’t think about that :sweat_smile:. Maybe try using MarketPlaceService? Like so:

local MPS = game:GetService("MarketPlaceService")
local id = 0 -- ID

local success, songData = pcall(function()
      return MPS:GetProductInfo(id)
end)
if (success) then -- song loaded
    print("Song loaded successfully!")
    local name = songData.Name -- do your checks with this
else -- song didn't load
    print("Song failed to load")
end

P.S sorry for the late reply i was busy

Thing is, even is a song is deleted it will still load using MarketPlaceService. If the song is deleted, the name will just load as something like “[ Content Deleted ]” or “(Removed for copyright)”.

Well then, I wish you good luck solving that! :smiley: Unfortunately, I’m a bit busy for the next few weeks, so I don’t have much time on my hands. I hope the code samples I provided will help you greatly!

Have a nice day!

I’ve actually fixed this on my own. Let me share the code with you…

function checkSong(id)
	local loaded = false
	
	if game:GetService("MarketplaceService"):GetProductInfo(id).Name == "(Removed for copyright)" or game:GetService("MarketplaceService"):GetProductInfo(id).Name == "[ Content Deleted ]" then return "Song was removed." end
	
	local loadSound = Instance.new("Sound") -- the new sound
	loadSound.SoundId = "rbxassetid://"..id -- put in the sound id
	loadSound.Parent = workspace
	loadSound.Name = id
	loadSound.Volume = 0
	loadSound:Play()
	
	if (not loadSound.IsLoaded) then
		loadSound.Loaded:Wait()
	end
	
	if loadSound.TimeLength < 0.5 then
		return "Failed to load."
	end

	
	for _, term in pairs({"loud", "volume", "warning", "bypass", "earrape", "airrape", "troll", "give you up", "rick", "moaning"}) do
		if string.match(string.lower(game:GetService("MarketplaceService"):GetProductInfo(id).Name), term) then 
			return "Song is potentially inappropriate."
		end
	end
	
	if table.find(queue, id) ~= nil then return"Song is already in queue." end
	return true
end

:smile:

2 Likes

Awesome! You did a really good job! Just a few things:

You might wanna delete the sound after you use it, because if you keep it, it could cause some server lag. Parenting the sound to workspace might cause some lag aswell, so I suggest putting it in the ServerStorage.

Good day!
:smiley:

Thanks for your feedback. I will take that into consideration.

Nobody ever pointed out the fact you were calling your callback function (loadedfunc) rather than passing it directly:

-- Wrong (this calls loadedfunc rather than passing it)
:PreloadAsync({"rbxassetid://" .. tostring(id)}, loadedfunc())
-- Correct:
:PreloadAsync({"rbxassetid://" .. tostring(id)}, loadedfunc)

(Removed the first bit of the line so you don’t have to scroll to see the issue)

1 Like

Oh… Thanks for that. I wasn’t really sure what the correct way to write that function.