From 8748e6d83edb90c6e0b404be2d2ad3860c9bccb0 Mon Sep 17 00:00:00 2001 From: JJRcop Date: Fri, 8 Mar 2019 10:51:04 -0500 Subject: [PATCH] Internet midi respects start and end times (#43021) * Play Internet Sound respects start time For example, adding &t=400 to youtube links. Doesn't try to parse the start time, youtube-dl does that for us already. Will probably work on most sites not just youtube. * [Play Internet Sound] now supports end time too Switched event handler for start to loadeddata from canplay loadeddata fires when the first frame is available this is quicker and more consistent than canplay, which tries to predict at least a few moments of playability being available before it fires * [Internet Sound] music_extra_data now starts null --- code/modules/admin/verbs/playsound.dm | 6 ++- code/modules/goonchat/browserOutput.dm | 10 +++-- .../browserassets/js/browserOutput.js | 37 +++++++++++++++++++ 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index 14f6d1f945d..83b0399b214 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -67,7 +67,7 @@ if(istext(web_sound_input)) var/web_sound_url = "" var/stop_web_sounds = FALSE - var/pitch + var/list/music_extra_data = list() if(length(web_sound_input)) web_sound_input = trim(web_sound_input) @@ -95,6 +95,8 @@ var/webpage_url = title if (data["webpage_url"]) webpage_url = "[title]" + music_extra_data["start"] = data["start_time"] + music_extra_data["end"] = data["end_time"] var/res = alert(usr, "Show the title of and link to this song to the players?\n[title]",, "No", "Yes", "Cancel") switch(res) @@ -126,7 +128,7 @@ var/client/C = M.client if((C.prefs.toggles & SOUND_MIDI) && C.chatOutput && !C.chatOutput.broken && C.chatOutput.loaded) if(!stop_web_sounds) - C.chatOutput.sendMusic(web_sound_url, pitch) + C.chatOutput.sendMusic(web_sound_url, music_extra_data) else C.chatOutput.stopMusic() diff --git a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm index 463df71f715..d148e3af865 100644 --- a/code/modules/goonchat/browserOutput.dm +++ b/code/modules/goonchat/browserOutput.dm @@ -115,12 +115,16 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico data = json_encode(data) C << output("[data]", "[window]:ehjaxCallback") -/datum/chatOutput/proc/sendMusic(music, pitch) +/datum/chatOutput/proc/sendMusic(music, list/extra_data) if(!findtext(music, GLOB.is_http_protocol)) return var/list/music_data = list("adminMusic" = url_encode(url_encode(music))) - if(pitch) - music_data["musicRate"] = pitch + + if(extra_data?.len) + music_data["musicRate"] = extra_data["pitch"] + music_data["musicSeek"] = extra_data["start"] + music_data["musicHalt"] = extra_data["end"] + ehjax_send(data = music_data) /datum/chatOutput/proc/stopMusic() diff --git a/code/modules/goonchat/browserassets/js/browserOutput.js b/code/modules/goonchat/browserassets/js/browserOutput.js index 6468e7fc754..ac759be7cfe 100644 --- a/code/modules/goonchat/browserassets/js/browserOutput.js +++ b/code/modules/goonchat/browserassets/js/browserOutput.js @@ -65,6 +65,8 @@ var opts = { 'volumeUpdateDelay': 5000, //Time from when the volume updates to data being sent to the server 'volumeUpdating': false, //True if volume update function set to fire 'updatedVolume': 0, //The volume level that is sent to the server + 'musicStartAt': 0, //The position the music starts playing + 'musicEndAt': 0, //The position the music... stops playing... if null, doesn't apply (so the music runs through) 'defaultMusicVolume': 25, @@ -543,6 +545,7 @@ function ehjaxCallback(data) { } else if (data.adminMusic) { if (typeof data.adminMusic === 'string') { var adminMusic = byondDecode(data.adminMusic); + var bindLoadedData = false; adminMusic = adminMusic.match(/https?:\/\/\S+/) || ''; if (data.musicRate) { var newRate = Number(data.musicRate); @@ -552,6 +555,19 @@ function ehjaxCallback(data) { } else { $('#adminMusic').prop('defaultPlaybackRate', 1.0); } + if (data.musicSeek) { + opts.musicStartAt = Number(data.musicSeek) || 0; + bindLoadedData = true; + } else { + opts.musicStartAt = 0; + } + if (data.musicHalt) { + opts.musicEndAt = Number(data.musicHalt) || null; + bindLoadedData = true; + } + if (bindLoadedData) { + $('#adminMusic').one('loadeddata', adminMusicLoadedData); + } $('#adminMusic').prop('src', adminMusic); $('#adminMusic').trigger("play"); } @@ -585,6 +601,27 @@ function sendVolumeUpdate() { } } +function adminMusicEndCheck(event) { + if (opts.musicEndAt) { + if ($('#adminMusic').prop('currentTime') >= opts.musicEndAt) { + $('#adminMusic').off(event); + $('#adminMusic').trigger('pause'); + $('#adminMusic').prop('src', ''); + } + } else { + $('#adminMusic').off(event); + } +} + +function adminMusicLoadedData(event) { + if (opts.musicStartAt && ($('#adminMusic').prop('duration') === Infinity || (opts.musicStartAt <= $('#adminMusic').prop('duration'))) ) { + $('#adminMusic').prop('currentTime', opts.musicStartAt); + } + if (opts.musicEndAt) { + $('#adminMusic').on('timeupdate', adminMusicEndCheck); + } +} + function subSlideUp() { $(this).removeClass('scroll'); $(this).css('height', '');