Hello, I want to create a music player with a progress bar that shows how far through the song is. I’ve got the script that randomises the songs but I don’t know how I would make a progress bar. This my server script in Workspace.
local songs = script.Parent
local tablee = {}
local lastsong = nil
for i,v in pairs(songs:GetChildren()) do
if v:IsA("Sound") then
table.insert(tablee,v)
end
end
while true do
for a,c in pairs(tablee) do
local chosensong = tablee[math.random(1,#tablee)]
repeat wait() chosensong = tablee[math.random(1,#tablee)] until chosensong ~= lastsong
lastsong = chosensong
chosensong:Play()
chosensong.Ended:Wait()
chosensong:Stop()
end
wait()
end
1 Like
You have to work with the Sound TimeLength and TimePosition like this:
ProgressBar.Size = UDim2.new(chosensong.TimePosition / chosensong.TimeLength, 0, 1, 0)
I don’t know if this script would work because It’s just an example but you have to do it somehow like this.
I’ve already tried something like this but it doesn’t work.
Use RunService for the script.
game["Run Service"]:BindToRenderStep("", 100, function()
ProgressBar.Size = UDim2.new(chosensong.TimePosition / chosensong.TimeLength, 0, 1, 0)
end)
Something like this.
Where would I put the script, because right now it’s a server-sided script in Workspace.
Hey, I put this together. It will work on the Server and the Client. It returns the percentage completion of the Sound. the percentage is to the nearest tenth. Hope this helps!
local Sound = script.Parent.Sound
for i = 1, math.huge do
local SoundLength = Sound.TimeLength
local CurrentPos = Sound.TimePosition
local Percentage = CurrentPos / SoundLength * 100
local Clip = math.floor(Percentage / 0.1) * 0.1
print(Clip)
wait()
end
Here’s what I would do:
-
Handle the progress bar locally (As in use Gui Objects/Frames)
-
Create a ScreenGui
inside StarterGui
, insert 2 Frame
Objects inside (1 for overlaying the background, 1 for getting the progress bar)
-
Get the progress-bar of the Frame by dividing the Sound.TimePosition / Sound.TimeLength
- You can either use
Size
or TweenSize
, I suppose Size
would be more efficient
-
Use the RunService’s RenderStepped
Event to detect changes every frame or so on the client
You should have something like this in a LocalScript inside 1 of the local descendants:
local RunService = game:GetService("RunService")
local Player = game.Players.LocalPlayer
local PlayerGui = Player:WaitForChild("PlayerGui")
local MusicProgress = PlayerGui:WaitForChild("ProgressBar")
local SongTable = {}
local Songs = workspace.Songs
for _, Song in pairs(Songs:GetChildren()) do
if Song:IsA("Sound") then
table.insert(SongTable, Song)
end
RunService.RenderStepped:Connect(function()
local RandomSong = SongTable[math.random(1, #SongTable)]
if RandomSong and RandomSong.IsPlaying == true then
local Progress = RandomSong.TimePosition / RandomSong.TimeLength
MusicProgress.ProgressBar.Size = UDim2.new(Progress, 0, 1, 0)
end
end)
1 Like
Where should I put the local script?
- StarterPlayerScripts
- StarterPack
- StarterGui
Any of those would work, just be sure to parent your objects in the correct way in relation to the variables I mentioned
I’ve put this
local RunService = game:GetService("RunService")
local Player = game.Players.LocalPlayer
local PlayerGui = Player:WaitForChild("PlayerGui")
local MusicProgress = PlayerGui.MusicGui.Frame
local SongTable = {}
local Songs = game.Workspace.Sounds
for _, Song in pairs(Songs:GetChildren()) do
if Song:IsA("Sound") then
table.insert(SongTable, Song)
end
RunService.RenderStepped:Connect(function()
local RandomSong = SongTable[math.random(1, #SongTable)]
if RandomSong and RandomSong.IsPlaying == true then
local Progress = RandomSong.TimePosition / RandomSong.TimeLength
MusicProgress.ProgressBar.Size = UDim2.new(Progress, 0, 1, 0)
end
end)
end
inside a local script inside the progress bar but it isn’t working or even playing the songs.
Did I really just put the RandomSong
variable inside the RenderStepped event-
The reason why it’s not playing the songs is cause it’s only listening to what’s being played on the server side, you should probably just create a random song picker check so it plays a random song:
local Songs = game.Workspace.Sounds:GetChildren()
while true do
local RandomSong = Songs[math.random(1, #Songs)]
if RandomSong:IsA("Sound") then
RandomSong:Play()
RandomSong.Ended:Wait()
RandomSong:Stop()
end
end
Also this should be the fixed script for the local side:
local RunService = game:GetService("RunService")
local Player = game.Players.LocalPlayer
local PlayerGui = Player:WaitForChild("PlayerGui")
local MusicProgress = PlayerGui.MusicGui.Frame
local Songs = game.Workspace.Sounds
RunService.RenderStepped:Connect(function()
for _, Song in pairs(Songs:GetChildren()) do
if Song:IsA("Sound") and Song.IsPlaying == true then
local Progress = Song.TimePosition / Song.TimeLength
MusicProgress.ProgressBar.Size = UDim2.new(Progress, 0, 1, 0)
end
end
end)
2 Likes
Once last quick question, the progress bar goes past the frame is there any way I can change that?
Your progress bar should be parented inside your OverlayFrame
, and it should do the trick
Your OverlayFrame
should be something like this: (0.5, 0, 0.2, 0)
1 Like
Now it only plays once, stops playing any songs, and says an error at the end of the first song that says Play is not a valid member of Script “Workspace.Sounds.SoundManager”.
Okay I edited the script in relevance to the server, could you try it again?
1 Like
Hey so I’m using this system and I’m a little confused with the progress bar, it goes past the overlay frame.
This is what I want it to look like when it’s full

Overlay size: {0.394, 0},{0.176, 0}
The progress script:
local RunService = game:GetService(“RunService”)
local Player = game.Players.LocalPlayer
local PlayerGui = Player:WaitForChild(“PlayerGui”)
local MusicProgress = PlayerGui.music.Background
local Songs = game.Workspace.Sounds
RunService.RenderStepped:Connect(function()
for _, Song in pairs(Songs:GetChildren()) do
if Song:IsA("Sound") and Song.IsPlaying == true then
MusicProgress.Parent.SongName.Text = Song.Name
local Progress = Song.TimePosition / Song.TimeLength
MusicProgress.progress.Size = UDim2.new(Progress, 0.150, 0.08, 0)
end
end
end)
