mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 10:21:11 +00:00
Adds a crossfade mode to songs for the jukebox. (#26355)
* Adds a crossfade mode to songs for the jukebox. * mmm * Tentative fix * _ * last fixes * better * comments * no * fuck wmp * It usually works better if it compiles
This commit is contained in:
@@ -8,3 +8,6 @@
|
||||
#define JUKEBOX_SCREEN_SETTINGS 3
|
||||
|
||||
#define JUKEBOX_RELOAD_COOLDOWN 600 // 60s
|
||||
|
||||
#define JUKEBOX_ODD_PLAYER "odd"
|
||||
#define JUKEBOX_EVEN_PLAYER "even"
|
||||
|
||||
@@ -95,6 +95,7 @@ var/global/global_playlists = list()
|
||||
|
||||
var/url = ""
|
||||
var/length = 0 // decaseconds
|
||||
var/crossfade_time = 0 // decaseconds, if the song ends up with a decresendo/fadeout so we can crossfade into the next one.
|
||||
|
||||
var/emagged = 0
|
||||
|
||||
@@ -106,6 +107,9 @@ var/global/global_playlists = list()
|
||||
url = json["url"]
|
||||
|
||||
length = text2num(json["length"])
|
||||
crossfade_time = text2num(json["crossfade_time"])
|
||||
if (isnull(crossfade_time))
|
||||
crossfade_time = 0
|
||||
|
||||
/datum/song_info/proc/display()
|
||||
var/str="\"[title]\""
|
||||
@@ -664,9 +668,14 @@ var/global/list/loopModeNames=list(
|
||||
return
|
||||
if(playing)
|
||||
var/datum/song_info/song
|
||||
var/datum/song_info/next_song_datum
|
||||
var/fadeout_time = 0
|
||||
if(current_song && playlist.len)
|
||||
song = playlist[current_song]
|
||||
if(!current_song || (song && world.time >= media_start_time + song.length))
|
||||
if(next_song && playlist.len)
|
||||
next_song_datum = playlist[next_song]
|
||||
fadeout_time = next_song_datum.crossfade_time
|
||||
if(!current_song || (song && world.time >= media_start_time + song.length - fadeout_time))
|
||||
current_song=1
|
||||
if(next_song)
|
||||
current_song = next_song
|
||||
@@ -718,6 +727,7 @@ var/global/list/loopModeNames=list(
|
||||
media_url = song.url
|
||||
last_song = current_song
|
||||
media_start_time = world.time
|
||||
media_finish_time = world.time + song.length
|
||||
visible_message("<span class='notice'>[bicon(src)] \The [src] begins to play [song.display()].</span>","<em>You hear music.</em>")
|
||||
//visible_message("<span class='notice'>[bicon(src)] \The [src] warbles: [song.length/10]s @ [song.url]</notice>")
|
||||
else
|
||||
@@ -878,6 +888,7 @@ var/global/list/loopModeNames=list(
|
||||
media_url = song.url
|
||||
last_song = current_song
|
||||
media_start_time = world.time
|
||||
media_finish_time = world.time + song.length
|
||||
visible_message("<span class='notice'>[bicon(src)] \The [src] begins to play [song.display()].</span>","<em>You hear music.</em>")
|
||||
//visible_message("<span class='notice'>[bicon(src)] \The [src] warbles: [song.length/10]s @ [song.url]</notice>")
|
||||
else
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
var/playing=0
|
||||
var/media_url=""
|
||||
var/media_start_time=0
|
||||
var/media_finish_time = 0
|
||||
var/volume = 1 // 0 - 1 for ease of coding.
|
||||
|
||||
var/area/master_area
|
||||
|
||||
@@ -135,15 +135,19 @@ function SetMusic(url, time, volume) {
|
||||
var/obj/machinery/media/media_source = null
|
||||
|
||||
#ifdef DEBUG_MEDIAPLAYER
|
||||
to_chat(#define MP_DEBUG(x) owner, x)
|
||||
#define MP_DEBUG(x) to_chat(owner, x)
|
||||
#warn Please comment out #define DEBUG_MEDIAPLAYER before committing.
|
||||
#else
|
||||
#define MP_DEBUG(x)
|
||||
#endif
|
||||
|
||||
/datum/media_manager
|
||||
var/url = ""
|
||||
var/url_odd = ""
|
||||
var/url_even = ""
|
||||
var/currently_broadcasting = JUKEBOX_ODD_PLAYER
|
||||
|
||||
var/start_time = 0
|
||||
var/finish_time = -1
|
||||
var/source_volume = 1 // volume * source_volume
|
||||
|
||||
var/volume = 50
|
||||
@@ -152,7 +156,8 @@ to_chat(#define MP_DEBUG(x) owner, x)
|
||||
|
||||
var/forced=0
|
||||
|
||||
var/const/window = "rpane.hosttracker"
|
||||
var/const/window_odd = "rpane.hosttracker"
|
||||
var/const/window_even = "rpane.hosttracker2"
|
||||
//var/const/window = "mediaplayer" // For debugging.
|
||||
var/playerstyle
|
||||
|
||||
@@ -169,28 +174,61 @@ to_chat(#define MP_DEBUG(x) owner, x)
|
||||
|
||||
// Actually pop open the player in the background.
|
||||
/datum/media_manager/proc/open()
|
||||
owner << browse(null, "window=[window]")
|
||||
owner << browse(playerstyle, "window=[window]")
|
||||
owner << browse(null, "window=[window_odd]")
|
||||
owner << browse(playerstyle, "window=[window_odd]")
|
||||
owner << browse(null, "window=[window_even]")
|
||||
owner << browse(playerstyle, "window=[window_even]")
|
||||
send_update()
|
||||
|
||||
// Tell the player to play something via JS.
|
||||
/datum/media_manager/proc/send_update()
|
||||
/datum/media_manager/proc/send_update(var/target_url)
|
||||
if(!(owner.prefs))
|
||||
return
|
||||
if(!(owner.prefs.toggles & SOUND_STREAMING) && url != "")
|
||||
if(!(owner.prefs.toggles & SOUND_STREAMING) && target_url != "")
|
||||
return // Nope.
|
||||
MP_DEBUG("<span class='good'>Sending update to VLC ([url])...</span>")
|
||||
owner << output(list2params(list(url, (world.time - start_time) / 10, volume*source_volume)), "[window]:SetMusic")
|
||||
MP_DEBUG("<span class='good'>Sending update to media player ([target_url])...</span>")
|
||||
var/window_playing
|
||||
if(owner.prefs.usewmp)
|
||||
stop_music()
|
||||
MP_DEBUG("<span class='good'>WMP user, no switching, going to even window.<span>")
|
||||
currently_broadcasting = JUKEBOX_EVEN_PLAYER
|
||||
window_playing = window_even
|
||||
url_even = target_url
|
||||
else
|
||||
switch (currently_broadcasting)
|
||||
if (JUKEBOX_ODD_PLAYER) // We were on odd, so now we are on even, broadcasting the target url.
|
||||
MP_DEBUG("<span class='good'>Going on the even player, as odd one is playing something.<span>")
|
||||
currently_broadcasting = JUKEBOX_EVEN_PLAYER
|
||||
window_playing = window_even
|
||||
url_even = target_url
|
||||
if (JUKEBOX_EVEN_PLAYER) // And vice versa.
|
||||
MP_DEBUG("<span class='good'>Going on the odd player, as even one is playing something.<span>")
|
||||
currently_broadcasting = JUKEBOX_ODD_PLAYER
|
||||
window_playing = window_odd
|
||||
url_odd = target_url
|
||||
// We start to broadcast the music on the second media thing
|
||||
owner << output(list2params(list(target_url, (world.time - start_time) / 10, volume*source_volume)), "[window_playing]:SetMusic")
|
||||
|
||||
|
||||
|
||||
/datum/media_manager/proc/push_music(var/targetURL,var/targetStartTime,var/targetVolume)
|
||||
if (url != targetURL || abs(targetStartTime - start_time) > 1 || abs(targetVolume - source_volume) > 0.1 /* 10% */)
|
||||
url = targetURL
|
||||
var/current_url
|
||||
if (owner && owner.prefs.usewmp)
|
||||
current_url = url_even
|
||||
else
|
||||
switch (currently_broadcasting)
|
||||
if (JUKEBOX_ODD_PLAYER)
|
||||
current_url = url_odd
|
||||
if (JUKEBOX_EVEN_PLAYER)
|
||||
current_url = url_even
|
||||
if (current_url != targetURL || abs(targetStartTime - start_time) > 1 || abs(targetVolume - source_volume) > 0.1 /* 10% */)
|
||||
start_time = targetStartTime
|
||||
source_volume = clamp(targetVolume, 0, 1)
|
||||
send_update()
|
||||
send_update(targetURL)
|
||||
|
||||
/datum/media_manager/proc/stop_music()
|
||||
push_music("",0,1)
|
||||
owner << output(list2params(list("", world.time, 1)), "[window_odd]:SetMusic")
|
||||
owner << output(list2params(list("", world.time, 1)), "[window_even]:SetMusic")
|
||||
|
||||
// Scan for media sources and use them.
|
||||
/datum/media_manager/proc/update_music()
|
||||
@@ -207,10 +245,27 @@ to_chat(#define MP_DEBUG(x) owner, x)
|
||||
stop_music()
|
||||
return
|
||||
var/obj/machinery/media/M = A.media_source // TODO: turn into a list, then only play the first one that's playing.
|
||||
|
||||
var/current_url
|
||||
if (owner.prefs.usewmp) // WMP only uses the even broadcaster
|
||||
current_url = url_even
|
||||
else
|
||||
switch (currently_broadcasting)
|
||||
if (JUKEBOX_ODD_PLAYER)
|
||||
current_url = url_odd
|
||||
if (JUKEBOX_EVEN_PLAYER)
|
||||
current_url = url_even
|
||||
|
||||
if(M && M.playing)
|
||||
MP_DEBUG("<span class='good'>[round(world.time - finish_time, 4)/10] seconds skipped...<span>")
|
||||
if ((targetURL =! current_url) && (finish_time > 0) && (world.time - finish_time < -10 SECONDS)) // We caught a music. Let's see if we can make a graceful fadeout for the music currently playing. If not, the other music is killed.
|
||||
MP_DEBUG("<span class='good'>Should be cutting off music.<span>")
|
||||
stop_music()
|
||||
sleep(1 SECONDS) // Have to wait for the media player response.
|
||||
targetURL = M.media_url
|
||||
targetStartTime = M.media_start_time
|
||||
targetVolume = M.volume
|
||||
src.finish_time = M.media_finish_time
|
||||
// to_chat(owner, "Found audio source: [M.media_url] @ [(world.time - start_time) / 10]s.")
|
||||
//else
|
||||
// testing("M is not playing or null.")
|
||||
|
||||
@@ -386,32 +386,32 @@ menu "menu"
|
||||
name = "&Client"
|
||||
command = ""
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
elem
|
||||
name = "&Quick screenshot\tF2"
|
||||
command = ".screenshot auto"
|
||||
category = "&Client"
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
elem
|
||||
name = "&Save screenshot as...\tShift+F2"
|
||||
command = ".screenshot"
|
||||
category = "&Client"
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
elem
|
||||
name = ""
|
||||
command = ""
|
||||
category = "&Client"
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
elem
|
||||
name = "Reconnect"
|
||||
command = ".reconnect"
|
||||
category = "&Client"
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
elem
|
||||
name = "&Quit"
|
||||
command = ".quit"
|
||||
category = "&Client"
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
elem
|
||||
name = "&Display"
|
||||
command = ""
|
||||
saved-params = "is-checked"
|
||||
@@ -429,15 +429,15 @@ menu "menu"
|
||||
is-checked = true
|
||||
can-check = true
|
||||
group = "scaling"
|
||||
saved-params = "is-checked"
|
||||
saved-params = "is-checked"
|
||||
elem "blur"
|
||||
name = "&Blur"
|
||||
command = ".winset \"mapwindow.map.zoom-mode=blur\""
|
||||
category = "&Display"
|
||||
group = "scaling"
|
||||
can-check = true
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
name = ""
|
||||
command = ""
|
||||
category = "&Display"
|
||||
@@ -449,8 +449,8 @@ menu "menu"
|
||||
is-checked = true
|
||||
can-check = true
|
||||
group = "size"
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
name = ""
|
||||
command = ""
|
||||
category = "&Display"
|
||||
@@ -490,7 +490,7 @@ menu "menu"
|
||||
can-check = true
|
||||
group = "size"
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
elem
|
||||
name = ""
|
||||
command = ""
|
||||
category = "&Display"
|
||||
@@ -512,16 +512,16 @@ menu "menu"
|
||||
category = "&Display"
|
||||
can-check = true
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
elem
|
||||
name = "&Help"
|
||||
command = ""
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
elem
|
||||
name = "&Admin help\tF1"
|
||||
command = "adminhelp"
|
||||
category = "&Help"
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
elem
|
||||
name = "&Hotkeys"
|
||||
command = "hotkeys-help"
|
||||
category = "&Help"
|
||||
@@ -530,12 +530,12 @@ menu "menu"
|
||||
name = "Settings"
|
||||
command = ""
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
elem
|
||||
name = "General Settings"
|
||||
command = "modifypreferences 1"
|
||||
category = "Settings"
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
elem
|
||||
name = "Special Roles"
|
||||
command = "modifypreferences 2"
|
||||
category = "Settings"
|
||||
@@ -545,12 +545,12 @@ menu "menu"
|
||||
command = ""
|
||||
is-disabled = true
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
elem
|
||||
name = "Profiler"
|
||||
command = ".profile"
|
||||
category = "Server"
|
||||
saved-params = "is-checked"
|
||||
elem
|
||||
elem
|
||||
name = ""
|
||||
command = ""
|
||||
category = "Server"
|
||||
@@ -883,6 +883,14 @@ window "rpane"
|
||||
anchor2 = none
|
||||
is-visible = false
|
||||
saved-params = ""
|
||||
elem "hosttracker2"
|
||||
type = BROWSER
|
||||
pos = 392,25
|
||||
size = 1x1
|
||||
anchor1 = none
|
||||
anchor2 = none
|
||||
is-visible = false
|
||||
saved-params = ""
|
||||
elem "rulesb"
|
||||
type = BUTTON
|
||||
pos = 253,0
|
||||
|
||||
Reference in New Issue
Block a user