I looked into TimeLength and it just doesn’t seem to be a reliable solution either, since sometimes the audio takes longer than even 0.5 seconds to load. I’ll try and tinker with it to see if I can make it work, though.
edit: I know 0.5 isn’t a very long time but I prefer it to be seamless between songs. If all else fails, this could work as a solution if I up the time to maybe 1 second.
local audios = {578934892, 578934892, 578934892}
for i, audio in pairs (audios) do
spawn(function()
local sound = Instance.new("Sound", game.Workspace)
sound.SoundId = "rbxassetid://"..audio
sound:Play() -- for good measure
wait(5)
if sound.TimeLength < 0.05 then
-- audio is not playable, remove from list.
table.remove(audios, i)
end
wait(1)
sound:Destroy()
end)
end
Spawn functions create an extra thread that runs in the background. Therefore you can check all of these audios at the same time.
You could run this at the beginning of every server, without the sound:Play(), then save the result to a datastore entry to make sure removed audios aren’t checked again.
I tried this out and it appears that it just removes almost all of the sounds from the list…
I think it does this because Roblox will only load one sound at a time, so trying to load them all at once with a spawn function means that a lot of them get left out.
edit: I think the best solution so far is checking the TimeLength after a second rather than 0.1.
I tried using a pcall’s message property to check for the “Failed to load” text but unfortunately it doesn’t count that type of warning as part of the pcall so it continues normally.
Thanks for your help, I’ll try looking into more solutions and I’ll let you know what I find.
Hey, I recently had this problem too with a music system I scripted which allowed requests. The best way I found was using LogService.MessageOut. I was then just able to search the error messages output which contained Sound %location% Failed to load %soundId%:
local sound = game:GetService("Workspace"):WaitForChild("Sound")
local failString = "Sound "..sound:GetFullName().." Failed to load"
game:GetService("LogService").MessageOut:Connect(function(msg,msgType)
if msgType == Enum.MessageType.MessageError then
if string.find(msg,failString,1,true) then
-- Handle content deleted audio here.
end
end
end)
Hope this helps! It’s worked for me without any problems so far, but I fear that some audios fail to load for people on slow connections. Nonetheless, they would probably rather have smoother gameplay than have audio playing.
Just ran the code provided on the Wiki, made the error appear saying that the sound failed to load and as I suspected, it did not print anything out. ScriptContext.Error used for getting the context of errors thrown by scripts, not all error messages come from scripts. In this case the error has no script context (not an external one anyway), which means that the event won’t be fired.
There presently isn’t a way to detect if an item is deleted or not. Using GetProductInfo from MarketplaceService is only effective for deleted content that isn’t later edited. Audios that are deleted can still have their names and descriptions changed and you won’t be able to flush those out. Any error tracking method is mostly only from source containers and “Sound failed to load” is an error produced from the backend, which you can’t access, read or track.
For audios, though, you can see if it has been deleted if you load the ID into a Sound object and see if the TimeLength property has changed after a couple seconds. Although this isn’t seamless, it works.