APM library boombox

To combat the new audio update, I decided to make an updated boombox, which allows:

  • Search and browse the Roblox APM music library
  • Favourite audios and play them at any time
  • Music time position slider
  • An up-to-date interface
  • Show and hide the interface (Toggle button can be moved anywhere in roblox studio)

For the boombox to function properly, your game must have access to API servers and HTTP requests


It’s just a quick build, but it does the job.
Get the model here!

Enjoy!

23 Likes

update this, I went to test and it is very buggy

1 Like

Turn on HTTP requests in studio settings

That’s not it, it’s just that when I hold the tool nothing appears on the screen

Add an option for users to insert an id incase they found something by roblox that they like

3 Likes

I second this, a few audios are fine, such as stuff by Monstercat, or
Parry Gripp’s Raining Tacos - Parry Gripp - Raining Tacos - Roblox

IDs insert would be nice, also found a weird bug

2 Likes

Any scripter to fix this model

Hi,
Sorry for the long wait. I’ve had a lot of trouble recently accessing the developer forums, so I’ve been very oblivious to the trouble my model seems to be causing you.
The boombox was, honestly, very quickly slapped together as a possible solution. The reception has been rather positive, aside from the few bugs here and there.

I’m updating the model now, and a new version will be available very soon.

1 Like

I’ve been waiting for a long time

Sorry for the long wait (again), been very busy and I haven’t had any time to look at this.
Fortunately, I was able to release a patch for the model, with some UX improvements and bug fixes.

As well as it’s original features, the boombox can now:

  • Filter out most SFX audios Until there is an API endpoint for create.roblox.com, this won’t be the most accurate, albeit a good solution was put in place.
  • Easier to find favourite audios
  • Automatically plays music when selected
  • Better page loading
  • Better error handling
  • Toggle the radio gui by clicking away from the gui / anywhere on screen when disabled

Enjoy! :grin:

Roblox has a limit of 250 APM audios in an experience

Its not enforced engine-wise but you should still tread carefully

It loads the data from one of roblox’s API endpoints and stores them in a table. Only 1 sound is ever present per boombox. I’m not familiar with the rules you’ve stated, but unless there are 250 players, each with boomboxes, I don’t see why this would be a problem :smile:

I have a few things that can improve your boombox

Local TTorso --This can be above the entire script that makes the sound play.
if Plr.Character:FindFirstChild(“HumanoidRootPart”) ~= nil then
TTorso = Plr.Character.HumanoidRootPart
else
TTorso = Plr.Character.HumanoidRootPart
end

if TTorso:FindFirstChild("Sound") then
	TTorso:FindFirstChild("Sound"):Remove()
end
local Sound = Instance.new'Sound'
Sound.Parent = TTorso
Sound.Volume = 0.8
Sound.Looped = true
Sound.Name = "Sound"
Sound.SoundId = "http://www.roblox.com/asset/?id="..id
Sound:Play()

end
–Makes the sound play on your root part, and the sound doesn’t stop when you take the boombox out

this one is for the boombox to be on the back, separate from what I posted above.

local Tool = script.Parent
local Handle = script.Parent:WaitForChild(“Handle”)
function Equipped(Mouse)
Player = script.Parent.Parent
if Player:FindFirstChild(“Holster”) then
Player.Holster:remove()
end
end

function Unequipped(Mouse)
local torso
local char = Player
if char ~= nil then
if char:FindFirstChild(“Torso”) ~= nil then
torso = char.Torso
else
torso = char.UpperTorso
end

	if torso ~= nil then

		local Holster = Handle:clone()
		Holster.CanCollide = false
		Holster.Name = "Holster"
		Holster.Parent = char
		Holster.Locked = true
		
		local weld = Instance.new("Weld")
		weld.Name = "BackWeld"
		weld.Part0 = torso
		weld.Part1 = Holster
		weld.C0 = CFrame.new(-0.001, 0,0.85 )
		weld.C0 = weld.C0 * CFrame.Angles(math.rad(180), math.rad(0), math.rad(120))
		weld.Parent = Holster
	end
end

end
Tool.Equipped:connect(Equipped)
Tool.Unequipped:connect(Unequipped)

This one is actually a pretty good idea, I’ll give it a look. Thank you :grin:

1 Like

Modded

local TTorso
local DataStoreService = game:GetService(“DataStoreService”)
local HttpService = game:GetService(“HttpService”)

local tool = script:FindFirstAncestorWhichIsA(“Tool”)
local func = tool:FindFirstChildWhichIsA(“RemoteFunction”)
local store = DataStoreService:GetDataStore(“BoomboxFavourites”)

func.OnServerInvoke = function(player, action, data)

if action == "RequestSongs" then

	if data.SearchKeyword == "favs" then
		return "favs"
	end

	local songs = nil

	--> Request songs list from proxy server:
	repeat
		
		local url = string.format("https://search.RoProxy.com/catalog/json?CatalogContext=2&Subcategory=16&CreatorID=1&SortAggregation=5&PageNumber=%i&Keyword=%s&LegendExpanded=true&Category=9&SearchId=3e31c553-b9e1-4811-8ba4-c0c511cf915f", data.PageNumber, data.SearchKeyword)
		local success, errormsg = pcall(function()
			songs = HttpService:JSONDecode(HttpService:RequestAsync({Url = url, Method = "GET"}).Body) --> Get songs from search.roblox.com result
		end)

		if not success then 
			warn(errormsg)
			task.wait(.2)
		end

	until success

	if not songs then
		songs = { --> List of default audios to load:
			{Name = "fnaf beatbox", AssetId = 8106213926, Description = "Length: 0s"},
			{Name = "Heart and soul", AssetId = 6515159451, Description = "Length: 0s"},
			{Name = "Good vibes", AssetId = 1836454862, Description = "Length: 0s"},
			{Name = "Blue vibes", AssetId = 1835804758, Description = "Length: 0s"},
			{Name = "fnaf beatbox", AssetId = 8106213926, Description = "Length: 0s"},
			{Name = "fnaf beatbox", AssetId = 8106213926, Description = "Length: 0s"},
			{Name = "fnaf beatbox", AssetId = 8106213926, Description = "Length: 0s"},
			{Name = "fnaf beatbox", AssetId = 8106213926, Description = "Length: 0s"},
			{Name = "fnaf beatbox", AssetId = 8106213926, Description = "Length: 0s"},
			{Name = "fnaf beatbox", AssetId = 8106213926, Description = "Length: 0s"},
		}
	end

	return songs

elseif action == "UpdateSound" then

	if player.Character:FindFirstChild("HumanoidRootPart") ~= nil then
		TTorso = player.Character.HumanoidRootPart
	else
		TTorso = player.Character.HumanoidRootPart
	end

	if TTorso:FindFirstChild("Sound") then
		TTorso:FindFirstChild("Sound"):Remove()
	end
	local Sound = Instance.new'Sound'
	Sound.Parent = TTorso
	Sound.Volume = 0.8
	Sound.Looped = true
	Sound.Name = "Sound"
	Sound.SoundId = string.format("rbxassetid://%i", data.Id)
	Sound:Play()


elseif action == "Play" then
	TTorso:FindFirstChild("Sound"):Resume()

–[[
elseif action == “Pause” then
TTorso:FindFirstChild(“Sound”):Pause()
–]]
elseif action == “ChangeTime” then
TTorso:FindFirstChild(“Sound”).TimePosition = data.TimePosition

elseif action == "GetFavourites" then
	return store:GetAsync(tostring(player.UserId)) or {}

elseif action == "SaveFavourites" then
	store:SetAsync(tostring(player.UserId), data)

end

return "Invalid action name!"

end

I haven’t tested it yet, is it possible to find sounds with ids?

No, but I didn’t think that would be necessary since you would already have the audio name, so it wouldn’t be hard to find.

… and if you’re talking about having IDs for other songs, not provided by the APM library - well, that wouldn’t be able to play in-game anyway. Unless it’s in your game and you own the audio, but that’s a rare case. This is more for wider distribution for other players to use in your games who can no longer use their own audios. If you want your own IDs you can use the old boombox. :smile:

1 Like

This script makes position time not work (unfindable)

a very important suggestion, make the radio work without having to keep it in your hand.