-- SERVICES local Players = game:GetService("Players") local SoundService = game:GetService("SoundService") local RunService = game:GetService("RunService") local UIS = game:GetService("UserInputService") local player = Players.LocalPlayer --------------------------------------------------- -- GUI --------------------------------------------------- local gui = Instance.new("ScreenGui") gui.Parent = player:WaitForChild("PlayerGui") gui.ResetOnSpawn = false local frame = Instance.new("Frame", gui) frame.Size = UDim2.fromScale(0.6, 0.7) frame.Position = UDim2.fromScale(0.2, 0.15) frame.BackgroundColor3 = Color3.fromRGB(35,35,35) -- TOGGLE BUTTON local toggleBtn = Instance.new("TextButton", gui) toggleBtn.Size = UDim2.fromScale(0.25,0.1) toggleBtn.Position = UDim2.fromScale(0.05,0.05) toggleBtn.Text = "🎵 MUSIC PLAYER" toggleBtn.TextScaled = true toggleBtn.Active = true toggleBtn.Draggable = true toggleBtn.BackgroundColor3 = Color3.fromRGB(60,60,60) toggleBtn.TextColor3 = Color3.new(1,1,1) toggleBtn.MouseButton1Click:Connect(function() frame.Visible = not frame.Visible end) --------------------------------------------------- -- SOUND --------------------------------------------------- local sound = Instance.new("Sound") sound.Parent = SoundService sound.Volume = 1 sound.Looped = false -- manual looping --------------------------------------------------- -- HELPERS --------------------------------------------------- local function button(text, size, pos) local b = Instance.new("TextButton", frame) b.Size = size b.Position = pos b.Text = text b.TextScaled = true b.BackgroundColor3 = Color3.fromRGB(80,80,80) b.TextColor3 = Color3.new(1,1,1) return b end local function box(placeholder, size, pos) local t = Instance.new("TextBox", frame) t.Size = size t.Position = pos t.PlaceholderText = placeholder t.Text = "" t.TextScaled = true t.ClearTextOnFocus = false t.BackgroundColor3 = Color3.fromRGB(60,60,60) t.TextColor3 = Color3.new(1,1,1) return t end -- TIME FORMAT local function formatTime(sec) sec = math.floor(sec) if sec < 60 then return tostring(sec) end return math.floor(sec/60) .. ":" .. string.format("%02d", sec % 60) end -- PARSE START TIME (supports mm:ss) local function parseTime(text) if string.find(text, ":") then local m,s = text:match("(%d+):(%d+)") return (tonumber(m) or 0)*60 + (tonumber(s) or 0) end return tonumber(text) or 0 end --------------------------------------------------- -- UI ELEMENTS --------------------------------------------------- local songBox = box("Song ID", UDim2.fromScale(0.9,0.08), UDim2.fromScale(0.05,0.03)) local playBtn = button("▶ PLAY", UDim2.fromScale(0.4,0.08), UDim2.fromScale(0.05,0.13)) local stopBtn = button("⏹ STOP", UDim2.fromScale(0.4,0.08), UDim2.fromScale(0.55,0.13)) local loopBtn = button("🔁 LOOP: OFF", UDim2.fromScale(0.9,0.08), UDim2.fromScale(0.05,0.23)) local looping = false local startBox = box("Start at (sec or mm:ss)", UDim2.fromScale(0.9,0.07), UDim2.fromScale(0.05,0.33)) local startTime = 0 --------------------------------------------------- -- VOLUME SLIDER --------------------------------------------------- local volumeLabel = Instance.new("TextLabel", frame) volumeLabel.Size = UDim2.fromScale(0.9,0.05) volumeLabel.Position = UDim2.fromScale(0.05,0.41) volumeLabel.BackgroundTransparency = 1 volumeLabel.TextScaled = true volumeLabel.TextColor3 = Color3.new(1,1,1) volumeLabel.Text = "Volume: 1.0x" local volTrack = Instance.new("Frame", frame) volTrack.Size = UDim2.fromScale(0.9,0.045) volTrack.Position = UDim2.fromScale(0.05,0.47) volTrack.BackgroundColor3 = Color3.fromRGB(70,70,70) local volKnob = Instance.new("Frame", volTrack) volKnob.Size = UDim2.fromScale(0.04,1) volKnob.Position = UDim2.fromScale(0.45,0) volKnob.BackgroundColor3 = Color3.fromRGB(200,200,200) --------------------------------------------------- -- TIME + SCRUB SLIDER --------------------------------------------------- local timeLabel = Instance.new("TextLabel", frame) timeLabel.Size = UDim2.fromScale(0.9,0.05) timeLabel.Position = UDim2.fromScale(0.05,0.53) timeLabel.BackgroundTransparency = 1 timeLabel.TextScaled = true timeLabel.TextColor3 = Color3.new(1,1,1) timeLabel.Text = "0 / 0" local scrubTrack = Instance.new("Frame", frame) scrubTrack.Size = UDim2.fromScale(0.9,0.045) scrubTrack.Position = UDim2.fromScale(0.05,0.59) scrubTrack.BackgroundColor3 = Color3.fromRGB(70,70,70) local scrubKnob = Instance.new("Frame", scrubTrack) scrubKnob.Size = UDim2.fromScale(0.03,1) scrubKnob.Position = UDim2.fromScale(0,0) scrubKnob.BackgroundColor3 = Color3.fromRGB(220,220,220) --------------------------------------------------- -- SKIP --------------------------------------------------- local rewindBtn = button("⏪ -10s", UDim2.fromScale(0.42,0.07), UDim2.fromScale(0.05,0.66)) local skipBtn = button("⏩ +10s", UDim2.fromScale(0.42,0.07), UDim2.fromScale(0.53,0.66)) --------------------------------------------------- -- LOGIC --------------------------------------------------- local function applyStartTime() startTime = parseTime(startBox.Text) if sound.TimeLength > 0 then sound.TimePosition = math.clamp(startTime, 0, sound.TimeLength) end end -- PLAY playBtn.MouseButton1Click:Connect(function() if songBox.Text == "" then return end sound.SoundId = "rbxassetid://" .. songBox.Text sound:Stop() sound:Play() task.wait(0.05) applyStartTime() end) stopBtn.MouseButton1Click:Connect(function() sound:Stop() end) loopBtn.MouseButton1Click:Connect(function() looping = not looping loopBtn.Text = looping and "🔁 LOOP: ON" or "🔁 LOOP: OFF" end) -- MANUAL LOOP + Start At sound.Ended:Connect(function() if looping then sound:Play() task.wait(0.05) applyStartTime() end end) skipBtn.MouseButton1Click:Connect(function() sound.TimePosition = math.min(sound.TimePosition + 10, sound.TimeLength) end) rewindBtn.MouseButton1Click:Connect(function() sound.TimePosition = math.max(sound.TimePosition - 10, 0) end) --------------------------------------------------- -- DRAGGING (VOLUME + SCRUB) --------------------------------------------------- local draggingVol, draggingScrub = false, false volKnob.InputBegan:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 or i.UserInputType == Enum.UserInputType.Touch then draggingVol = true end end) scrubKnob.InputBegan:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 or i.UserInputType == Enum.UserInputType.Touch then draggingScrub = true end end) UIS.InputEnded:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 or i.UserInputType == Enum.UserInputType.Touch then draggingVol = false draggingScrub = false end end) RunService.RenderStepped:Connect(function() -- VOLUME if draggingVol then local x = math.clamp((UIS:GetMouseLocation().X - volTrack.AbsolutePosition.X) / volTrack.AbsoluteSize.X, 0, 1) volKnob.Position = UDim2.fromScale(x - 0.02, 0) local vol = 0.1 + (x * 1.9) sound.Volume = vol volumeLabel.Text = string.format("Volume: %.1fx", vol) end -- SCRUB if draggingScrub and sound.TimeLength > 0 then local x = math.clamp((UIS:GetMouseLocation().X - scrubTrack.AbsolutePosition.X) / scrubTrack.AbsoluteSize.X, 0, 1) scrubKnob.Position = UDim2.fromScale(x - 0.015, 0) sound.TimePosition = x * sound.TimeLength end -- TIME DISPLAY if sound.IsPlaying and sound.TimeLength > 0 then timeLabel.Text = formatTime(sound.TimePosition) .. " / " .. formatTime(sound.TimeLength) scrubKnob.Position = UDim2.fromScale( sound.TimePosition / sound.TimeLength - 0.015, 0 ) end end)