From 4ff1c25f2263184ad226b45673f041eca3ffbbde Mon Sep 17 00:00:00 2001 From: emeric Date: Thu, 13 Feb 2025 11:45:19 +0100 Subject: [PATCH] Attempt to reduce issues when loading the mediaplayer js code, ref #609 --- docroot/js/mediaplayer.js | 672 ++++++++++++++++++------------------- src/lms/ui/MediaPlayer.cpp | 8 +- 2 files changed, 340 insertions(+), 340 deletions(-) diff --git a/docroot/js/mediaplayer.js b/docroot/js/mediaplayer.js index f1857145..0e0ead83 100644 --- a/docroot/js/mediaplayer.js +++ b/docroot/js/mediaplayer.js @@ -1,126 +1,257 @@ // @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3-or-Later -var LMS = LMS || {}; - // Keep in sync with MediaPlayer::TranscodingMode cpp -const TranscodingMode = { +LMSTranscodingMode = { Never: 0, Always: 1, IfFormatNotSupported: 2, } +Object.freeze(LMSTranscodingMode); -const Mode = { - Transcoding: 1, - File: 2, -} -Object.freeze(Mode); +class LMSMediaPlayer { + // How much to increase / decrease volume when adjusting it with keyboard shortcuts + static #volumeStepAmount = 0.05; -// How much to increase / decrease volume when adjusting it with keyboard shortcuts -const volumeStepAmount = 0.05; + // How much to seek back / forward (in seconds) with keyboard shortcuts + static #seekAmount = 5; -// How much to seek back / forward (in seconds) with keyboard shortcuts -const seekAmount = 5; + static #Mode = { + Transcoding: 1, + File: 2, + } -LMS.mediaplayer = function () { - let _root = {}; - let _elems = {}; - let _offset = 0; - let _trackId = null; - let _duration = 0; - let _audioNativeSrc; - let _audioTranscodingSrc; - let _settings = {}; - let _playedDuration = 0; - let _lastStartPlaying = null; - let _audioIsInit = false; - let _pendingTrackParameters = null; - let _gainNode = null; - let _audioCtx = null; + #root; + #elems; + #offset; + #trackId; + #duration; + #audioNativeSrc; + #audioTranscodingSrc; + #settings; + #playedDuration; + #lastStartPlaying; + #audioIsInit; + #pendingTrackParameters; + #gainNode; + #audioCtx; - let _unlock = function() { - document.removeEventListener("touchstart", _unlock); - document.removeEventListener("touchend", _unlock); - document.removeEventListener("click", _unlock); - _initAudioCtx(); + constructor(root, defaultSettings) { + this.#root = root; + this.#elems = {}; + this.#offset = 0; + this.#trackId = null; + this.#duration = 0; + this.#audioNativeSrc; + this.#audioTranscodingSrc; + this.#settings = {}; + this.#playedDuration = 0; + this.#lastStartPlaying = null; + this.#audioIsInit = false; + this.#pendingTrackParameters = null; + this.#gainNode = null; + this.#audioCtx = null; + + this.#elems.audio = document.getElementById("lms-mp-audio"); + this.#elems.playpause = document.getElementById("lms-mp-playpause"); + this.#elems.previous = document.getElementById("lms-mp-previous"); + this.#elems.next = document.getElementById("lms-mp-next"); + this.#elems.progress = document.getElementById("lms-mp-progress"); + this.#elems.seek = document.getElementById("lms-mp-seek"); + this.#elems.curtime = document.getElementById("lms-mp-curtime"); + this.#elems.duration = document.getElementById("lms-mp-duration"); + this.#elems.volume = document.getElementById("lms-mp-volume"); + this.#elems.volumeslider = document.getElementById("lms-mp-volume-slider"); + this.#elems.transcodingActive = document.getElementById("lms-transcoding-active"); + + this.#elems.playpause.addEventListener("click", () => { + this.#playPause(); + }); + + this.#elems.previous.addEventListener("click", () => { + this.#playPrevious(); + }); + this.#elems.next.addEventListener("click", () => { + this.#playNext(); + }); + this.#elems.seek.addEventListener("change", () => { + this.#seekTo(parseInt(this.#elems.seek.value, 10)); + }); + + this.#elems.audio.addEventListener("play", this.#updateControls.bind(this)); + this.#elems.audio.addEventListener("playing", this.#updateControls.bind(this)); + this.#elems.audio.addEventListener("pause", this.#updateControls.bind(this)); + + this.#elems.audio.addEventListener("play", this.#updateMediaSessionState.bind(this)); + this.#elems.audio.addEventListener("playing", this.#updateMediaSessionState.bind(this)); + this.#elems.audio.addEventListener("pause", this.#updateMediaSessionState.bind(this)); + + this.#elems.audio.addEventListener("pause", this.#pauseTimer); + this.#elems.audio.addEventListener("playing", this.#startTimer.bind(this)); + this.#elems.audio.addEventListener("waiting", this.#pauseTimer.bind(this)); + + this.#elems.audio.addEventListener("timeupdate", () => { + this.#elems.progress.style.width = "" + ((this.#offset + this.#elems.audio.currentTime) / this.#duration) * 100 + "%"; + this.#elems.curtime.innerHTML = this.#durationToString(this.#offset + this.#elems.audio.currentTime); + }); + + this.#elems.audio.addEventListener("ended", () => { + this.#resetTimer(); + Wt.emit(this.#root, "playbackEnded"); + }); + + this.#elems.audio.addEventListener("canplay", () => { + if (this.#getAudioMode() == LMSMediaPlayer.#Mode.Transcoding) { + this.#elems.transcodingActive.style.display = "inline"; + } + else { + this.#elems.transcodingActive.style.display = "none"; + } + }); + + this.#initVolume(); + this.#initDefaultSettings(defaultSettings); + + this.#elems.volumeslider.addEventListener("input", () => { + this.#setVolume(this.#elems.volumeslider.value); + }); + + this.#elems.volume.addEventListener("click", () => { + if (this.#elems.audio.volume != 0) { + this.#setVolume(0); + } + else { + this.#setVolume(this.#elems.lastvolume); + } + }); + + document.addEventListener("keydown", (event) => { + let handled = false; + + if (event.target instanceof HTMLInputElement) + return; + + if (event.keyCode == 32) { + this.#playPause(); + handled = true; + } + else if (event.ctrlKey && !event.shiftKey && event.keyCode == 37) { + this.#playPrevious(); + handled = true; + } + else if (event.ctrlKey && !event.shiftKey && event.keyCode == 39) { + this.#playNext(); + handled = true; + } + else if (event.ctrlKey && event.keyCode == 40) { + this.#stepVolumeDown(); + handled = true; + } + else if (event.ctrlKey && event.keyCode == 38) { + this.#stepVolumeUp(); + handled = true; + } + else if (event.ctrlKey && event.shiftKey && event.keyCode == 37) { + this.#seekBack(); + handled = true; + } + else if (event.ctrlKey && event.shiftKey && event.keyCode == 39) { + this.#seekForward(); + handled = true; + } + + if (handled) + event.preventDefault(); + }); + + document.addEventListener("touchstart", this.#unlock.bind(this)); + document.addEventListener("touchend", this.#unlock.bind(this)); + document.addEventListener("click", this.#unlock.bind(this)); + } + + #unlock() { + document.removeEventListener("touchstart", this.#unlock.bind(this)); + document.removeEventListener("touchend", this.#unlock.bind(this)); + document.removeEventListener("click", this.#unlock.bind(this)); + this.#initAudioCtx(); }; - let _initAudioCtx = function() { - if (_audioIsInit) { - _audioCtx.resume(); // not sure of this + #initAudioCtx() { + if (this.#audioIsInit) { + this.#audioCtx.resume(); // not sure of this return; } - _audioIsInit = true; + this.#audioIsInit = true; - _audioCtx = new (window.AudioContext || window.webkitAudioContext)(); - _gainNode = _audioCtx.createGain(); - let source = _audioCtx.createMediaElementSource(_elems.audio); - source.connect(_gainNode); - _gainNode.connect(_audioCtx.destination); - _audioCtx.resume(); // not sure of this + this.#audioCtx = new (window.AudioContext || window.webkitAudioContext)(); + this.#gainNode = this.#audioCtx.createGain(); + let source = this.#audioCtx.createMediaElementSource(this.#elems.audio); + source.connect(this.#gainNode); + this.#gainNode.connect(this.#audioCtx.destination); + this.#audioCtx.resume(); // not sure of this if ("mediaSession" in navigator) { - navigator.mediaSession.setActionHandler("play", function() { - _playPause(); + navigator.mediaSession.setActionHandler("play", () => { + this.#playPause(); }); - navigator.mediaSession.setActionHandler("pause", function() { - _playPause(); + navigator.mediaSession.setActionHandler("pause", () => { + this.#playPause(); }); - navigator.mediaSession.setActionHandler("previoustrack", function() { - _playPrevious(); + navigator.mediaSession.setActionHandler("previoustrack", () => { + this.#playPrevious(); }); - navigator.mediaSession.setActionHandler("nexttrack", function() { - _playNext(); + navigator.mediaSession.setActionHandler("nexttrack", () => { + this.#playNext(); }); - navigator.mediaSession.setActionHandler("seekto", function(e) { - _seekTo(e.seekTime); + navigator.mediaSession.setActionHandler("seekto", (e) => { + this.#seekTo(e.seekTime); }); } - if (_pendingTrackParameters != null) { - _applyAudioTrackParameters(_pendingTrackParameters); - _pendingTrackParameters = null; + if (this.#pendingTrackParameters != null) { + this.#applyAudioTrackParameters(this.#pendingTrackParameters); + this.#pendingTrackParameters = null; } } - let _updateControls = function() { + #updateControls() { const pauseClass = "fa-pause"; const playClass = "fa-play"; - if (_elems.audio.paused) { - _elems.playpause.firstElementChild.classList.remove(pauseClass); - _elems.playpause.firstElementChild.classList.add(playClass); + if (this.#elems.audio.paused) { + this.#elems.playpause.firstElementChild.classList.remove(pauseClass); + this.#elems.playpause.firstElementChild.classList.add(playClass); } else { - _elems.playpause.firstElementChild.classList.remove(playClass); - _elems.playpause.firstElementChild.classList.add(pauseClass); + this.#elems.playpause.firstElementChild.classList.remove(playClass); + this.#elems.playpause.firstElementChild.classList.add(pauseClass); } } - let _startTimer = function() { - if (_lastStartPlaying == null) - Wt.emit(_root, "scrobbleListenNow", _trackId); - _lastStartPlaying = Date.now(); + #startTimer() { + if (this.#lastStartPlaying == null) + Wt.emit(this.#root, "scrobbleListenNow", this.#trackId); + this.#lastStartPlaying = Date.now(); } - let _pauseTimer = function() { - if (_lastStartPlaying != null) { - _playedDuration += Date.now() - _lastStartPlaying; - _lastStartPlaying = null; + #pauseTimer() { + if (this.#lastStartPlaying != null) { + this.#playedDuration += Date.now() - this.#lastStartPlaying; + this.#lastStartPlaying = null; } } - let _resetTimer = function() { - if (_lastStartPlaying != null) - _pauseTimer(); + #resetTimer() { + if (this.#lastStartPlaying != null) + this.#pauseTimer(); - if (_playedDuration > 0) { - Wt.emit(_root, "scrobbleListenFinished", _trackId, _playedDuration); - _playedDuration = 0; + if (this.#playedDuration > 0) { + Wt.emit(this.#root, "scrobbleListenFinished", this.#trackId, this.#playedDuration); + this.#playedDuration = 0; } } - let _durationToString = function (duration) { + #durationToString(duration) { const seconds = parseInt(duration, 10); const h = Math.floor(seconds / 3600); const m = Math.floor((seconds % 3600) / 60); @@ -132,332 +263,173 @@ LMS.mediaplayer = function () { ].filter(Boolean).join(':'); } - let _playTrack = function() { - _elems.audio.play() - .then(_ => {}) + #playTrack() { + this.#elems.audio.play() + .then(_ => { }) .catch(error => { console.log("Cannot play audio: " + error); }); } - let _playPause = function() { - _initAudioCtx(); + #playPause() { + this.#initAudioCtx(); - if (_elems.audio.paused && _elems.audio.children.length > 0) { - _playTrack(); + if (this.#elems.audio.paused && this.#elems.audio.children.length > 0) { + this.#playTrack(); } else - _elems.audio.pause(); + this.#elems.audio.pause(); } - let _playPrevious = function() { - _initAudioCtx(); - Wt.emit(_root, "playPrevious"); + #playPrevious() { + this.#initAudioCtx(); + Wt.emit(this.#root, "playPrevious"); } - let _playNext = function() { - _initAudioCtx(); - Wt.emit(_root, "playNext"); + #playNext() { + this.#initAudioCtx(); + Wt.emit(this.#root, "playNext"); } - let _initVolume = function() { - if (typeof(Storage) !== "undefined" && localStorage.volume) { - _elems.volumeslider.value = Number(localStorage.volume); + #initVolume() { + if (typeof (Storage) !== "undefined" && localStorage.volume) { + this.#elems.volumeslider.value = Number(localStorage.volume); } - _setVolume(_elems.volumeslider.value); + this.#setVolume(this.#elems.volumeslider.value); } - let _initDefaultSettings = function(defaultSettings) { - if (typeof(Storage) !== "undefined" && localStorage.settings) { - _settings = Object.assign(defaultSettings, JSON.parse(localStorage.settings)); + #initDefaultSettings = function (defaultSettings) { + if (typeof (Storage) !== "undefined" && localStorage.settings) { + this.#settings = Object.assign(defaultSettings, JSON.parse(localStorage.settings)); } else { - _settings = defaultSettings; + this.#settings = defaultSettings; } - Wt.emit(_root, "settingsLoaded", JSON.stringify(_settings)); + Wt.emit(this.#root, "settingsLoaded", JSON.stringify(this.#settings)); } - let _setVolume = function(volume) { - _elems.lastvolume = _elems.audio.volume; + #setVolume(volume) { + this.#elems.lastvolume = this.#elems.audio.volume; - _elems.audio.volume = volume; - _elems.volumeslider.value = volume; + this.#elems.audio.volume = volume; + this.#elems.volumeslider.value = volume; if (volume > 0.5) { - _elems.volume.classList.remove("fa-volume-off"); - _elems.volume.classList.remove("fa-volume-down"); - _elems.volume.classList.add("fa-volume-up"); + this.#elems.volume.classList.remove("fa-volume-off"); + this.#elems.volume.classList.remove("fa-volume-down"); + this.#elems.volume.classList.add("fa-volume-up"); } else if (volume > 0) { - _elems.volume.classList.remove("fa-volume-off"); - _elems.volume.classList.remove("fa-volume-up"); - _elems.volume.classList.add("fa-volume-down"); - + this.#elems.volume.classList.remove("fa-volume-off"); + this.#elems.volume.classList.remove("fa-volume-up"); + this.#elems.volume.classList.add("fa-volume-down"); } else { - _elems.volume.classList.remove("fa-volume-up"); - _elems.volume.classList.remove("fa-volume-down"); - _elems.volume.classList.add("fa-volume-off"); + this.#elems.volume.classList.remove("fa-volume-up"); + this.#elems.volume.classList.remove("fa-volume-down"); + this.#elems.volume.classList.add("fa-volume-off"); } - if (typeof(Storage) !== "undefined") { + if (typeof (Storage) !== "undefined") { localStorage.volume = volume; } } - let _stepVolumeDown = function() { - let currentVolume = _elems.audio.volume; - let remainder = (currentVolume * 10) % (volumeStepAmount * 10); - let newVolume = remainder === 0 ? currentVolume - volumeStepAmount : currentVolume - (remainder / 10); - _setVolume(Math.max(newVolume, 0)); + #stepVolumeDown() { + let currentVolume = this.#elems.audio.volume; + let remainder = (currentVolume * 10) % (LMSMediaPlayer.#volumeStepAmount * 10); + let newVolume = remainder === 0 ? currentVolume - LMSMediaPlayer.#volumeStepAmount : currentVolume - (remainder / 10); + this.#setVolume(Math.max(newVolume, 0)); } - let _stepVolumeUp = function() { - let currentVolume = _elems.audio.volume; - let remainder = (currentVolume * 10) % (volumeStepAmount * 10); - let newVolume = remainder === 0 ? currentVolume + volumeStepAmount : currentVolume + (volumeStepAmount - (remainder / 10)); - _setVolume(Math.min(newVolume, 1)); + #stepVolumeUp() { + let currentVolume = this.#elems.audio.volume; + let remainder = (currentVolume * 10) % (LMSMediaPlayer.#volumeStepAmount * 10); + let newVolume = remainder === 0 ? currentVolume + LMSMediaPlayer.#volumeStepAmount : currentVolume + (LMSMediaPlayer.#volumeStepAmount - (remainder / 10)); + this.#setVolume(Math.min(newVolume, 1)); } - let _setReplayGain = function (replayGain) { - _gainNode.gain.value = Math.pow(10, (_settings.replayGain.preAmpGain + replayGain) / 20); + #setReplayGain(replayGain) { + this.#gainNode.gain.value = Math.pow(10, (this.#settings.replayGain.preAmpGain + replayGain) / 20); } - let _seekTo = function(seekTime) { - _initAudioCtx(); - let mode = _getAudioMode(); + #seekTo(seekTime) { + this.#initAudioCtx(); + let mode = this.#getAudioMode(); if (!mode) return; switch (mode) { - case Mode.Transcoding: - _offset = seekTime; - _removeAudioSources(); - _addAudioSource(_audioTranscodingSrc + "&offset=" + _offset); - _elems.audio.load(); - _elems.audio.currentTime = 0; - _playTrack(); + case LMSMediaPlayer.#Mode.Transcoding: + this.#offset = seekTime; + this.#removeAudioSources(); + this.#addAudioSource(this.#audioTranscodingSrc + "&offset=" + this.#offset); + this.#elems.audio.load(); + this.#elems.audio.currentTime = 0; + this.#playTrack(); break; - case Mode.File: - _elems.audio.currentTime = seekTime; - _playTrack(); + case LMSMediaPlayer.#Mode.File: + this.#elems.audio.currentTime = seekTime; + this.#playTrack(); break; } - _updateMediaSessionState(); + this.#updateMediaSessionState(); } - let _seekBack = function() { - let currentPosition = _offset + _elems.audio.currentTime; - let newPosition = currentPosition - seekAmount; - _seekTo(Math.max(newPosition, 0)); + #seekBack() { + let currentPosition = this.#offset + this.#elems.audio.currentTime; + let newPosition = currentPosition - LMSMediaPlayer.#seekAmount; + this.#seekTo(Math.max(newPosition, 0)); } - let _seekForward = function() { - let currentPosition = _offset + _elems.audio.currentTime; - let newPosition = currentPosition + seekAmount; - _seekTo(Math.min(newPosition, _duration)); + #seekForward() { + let currentPosition = this.#offset + this.#elems.audio.currentTime; + let newPosition = currentPosition + LMSMediaPlayer.#seekAmount; + this.#seekTo(Math.min(newPosition, this.#duration)); } - let _updateMediaSessionState = function() { + #updateMediaSessionState() { if ("mediaSession" in navigator) { navigator.mediaSession.setPositionState({ - duration: _duration, + duration: this.#duration, playbackRate: 1, - position: Math.min(_offset + _elems.audio.currentTime, _duration), + position: Math.min(this.#offset + this.#elems.audio.currentTime, this.#duration), }); - if (_elems.audio.paused) + if (this.#elems.audio.paused) navigator.mediaSession.playbackState = "paused"; else navigator.mediaSession.playbackState = "playing"; } } - let init = function(root, defaultSettings) { - _root = root; - - _elems.audio = document.getElementById("lms-mp-audio"); - _elems.playpause = document.getElementById("lms-mp-playpause"); - _elems.previous = document.getElementById("lms-mp-previous"); - _elems.next = document.getElementById("lms-mp-next"); - _elems.progress = document.getElementById("lms-mp-progress"); - _elems.seek = document.getElementById("lms-mp-seek"); - _elems.curtime = document.getElementById("lms-mp-curtime"); - _elems.duration = document.getElementById("lms-mp-duration"); - _elems.volume = document.getElementById("lms-mp-volume"); - _elems.volumeslider = document.getElementById("lms-mp-volume-slider"); - _elems.transcodingActive = document.getElementById("lms-transcoding-active"); - - _elems.playpause.addEventListener("click", function() { - _playPause(); - }); - - _elems.previous.addEventListener("click", function() { - _playPrevious(); - }); - _elems.next.addEventListener("click", function() { - _playNext(); - }); - _elems.seek.addEventListener("change", function() { - _seekTo(parseInt(_elems.seek.value, 10)); - }); - - _elems.audio.addEventListener("play", _updateControls); - _elems.audio.addEventListener("playing", _updateControls); - _elems.audio.addEventListener("pause", _updateControls); - - _elems.audio.addEventListener("play", _updateMediaSessionState); - _elems.audio.addEventListener("playing", _updateMediaSessionState); - _elems.audio.addEventListener("pause", _updateMediaSessionState); - - _elems.audio.addEventListener("pause", _pauseTimer); - _elems.audio.addEventListener("playing", _startTimer); - _elems.audio.addEventListener("waiting", _pauseTimer); - - _elems.audio.addEventListener("timeupdate", function() { - _elems.progress.style.width = "" + ((_offset + _elems.audio.currentTime) / _duration) * 100 + "%"; - _elems.curtime.innerHTML = _durationToString(_offset + _elems.audio.currentTime); - }); - - _elems.audio.addEventListener("ended", function() { - _resetTimer(); - Wt.emit(_root, "playbackEnded"); - }); - - _elems.audio.addEventListener("canplay", function() { - if (_getAudioMode() == Mode.Transcoding) { - _elems.transcodingActive.style.display = "inline"; - } - else { - _elems.transcodingActive.style.display = "none"; - } - }); - - _initVolume(); - _initDefaultSettings(defaultSettings); - - _elems.volumeslider.addEventListener("input", function() { - _setVolume(_elems.volumeslider.value); - }); - - _elems.volume.addEventListener("click", function () { - if (_elems.audio.volume != 0) { - _setVolume(0); - } - else { - _setVolume(_elems.lastvolume); - } - }); - - document.addEventListener("keydown", function(event) { - let handled = false; - - if (event.target instanceof HTMLInputElement) - return; - - if (event.keyCode == 32) { - _playPause(); - handled = true; - } - else if (event.ctrlKey && !event.shiftKey && event.keyCode == 37) { - _playPrevious(); - handled = true; - } - else if (event.ctrlKey && !event.shiftKey && event.keyCode == 39) { - _playNext(); - handled = true; - } - else if (event.ctrlKey && event.keyCode == 40) { - _stepVolumeDown(); - handled = true; - } - else if (event.ctrlKey && event.keyCode == 38) { - _stepVolumeUp(); - handled = true; - } - else if (event.ctrlKey && event.shiftKey && event.keyCode == 37) { - _seekBack(); - handled = true; - } - else if (event.ctrlKey && event.shiftKey && event.keyCode == 39) { - _seekForward(); - handled = true; - } - - if (handled) - event.preventDefault(); - }); - - document.addEventListener("touchstart", _unlock); - document.addEventListener("touchend", _unlock); - document.addEventListener("click", _unlock); - } - - let _removeAudioSources = function() { - while ( _elems.audio.lastElementChild) { - _elems.audio.removeChild( _elems.audio.lastElementChild); + #removeAudioSources() { + while (this.#elems.audio.lastElementChild) { + this.#elems.audio.removeChild(this.#elems.audio.lastElementChild); } } - let _addAudioSource = function(audioSrc) { + #addAudioSource(audioSrc) { let source = document.createElement('source'); source.src = audioSrc; - _elems.audio.appendChild(source); + this.#elems.audio.appendChild(source); } - let _getAudioMode = function() { - if (_elems.audio.currentSrc) { - if (_elems.audio.currentSrc.includes("format")) - return Mode.Transcoding; + #getAudioMode() { + if (this.#elems.audio.currentSrc) { + if (this.#elems.audio.currentSrc.includes("format")) + return LMSMediaPlayer.#Mode.Transcoding; else - return Mode.File; + return LMSMediaPlayer.#Mode.File; } else return undefined; } - let loadTrack = function(params, autoplay) { - _resetTimer(); - - _trackId = params.trackId; - _offset = 0; - _duration = params.duration; - _audioNativeSrc = params.nativeResource; - _audioTranscodingSrc = params.transcodingResource + "&bitrate=" + _settings.transcoding.bitrate + "&format=" + _settings.transcoding.format; - - _elems.seek.max = _duration; - - _removeAudioSources(); - // ! order is important - if (_settings.transcoding.mode == TranscodingMode.Never || _settings.transcoding.mode == TranscodingMode.IfFormatNotSupported) - { - _addAudioSource(_audioNativeSrc); - } - if (_settings.transcoding.mode == TranscodingMode.Always || _settings.transcoding.mode == TranscodingMode.IfFormatNotSupported) - { - _addAudioSource(_audioTranscodingSrc); - } - _elems.audio.load(); - - _elems.curtime.innerHTML = _durationToString(_offset); - _elems.duration.innerHTML = _durationToString(_duration); - - if (!_audioIsInit) { - _pendingTrackParameters = params; - return; - } - - _applyAudioTrackParameters(params); - - if (autoplay && _audioCtx.state == "running") - _playTrack(); - } - - let _applyAudioTrackParameters = function(params) - { - _setReplayGain(params.replayGain); + #applyAudioTrackParameters(params) { + this.#setReplayGain(params.replayGain); if ("mediaSession" in navigator) { navigator.mediaSession.metadata = new MediaMetadata({ title: params.title, @@ -468,24 +440,52 @@ LMS.mediaplayer = function () { } } - let stop = function() { - _elems.audio.pause(); + loadTrack(params, autoplay) { + this.#resetTimer(); + + this.#trackId = params.trackId; + this.#offset = 0; + this.#duration = params.duration; + this.#audioNativeSrc = params.nativeResource; + this.#audioTranscodingSrc = params.transcodingResource + "&bitrate=" + this.#settings.transcoding.bitrate + "&format=" + this.#settings.transcoding.format; + + this.#elems.seek.max = this.#duration; + + this.#removeAudioSources(); + // ! order is important + if (this.#settings.transcoding.mode == LMSTranscodingMode.Never || this.#settings.transcoding.mode == LMSTranscodingMode.IfFormatNotSupported) { + this.#addAudioSource(this.#audioNativeSrc); + } + if (this.#settings.transcoding.mode == LMSTranscodingMode.Always || this.#settings.transcoding.mode == LMSTranscodingMode.IfFormatNotSupported) { + this.#addAudioSource(this.#audioTranscodingSrc); + } + this.#elems.audio.load(); + + this.#elems.curtime.innerHTML = this.#durationToString(this.#offset); + this.#elems.duration.innerHTML = this.#durationToString(this.#duration); + + if (!this.#audioIsInit) { + this.#pendingTrackParameters = params; + return; + } + + this.#applyAudioTrackParameters(params); + + if (autoplay && this.#audioCtx.state == "running") + this.#playTrack(); } - let setSettings = function(settings) { - _settings = settings; + stop() { + this.#elems.audio.pause(); + } - if (typeof(Storage) !== "undefined") { - localStorage.settings = JSON.stringify(_settings); + setSettings(settings) { + this.#settings = settings; + + if (typeof (Storage) !== "undefined") { + localStorage.settings = JSON.stringify(this.#settings); } } - - return { - init: init, - loadTrack: loadTrack, - stop: stop, - setSettings: setSettings, - }; -}(); +} // @license-end diff --git a/src/lms/ui/MediaPlayer.cpp b/src/lms/ui/MediaPlayer.cpp index 73c5bec6..87a76c35 100644 --- a/src/lms/ui/MediaPlayer.cpp +++ b/src/lms/ui/MediaPlayer.cpp @@ -213,7 +213,7 @@ namespace lms::ui Settings defaultSettings; std::ostringstream oss; - oss << "LMS.mediaplayer.init(" + oss << jsRef() + ".mediaplayer = new LMSMediaPlayer(" << jsRef() << ", defaultSettings = " << settingsToJSString(defaultSettings) << ")"; @@ -260,7 +260,7 @@ namespace lms::ui // Update 'sizes' above to match this: static_assert(static_cast>(ArtworkResource::Size::Small) == 128); static_assert(static_cast>(ArtworkResource::Size::Large) == 512); - oss << "LMS.mediaplayer.loadTrack(params, " << (play ? "true" : "false") << ")"; // true to autoplay + oss << jsRef() + ".mediaplayer.loadTrack(params, " << (play ? "true" : "false") << ")"; // true to autoplay _title->setTextFormat(Wt::TextFormat::Plain); _title->setText(Wt::WString::fromUTF8(track->getName())); @@ -308,7 +308,7 @@ namespace lms::ui void MediaPlayer::stop() { - doJavaScript("LMS.mediaplayer.stop()"); + doJavaScript(jsRef() + ".mediaplayer.stop()"); } void MediaPlayer::setSettings(const Settings& settings) @@ -317,7 +317,7 @@ namespace lms::ui { std::ostringstream oss; - oss << "LMS.mediaplayer.setSettings(settings = " << settingsToJSString(settings) << ")"; + oss << jsRef() + ".mediaplayer.setSettings(settings = " << settingsToJSString(settings) << ")"; LMS_LOG(UI, DEBUG, "Running js = '" << oss.str() << "'"); doJavaScript(oss.str());