How would I be able to make it so that the song is synced for everyone at the same time?

PLEASE READ BELOW BEFORE COMMENTING

Hi there, I have a song playlist script which loops through a list of songs and plays them randomly. I’ve been sticking with using a local script of that playlist script since if I used a serverscripts, stuff bugs out and functions don’t connect properly in order. What I want to achieve, is to somehow always send out info of a song playing on a playlist on a serverscript including the time and position, then have the info read on a local script and play the info from that serverscript (for example what song should be playing).

Of course, I could easily fix this and change it to a serverscript, but the issue is, is that because it’s on the server, the loops and functions (for example how it transition to the next song) somehow mess up its order even in a loop, and then breaks the entire script and is too hard to explain what the bug is. However, the main goal is achieving as what said in the title, and not how to fix this bug.

Ever since I had it as a local script, everything works perfectly fine excepts the songs that are playing aren’t in sync with other players.

Script (originally a local script located in starterplayerscripts):

local MPS = game:GetService("MarketplaceService")
local currentTrack = game.ReplicatedStorage.CurrentTrack 
local CurrentCamera = workspace.CurrentCamera
local musicplayer = workspace.Sound

music = {
	"rbxassetid://3044286747",
	"rbxassetid://1256391355",
	"rbxassetid://5480102561",
	"rbxassetid://5024527209",
	"rbxassetid://870242868",
	"rbxassetid://1112109949",
	"rbxassetid://6303331764",
	"rbxassetid://2206587324",
	"rbxassetid://5987864893",
	"rbxassetid://534429024",
	"rbxassetid://4551177864",
	"rbxassetid://664277618",
	"rbxassetid://3011342543",
	"rbxassetid://3523361267",
	"rbxassetid://3616424949";

}

while true do 

	if not musicplayer.IsPlaying then

		local RandomSong = music[math.random(1, #music)]
		local SongID = string.match(RandomSong, "%d+")
		local SongInfo = MPS:GetProductInfo(SongID)

		musicplayer.SoundId = RandomSong
		musicplayer:Play()

		currentTrack.Value = "..." -- displays the song playing in a music player gui

		currentTrack.Value = SongInfo.Name -- just for displaying current song playing

		musicplayer.Ended:Wait()

		game:GetService("RunService"):UnbindFromRenderStep("CurrentTrack")

	end
end

Put the sounds under SoundService and enable RespectFilteringEnabled?

Also, if you’re doing this locally, wouldn’t each player get their own copy of this script inside their player or character meaning they’d all get a different song?

Maybe choose the song on the server via math.random and then :FireAllClients() if you really wanted to, or just play the song on the server.

There’s probably an error in your logic if this was occurring. Do you still have the old server code?

1 Like

That’s the same code for when I converted it to a serverscript.

Whether you want to play the music on the client or the server, the server will have to be involved. Either play the sound in a Script or in a LocalScript by using a RemoteEvent.

1 Like

Okay, so this is what I have so far on my serverscript, which is for what chooses the song. What else do I have to do, I am kinda lost.

local MPS = game:GetService("MarketplaceService")
local currentTrack = game.ReplicatedStorage.CurrentTrack 
local CurrentCamera = workspace.CurrentCamera
local musicplayer = workspace.Sound
local rs = game:GetService("ReplicatedStorage")
local re = rs:WaitForChild("music")

music = {
	"rbxassetid://3044286747",
	"rbxassetid://1256391355",
	"rbxassetid://5480102561",
	"rbxassetid://5024527209",
	"rbxassetid://870242868",
	"rbxassetid://1112109949",
	"rbxassetid://6303331764",
	"rbxassetid://2206587324",
	"rbxassetid://5987864893",
	"rbxassetid://534429024",
	"rbxassetid://4551177864",
	"rbxassetid://664277618",
	"rbxassetid://3011342543",
	"rbxassetid://3523361267",
	"rbxassetid://3616424949";

}

while true do 

	if not musicplayer.IsPlaying then

		local RandomSong = music[math.random(1, #music)]
		local SongID = string.match(RandomSong, "%d+")
		local SongInfo = MPS:GetProductInfo(SongID)

		re:FireAllClients(SongID)

	end
end

You could just play the Sound on the server and it should replicate to all clients.

If he wants the song synced for all clients then that wouldn’t work. This is because there is latency between the replications.

How would I do this (what would I be replicated to specifically)?

Sound played on the server replicates to the clients just like animations, attributes , etc.

Oh, yeah but the issue is is that I’ve already tried this and the functions dont connect in order. It’s just a hassle to explain this bug since its rarely discussed on the devforum. So it’s probably the latency that is the issue when using a serverscript just like you said.

Yes, but the issue is, is that the functions and visualizers that read off the server played sound, don’t work correctly and some functions that perform inside a loop don’t loop properly or connect/disconnect because of what I think is latency (as what @RatiusRat said).

You’d have to consider skipping some of the song in order to sync perfectly by using the real time of the clients. This method requires you to use a remote event.

So basically skipping a song, then the next song played will make it insync with the client? Can you explain how this would be done?

I meant skipping part of a song in order to synchronise the song position.

I would recommend you add a parameter storing the current tick() then the client can get the delay by finding the difference between their current tick and the server’s.

I mean, that would work but again, there are other functions that read off the same song and wouldn’t work properly.

Honestly, I think sticking to using a remoteevent is easier like you said, but I just don’t know how.

What I think I should do, is have the same playlist script, except without the playing stuff and just the randomizer part. Then you get that the song id of the randomized song and somehow replicate that to the sound. I’m just confused on how you would replicate this to a sound.

Once you have the song id on the client create a sound instance then load the song?(or use an existing one) Also, using the delay and the delay to load the song, you set the song at the appropriate position.

Except I’d want it to be the server to client. This is making me get really mixed up.

What I’ll try do, is after I got the songid, put it into a intvalue then on the client, input that into the soundID and play off there, with the delay. I’d also do the same for timeposition. Would this work?

The only thing is, is that it would be hard to make this also work with a looped playlist since the loop is around finding if the song has ended on the client using the serverscript.

1 Like

I’ll try to use a remotefunction to see if the song for all the clients have played or stopped playing.