diff --git a/pikaraoke/app.py b/pikaraoke/app.py index 0ae18528..63c5bf21 100644 --- a/pikaraoke/app.py +++ b/pikaraoke/app.py @@ -9,9 +9,9 @@ import sys import flask_babel -from flask import Flask, redirect, request, session, url_for +from flask import Flask, request, session from flask_babel import Babel -from flask_socketio import SocketIO, emit +from flask_socketio import SocketIO from pikaraoke import karaoke from pikaraoke.constants import LANGUAGES @@ -23,6 +23,7 @@ from pikaraoke.lib.selenium import launch_splash_screen from pikaraoke.routes.admin import admin_bp from pikaraoke.routes.background_music import background_music_bp +from pikaraoke.routes.controller import controller_bp from pikaraoke.routes.files import files_bp from pikaraoke.routes.home import home_bp from pikaraoke.routes.images import images_bp @@ -64,11 +65,7 @@ app.register_blueprint(search_bp) app.register_blueprint(info_bp) app.register_blueprint(splash_bp) - - -def broadcast_event(event, data=None): - print("Broadcasting event: " + event) - emit(event, data, namespace="/", broadcast=True) +app.register_blueprint(controller_bp) @babel.localeselector @@ -115,88 +112,6 @@ def nowplaying(): return "" -# Call this after receiving a command in the front end -@app.route("/clear_command") -def clear_command(): - k = get_karaoke_instance() - k.now_playing_command = None - return "" - - -@app.route("/skip") -def skip(): - k = get_karaoke_instance() - broadcast_event("skip") - k.skip() - return redirect(url_for("home.home")) - - -@app.route("/pause") -def pause(): - k = get_karaoke_instance() - if k.is_paused: - broadcast_event("play") - else: - broadcast_event("pause") - k.pause() - return redirect(url_for("home.home")) - - -@app.route("/transpose/", methods=["GET"]) -def transpose(semitones): - k = get_karaoke_instance() - k.transpose_current(int(semitones)) - return redirect(url_for("home.home")) - - -@app.route("/restart") -def restart(): - k = get_karaoke_instance() - broadcast_event("restart") - k.restart() - return redirect(url_for("home.home")) - - -@app.route("/volume/") -def volume(volume): - k = get_karaoke_instance() - broadcast_event("volume", volume) - k.volume_change(float(volume)) - return redirect(url_for("home.home")) - - -@app.route("/vol_up") -def vol_up(): - k = get_karaoke_instance() - broadcast_event("volume", "up") - k.vol_up() - return redirect(url_for("home.home")) - - -@app.route("/vol_down") -def vol_down(): - k = get_karaoke_instance() - broadcast_event("volume", "down") - k.vol_down() - return redirect(url_for("home.home")) - - -@app.route("/end_song", methods=["GET", "POST"]) -def end_song(): - k = get_karaoke_instance() - d = request.form.to_dict() - reason = d["reason"] if "reason" in d else None - k.end_song(reason) - return "ok" - - -@app.route("/start_song", methods=["GET"]) -def start_song(): - k = get_karaoke_instance() - k.start_song() - return "ok" - - def main(): platform = get_platform() diff --git a/pikaraoke/lib/current_app.py b/pikaraoke/lib/current_app.py index ce8c396d..1c10ab3c 100644 --- a/pikaraoke/lib/current_app.py +++ b/pikaraoke/lib/current_app.py @@ -4,6 +4,7 @@ import time from flask import current_app, request +from flask_socketio import emit from pikaraoke.karaoke import Karaoke @@ -50,6 +51,11 @@ def get_site_name() -> str: return current_app.config["SITE_NAME"] +def broadcast_event(event, data=None): + print("Broadcasting event: " + event) + emit(event, data, namespace="/", broadcast=True) + + def delayed_halt(cmd): time.sleep(1.5) current_app.k.queue_clear() diff --git a/pikaraoke/routes/controller.py b/pikaraoke/routes/controller.py new file mode 100644 index 00000000..7093f1ac --- /dev/null +++ b/pikaraoke/routes/controller.py @@ -0,0 +1,84 @@ +import flask_babel +from flask import Blueprint, redirect, request, url_for + +from pikaraoke.lib.current_app import broadcast_event, get_karaoke_instance + +_ = flask_babel.gettext + + +controller_bp = Blueprint("controller", __name__) + + +@controller_bp.route("/skip") +def skip(): + k = get_karaoke_instance() + broadcast_event("skip", "user command") + k.skip() + return redirect(url_for("home.home")) + + +@controller_bp.route("/pause") +def pause(): + k = get_karaoke_instance() + if k.is_paused: + broadcast_event("play") + else: + broadcast_event("pause") + k.pause() + return redirect(url_for("home.home")) + + +@controller_bp.route("/transpose/", methods=["GET"]) +def transpose(semitones): + k = get_karaoke_instance() + broadcast_event("skip", "transpose current") + k.transpose_current(int(semitones)) + return redirect(url_for("home.home")) + + +@controller_bp.route("/restart") +def restart(): + k = get_karaoke_instance() + broadcast_event("restart") + k.restart() + return redirect(url_for("home.home")) + + +@controller_bp.route("/volume/") +def volume(volume): + k = get_karaoke_instance() + broadcast_event("volume", volume) + k.volume_change(float(volume)) + return redirect(url_for("home.home")) + + +@controller_bp.route("/vol_up") +def vol_up(): + k = get_karaoke_instance() + broadcast_event("volume", "up") + k.vol_up() + return redirect(url_for("home.home")) + + +@controller_bp.route("/vol_down") +def vol_down(): + k = get_karaoke_instance() + broadcast_event("volume", "down") + k.vol_down() + return redirect(url_for("home.home")) + + +@controller_bp.route("/end_song", methods=["GET", "POST"]) +def end_song(): + k = get_karaoke_instance() + d = request.form.to_dict() + reason = d["reason"] if "reason" in d else None + k.end_song(reason) + return "ok" + + +@controller_bp.route("/start_song", methods=["GET"]) +def start_song(): + k = get_karaoke_instance() + k.start_song() + return "ok" diff --git a/pikaraoke/routes/queue.py b/pikaraoke/routes/queue.py index b8337a25..a3856ebb 100644 --- a/pikaraoke/routes/queue.py +++ b/pikaraoke/routes/queue.py @@ -3,7 +3,12 @@ import flask_babel from flask import Blueprint, flash, redirect, render_template, request, url_for -from pikaraoke.lib.current_app import get_karaoke_instance, get_site_name, is_admin +from pikaraoke.lib.current_app import ( + broadcast_event, + get_karaoke_instance, + get_site_name, + is_admin, +) try: from urllib.parse import unquote @@ -55,6 +60,7 @@ def queue_edit(): k.queue_clear() # MSG: Message shown after clearing the queue flash(_("Cleared the queue!"), "is-warning") + broadcast_event("skip", "clear queue") return redirect(url_for("queue.queue")) else: song = request.args["song"] diff --git a/pikaraoke/templates/splash.html b/pikaraoke/templates/splash.html index a58fc12c..3985181a 100644 --- a/pikaraoke/templates/splash.html +++ b/pikaraoke/templates/splash.html @@ -36,11 +36,6 @@ var mouseTimer = null, cursorVisible = true; - var screensaverTimeoutMs = - parseInt('{{ screensaver_timeout }}') * 1000 || 300000; - let screensaverTimeout; //stores the screensaver timer - var isScreensaverEnabled = screensaverTimeoutMs > 0 - var nowPlayingInterval = null; var pollingInterval = 1000; @@ -91,10 +86,6 @@ playBGMusic(true); } - function clearCommand() { - $.get('{{ url_for("clear_command") }}'); - } - function hideVideo() { $("#video-container").hide(); } @@ -106,7 +97,7 @@ isScoreShown = false; } hideVideo(); - $.post('{{ url_for("end_song") }}', {reason: reason}); + $.post('{{ url_for("controller.end_song") }}', {reason: reason}); } function getBackgroundMusicPlayer() { @@ -181,8 +172,10 @@ bgVideoContainer.fadeIn(2000); } } else { - bgVideo.pause(); - bgVideoContainer.fadeOut(2000); + if (isMediaPlaying(bgVideo)) { + bgVideo.pause(); + bgVideoContainer.fadeOut(2000); + } } } } @@ -209,6 +202,39 @@ } } + //handle screensaver idle loop + var idleTime = 0; + var screensaverTimeoutSeconds = parseInt('{{ screensaver_timeout }}') || 0; + if (screensaverTimeoutSeconds > 0) { + setInterval(() => { + let screensaver = document.getElementById('screensaver'); + let video = getVideoPlayer(); + if (isMediaPlaying(video) || cursorVisible) { + idleTime = 0; //reset idle timer on playback and mouse move + } + if (idleTime >= screensaverTimeoutSeconds) { + if (screensaver.style.visibility == 'hidden') { + screensaver.style.visibility = 'visible'; + playBGVideo(false); + startScreensaver(); + } + if (idleTime > screensaverTimeoutSeconds + 36000) { + idleTime = screensaverTimeoutSeconds; //prevent overflow + } + } + else { //stop screensaver + if (screensaver.style.visibility == 'visible') { + screensaver.style.visibility = 'hidden'; + stopScreensaver(); + if (!nowPlaying.up_next && !isMediaPlaying(video)) { + playBGVideo(true); + } + } + } + idleTime++; + }, 1000) + } + function getNowPlaying() { $.get('{{ url_for("nowplaying") }}', function (data) { var obj = JSON.parse(data); @@ -235,6 +261,7 @@ // Handle the Background music depending on the up_next and nowplaying status if (obj.up_next) { + idleTime = 0; // reset idle timer to clear screensaver playBGMusic(false); playBGVideo(false); } else if (!obj.now_playing) { @@ -309,33 +336,8 @@ } } - //handle screensaver - if (isScreensaverEnabled) { - let screensaver = document.getElementById('screensaver'); - if ( - !nowPlaying.up_next && - !isMediaPlaying(video) && - !screensaverTimeout && - !cursorVisible - ) { - screensaverTimeout = setTimeout(function () { - screensaver.style.visibility = 'visible'; - playBGVideo(false); - startScreensaver(); - }, screensaverTimeoutMs); - } else { - if (nowPlaying.up_next || isMediaPlaying(video) || cursorVisible) { - if (screensaver.style.visibility == 'visible') { - screensaver.style.visibility = "hidden"; - stopScreensaver(); - screensaverTimeout = clearTimeout(screensaverTimeout); - if (!nowPlaying.up_next && !isMediaPlaying(video)) { - playBGVideo(true); - } - } - } - } - } + + }); } @@ -376,7 +378,7 @@ video.addEventListener("play", () => { $("#video-container").show(); //Report song start after a slight delay to allow video to load - setTimeout(() => $.get('{{ url_for("start_song") }}'), 1200); + setTimeout(() => $.get('{{ url_for("controller.start_song") }}'), 1200); }); video.addEventListener("ended", () => { endSong("complete", true); @@ -475,16 +477,16 @@ } }); - socket.on('skip', () => { + socket.on('skip', (reason) => { const video = getVideoPlayer(); - if (!isMediaPlaying(video)) { + if (isMediaPlaying(video)) { const currVolume = video.volume; $(video).animate({ volume: 0 }, 1000, () => { video.pause(); video.volume = currVolume; hideVideo(); }); - console.log(`Skip`); + console.log(`Skip: ${reason}`); } });