1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-12-22 08:56:17 +00:00

Skipping within tracks

This commit is contained in:
Alban Féron 2019-09-08 15:41:20 +02:00
parent ee2efec59a
commit 3b5885dde4
No known key found for this signature in database
GPG Key ID: 8CE0313646D16165
3 changed files with 56 additions and 40 deletions

View File

@ -44,36 +44,36 @@ def jukebox_control():
): ):
raise GenericError("Unknown action") raise GenericError("Unknown action")
arg = None args = ()
if action == "set": if action == "set":
if not id: if id:
arg = [] args = [uuid.UUID(i) for i in id]
else:
arg = [uuid.UUID(i) for i in id]
elif action == "skip": elif action == "skip":
if not index: if not index:
raise MissingParameter("index") raise MissingParameter("index")
if offset:
args = (int(index), int(offset))
else: else:
arg = int(index) args = (int(index), 0)
elif action == "add": elif action == "add":
if not id: if not id:
raise MissingParameter("id") raise MissingParameter("id")
else: else:
arg = [uuid.UUID(i) for i in id] args = [uuid.UUID(i) for i in id]
elif action == "remove": elif action == "remove":
if not index: if not index:
raise MissingParameter("index") raise MissingParameter("index")
else: else:
arg = int(index) args = (int(index),)
elif action == "setGain": elif action == "setGain":
if not gain: if not gain:
raise MissingParameter("gain") raise MissingParameter("gain")
else: else:
arg = float(gain) args = (float(gain),)
try: try:
status = DaemonClient(current_app.config["DAEMON"]["socket"]).jukebox_control( status = DaemonClient(current_app.config["DAEMON"]["socket"]).jukebox_control(
action, arg action, *args
) )
except DaemonUnavailableError: except DaemonUnavailableError:
raise GenericError("Jukebox unavaliable") raise GenericError("Jukebox unavaliable")

View File

@ -60,9 +60,9 @@ class ScannerStartCommand(ScannerCommand):
class JukeboxCommand(DaemonCommand): class JukeboxCommand(DaemonCommand):
def __init__(self, action, arg): def __init__(self, action, args):
self.__action = action self.__action = action
self.__arg = arg self.__args = args
def apply(self, connection, daemon): def apply(self, connection, daemon):
if daemon.jukebox is None: if daemon.jukebox is None:
@ -74,24 +74,29 @@ class JukeboxCommand(DaemonCommand):
playlist = daemon.jukebox.playlist playlist = daemon.jukebox.playlist
elif self.__action == "status": elif self.__action == "status":
pass pass
elif self.__action == "set": else:
daemon.jukebox.set(self.__arg) func = None
elif self.__action == "start":
daemon.jukebox.start() if self.__action == "set":
elif self.__action == "stop": func = daemon.jukebox.set
daemon.jukebox.stop() elif self.__action == "start":
elif self.__action == "skip": func = daemon.jukebox.start
daemon.jukebox.skip(self.__arg) elif self.__action == "stop":
elif self.__action == "add": func = daemon.jukebox.stop
daemon.jukebox.add(self.__arg) elif self.__action == "skip":
elif self.__action == "clear": func = daemon.jukebox.skip
daemon.jukebox.clear() elif self.__action == "add":
elif self.__action == "remove": func = daemon.jukebox.add
daemon.jukebox.remove(self.__arg) elif self.__action == "clear":
elif self.__action == "shuffle": func = daemon.jukebox.clear
daemon.jukebox.shuffle() elif self.__action == "remove":
elif self.__action == "setGain": func = daemon.jukebox.remove
daemon.jukebox.setgain(self.__arg) elif self.__action == "shuffle":
func = daemon.jukebox.shuffle
elif self.__action == "setGain":
func = daemon.jukebox.setgain
func(*self.__args)
rv = JukeboxResult(daemon.jukebox) rv = JukeboxResult(daemon.jukebox)
rv.playlist = playlist rv.playlist = playlist
@ -162,9 +167,9 @@ class DaemonClient(object):
with self.__get_connection() as c: with self.__get_connection() as c:
c.send(ScannerStartCommand(folders, force)) c.send(ScannerStartCommand(folders, force))
def jukebox_control(self, action, arg): def jukebox_control(self, action, *args):
if not isinstance(action, strtype): if not isinstance(action, strtype):
raise TypeError("Expecting string, got " + str(type(action))) raise TypeError("Expecting string, got " + str(type(action)))
with self.__get_connection() as c: with self.__get_connection() as c:
c.send(JukeboxCommand(action, arg)) c.send(JukeboxCommand(action, args))
return c.recv() return c.recv()

View File

@ -12,7 +12,7 @@ import os
import shlex import shlex
import time import time
from datetime import datetime from datetime import datetime, timedelta
from pony.orm import db_session, ObjectNotFound from pony.orm import db_session, ObjectNotFound
from random import shuffle from random import shuffle
from subprocess import Popen from subprocess import Popen
@ -28,6 +28,7 @@ class Jukebox(object):
self.__cmd = shlex.split(cmd) self.__cmd = shlex.split(cmd)
self.__playlist = [] self.__playlist = []
self.__index = 0 self.__index = 0
self.__offset = 0
self.__start = None self.__start = None
self.__devnull = None self.__devnull = None
@ -62,9 +63,9 @@ class Jukebox(object):
os.close(self.__devnull) os.close(self.__devnull)
self.__devnull = None self.__devnull = None
def set(self, tracks): def set(self, *tracks):
self.clear() self.clear()
self.add(tracks) self.add(*tracks)
def start(self): def start(self):
if self.playing or not self.__playlist: if self.playing or not self.__playlist:
@ -72,6 +73,7 @@ class Jukebox(object):
self.__skip.clear() self.__skip.clear()
self.__stop.clear() self.__stop.clear()
self.__offset = 0
self.__thread = Thread(target=self.__play_thread) self.__thread = Thread(target=self.__play_thread)
self.__thread.start() self.__thread.start()
@ -81,17 +83,20 @@ class Jukebox(object):
self.__stop.set() self.__stop.set()
def skip(self, index): def skip(self, index, offset):
if index < 0 or index >= len(self.__playlist): if index < 0 or index >= len(self.__playlist):
raise IndexError() raise IndexError()
if offset < 0:
raise ValueError()
with self.__lock: with self.__lock:
self.__index = index self.__index = index
self.__start = None self.__offset = offset
self.__start = datetime.utcnow() - timedelta(seconds=offset)
self.__skip.set() self.__skip.set()
self.start() self.start()
def add(self, tracks): def add(self, *tracks):
with self.__lock: with self.__lock:
with db_session: with db_session:
for t in tracks: for t in tracks:
@ -104,6 +109,7 @@ class Jukebox(object):
with self.__lock: with self.__lock:
self.__playlist.clear() self.__playlist.clear()
self.__index = 0 self.__index = 0
self.__offset = 0
def remove(self, index): def remove(self, index):
try: try:
@ -156,11 +162,16 @@ class Jukebox(object):
def __play_file(self): def __play_file(self):
path = self.__playlist[self.__index] path = self.__playlist[self.__index]
args = [a.replace("%path", path) for a in self.__cmd] args = [
a.replace("%path", path).replace("%offset", str(self.__offset))
for a in self.__cmd
]
self.__start = datetime.utcnow() - timedelta(seconds=self.__offset)
self.__offset = 0
logger.debug("Start playing with command %s", args) logger.debug("Start playing with command %s", args)
try: try:
self.__start = datetime.utcnow()
return Popen( return Popen(
args, args,
stdin=self._get_devnull(), stdin=self._get_devnull(),