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:
ShiftyRail
2020-05-21 05:20:24 +02:00
committed by GitHub
parent 587297e906
commit 10a2cac0cd
5 changed files with 111 additions and 33 deletions

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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.")

View File

@@ -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