From fc54058e7f58774876fd753ebec21253ae47405d Mon Sep 17 00:00:00 2001 From: Matthew Stratford Date: Fri, 23 Oct 2020 21:10:32 +0100 Subject: [PATCH] Basic player --- .gitignore | 4 ++ bapsicle_standalone.py | 98 ++++++++++++++++++++++++++++++++++++++++++ multiplay-flask.py | 90 ++++++++++++++++++++++++++++++++++++++ templates/index.html | 17 ++++++++ 4 files changed, 209 insertions(+) create mode 100644 .gitignore create mode 100644 bapsicle_standalone.py create mode 100644 multiplay-flask.py create mode 100644 templates/index.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0dc99e6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ + +.vscode/ + +__pycache__/ diff --git a/bapsicle_standalone.py b/bapsicle_standalone.py new file mode 100644 index 0000000..e5716c9 --- /dev/null +++ b/bapsicle_standalone.py @@ -0,0 +1,98 @@ +import pygame +import time +import json +from mutagen.mp3 import MP3 + +class bapsicle(): + state = { + "filename": "", + "channel": -1, + "playing": False, + "pos": 0, + "remaining": 0, + "length": 0, + "loop": False + } + + def isPlaying(self): + return bool(pygame.mixer.music.get_busy()) + + def play(self): + + + pygame.mixer.music.play(0) + + def pause(self): + pygame.mixer.music.pause() + + def unpause(self): + pygame.mixer.music.play(0, self.state["pos"]) + + def stop(self): + pygame.mixer.music.stop() + + def seek(self, pos): + if self.isPlaying(): + pygame.mixer.music.play(0, pos) + else: + self.updateState(pos) + + def load(self, filename): + if not self.isPlaying(): + self.state["filename"] = filename + pygame.mixer.music.load(filename) + if ".mp3" in filename: + song = MP3(filename) + self.state["length"] = song.info.length + else: + self.state["length"] = pygame.mixer.Sound(filename).get_length()/1000 + + + + def updateState(self, pos = None): + self.state["playing"] = self.isPlaying() + if (pos): + self.state["pos"] = pos + else: + self.state["pos"] = pygame.mixer.music.get_pos()/1000 + + self.state["remaining"] = self.state["length"] - self.state["pos"] + + def getDetails(self): + res = "RESP:DETAILS: " + json.dumps(self.state) + return res + + + def __init__(self, channel, in_q, out_q): + + self.state["channel"] = channel + + pygame.mixer.init() + + + + + while True: + time.sleep(0.01) + incoming_msg = in_q.get() + self.updateState() + if (not incoming_msg): + continue + if (incoming_msg == 'PLAY'): + self.play() + if (incoming_msg == 'PAUSE'): + self.pause() + if (incoming_msg == 'UNPAUSE'): + self.unpause() + if (incoming_msg == 'STOP'): + self.stop() + if (incoming_msg.startswith("SEEK")): + split = incoming_msg.split(":") + self.seek(float(split[1])) + if (incoming_msg.startswith("LOAD")): + split = incoming_msg.split(":") + self.load(split[1]) + + if (incoming_msg == 'DETAILS'): + out_q.put(self.getDetails()) + diff --git a/multiplay-flask.py b/multiplay-flask.py new file mode 100644 index 0000000..58da8fb --- /dev/null +++ b/multiplay-flask.py @@ -0,0 +1,90 @@ +import multiprocessing +from bapsicle_standalone import bapsicle +from flask import Flask, render_template +import json + +app = Flask(__name__) + +channel_to_q = [] +channel_from_q = [] +channel_p = [] + + + + + + + + +@app.route("/") +def status(): + data = [] + for i in range(3): + data.append(details(i)) + return render_template('index.html', data=data) + + +@app.route("/player//play") +def play(channel): + + channel_to_q[channel].put("PLAY") + + return status() + + +@app.route("/player//pause") +def pause(channel): + + channel_to_q[channel].put("PAUSE") + + return status() + + +@app.route("/player//unpause") +def unPause(channel): + + channel_to_q[channel].put("UNPAUSE") + + return status() + + +@app.route("/player//stop") +def stop(channel): + + channel_to_q[channel].put("STOP") + + return status() + + +@app.route("/player//seek/") +def seek(channel, pos): + + channel_to_q[channel].put("SEEK:" + str(pos)) + + return status() + + +@app.route("/player//details") +def details(channel): + + channel_to_q[channel].put("DETAILS") + while True: + response = channel_from_q[channel].get() + + if response and response.startswith("RESP:DETAILS"): + return json.loads(response.strip("RESP:DETAILS:")) + + +@app.route("/player/all/stop") +def all_stop(): + for channel in channel_to_q: + channel.put("STOP") + status() + +for channel in range(3): + channel_to_q.append(multiprocessing.Queue()) + channel_from_q.append(multiprocessing.Queue()) + channel_to_q[-1].put_nowait("LOAD:test"+str(channel)+".mp3") + channel_p.append(multiprocessing.Process(target=bapsicle, args=(channel, channel_to_q[-1], channel_from_q[-1])).start()) + +app.run(host='0.0.0.0', port=5000, debug=True) diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..510acb4 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,17 @@ + + + BAPSicle + + + + {% if data %} + + {% for player in data %} + {{player}} Play Stop
+ {% endfor %} +
+ {% endif %} + + + +