Checking if a game can use an audio with SoundService:CanUseAudioAsync

As a developer, it is currently nearly impossible to detect if a game is allowed to use an audio. With the unfortunate (but reasonable) introduction to audio permissions, players who own radio gamepasses are left in the dark. When they play an invalid ID, the audio simply does not play.

Instead, I’d like to notify players if their audio won’t play, but that by itself deals with using a quite hacky method using LogService (which i have included below to those who would like to see/use it :smiley:

Here’s my proposal: the function SoundService:CanUseAudioAsync that returns true/false depending on whether a game is allowed to play the audio provided.

In example:

print(game.SoundService:CanUseAudioAsync(234234423)) -- false, since the audio is longer than 7 seconds.
print(game.SoundService:CanUseAudioAsync(9245552700)) -- true, since any game can use parry gripp songs
11 Likes

Can’t you do this yourself by using pcall, checking if an error occurred, and checking the error message? Sure, a built in method would be nice, but it’s already possible to do

1 Like

This is not the case, sound loading errors do not return false to any pcalls

4 Likes

So, I was playing around a bit with various ways of validating whether an audio could be loaded, and I found MarketplaceService:GetProductInfo to be a good substitute in the meantime.

The premise is that if the Audio is tagged as ‘IsPublicDomain’, then it can be assumed that the game will have the technical permissions to load it. This isn’t a 1:1 replacement for the feature being requested (as ownership rules can get considerably complex when it comes to private audios uploaded by the game’s developers), but for the purpose of giving feedback to users of radio gamepasses, I think it should suffice.

Proof of concept
local MarketplaceService = game:GetService("MarketplaceService")

local function CanSoundBeLoaded(SoundId)
	local Success, Result = pcall(MarketplaceService.GetProductInfo, MarketplaceService, SoundId)
	if Success then
		if Result.AssetTypeId == 3 then
			return Result.IsPublicDomain
		end
		return false, "Id is not an Audio asset"
	end
	return false, Result
end

-- Sound that's freely available (Raining Tacos):
print(CanSoundBeLoaded(142376088)) -- true

-- Sound that's private (DOTR):
print(CanSoundBeLoaded(11420922)) -- false

-- Wrong Id type (my UserId):
print(CanSoundBeLoaded(21645075)) -- false, "Id is not an Audio asset"

-- An invalid Id entirely:
print(CanSoundBeLoaded(-1)) -- false, *some error message thrown by GetProductInfo*
4 Likes

This does seem like a bug. I would post this within’ the bug-reports as all sounds that had an error while trying to play should error out automatically. (If the server was too slow to start the sound, the sound was banned or deleted, or you don’t have permission)

pcall seems to work perfectly for me. So, it’s probably something within’ your studio.

1 Like

The error happens in a different script than what changes the audio ID so this is unfortunately intended behaviour as pcalls only return false if a function with-in them fails and since ContentProvider itself is not inside the pcall ContentProvider will error but the function will still return true.

Interesting. You are indeed correct but pcall did fix my game in the past with audio issues.

Here is a quick script I made that helps with this cause until Roblox eventually adds it in.

local LoadPingSeconds = 5

function PlaySound(sound)
	local loaded = false
	for i=1,LoadPingSeconds*1000 do --This will ping the sound for 5 seconds or until it eventually loads fully. We're not using any waits as were using miliseconds to play the song or audio as fast as possible. 
		if sound.IsLoaded then --if the sound is loaded. Break the loop.
			loaded = true
			break
		end
	end
	if loaded == true and sound.TimeLength ~= 0 then --If the sound was loaded, and the Timelength isn't equal to 0 (Means we didn't have access to it, or it's incorrect) then play the sound.
		sound:Play()
		return true
	else
		return false
	end
end

if PlaySound(script.Parent:FindFirstChild("Sound")) then
	warn("I had access to the sound, and Roblox loaded the sound successfully.")
else
	warn("I couldn't play the sound as I didn't have access, or Roblox's servers are being lazy.")
end
1 Like

I mean my preferred work around is to make Roblox revert this update and let us use sounds.

Certainly everyone would like that but there is a very good reason for the update.

1 Like

They’re not gonna set everything back to public but hopefully they will someday be able to unfreeze the button for setting an audio asset to public.

There was a good reason Roblox made this Audio Update. Bypassed audio, copyright, etc.

Roblox was getting in trouble. So they did something to permanently fix the issue by not allowing music they didn’t upload in different games. And… If Roblox was to get sued they could just find out who you are and tell the company your information getting you sued.

1 Like

The privacy sweep for old music may have been to assist with the copyright sweep since the majority of copyrighted music was played in games not owned by the asset uploader, but if the copyrighted asset wasn’t fully taken down it could’ve still been played in games that the uploader also made.

If they were forced to permanently suspend the user-uploaded audio catalog I imagine they would not have said the restrictions were temporary nor have added a grayed out button for setting an audio to “all games”.

I would still like this to be added.

3 Likes