added the new http player and lf command
This commit is contained in:
parent
9b90dd50a7
commit
c9cbfdb705
@ -128,6 +128,7 @@ COMMANDS_QUEUE = ['queue', 'qa', 'add']
|
||||
COMMANDS_PLAYLIST = ['playlist', 'ql', 'pl']
|
||||
COMMANDS_SELECT = ['select', 'qs']
|
||||
COMMANDS_DELETE = ['delete', 'd', 'qd']
|
||||
COMMANDS_FILE = ['lf']
|
||||
MPC_MIN_VER = "1.6.4"
|
||||
MPC_BE_MIN_VER = "1.5.2.3123"
|
||||
VLC_MIN_VERSION = "2.2.1"
|
||||
|
||||
@ -91,6 +91,7 @@ de = {
|
||||
"commandList-notification/playlist": "\tql - show the current playlist", # TO DO: Translate
|
||||
"commandList-notification/select": "\tqs [index] - select given entry in the playlist", # TO DO: Translate
|
||||
"commandList-notification/delete": "\tqd [index] - delete the given entry from the playlist", # TO DO: Translate
|
||||
"commandList-notification/load": "\tlf [path] - load file",
|
||||
"syncplay-version-notification": "Syncplay Version: {}", # syncplay.version
|
||||
"more-info-notification": "Weitere Informationen auf: {}", # projectURL
|
||||
|
||||
|
||||
@ -91,6 +91,7 @@ en = {
|
||||
"commandList-notification/playlist": "\tql - show the current playlist",
|
||||
"commandList-notification/select": "\tqs [index] - select given entry in the playlist",
|
||||
"commandList-notification/delete": "\tqd [index] - delete the given entry from the playlist",
|
||||
"commandList-notification/load": "\tlf [path] - load file",
|
||||
"syncplay-version-notification": "Syncplay version: {}", # syncplay.version
|
||||
"more-info-notification": "More info available at: {}", # projectURL
|
||||
|
||||
|
||||
@ -91,6 +91,7 @@ es = {
|
||||
"commandList-notification/playlist": "\tql - show the current playlist", # TO DO: Translate
|
||||
"commandList-notification/select": "\tqs [index] - select given entry in the playlist", # TO DO: Translate
|
||||
"commandList-notification/delete": "\tqd [index] - delete the given entry from the playlist", # TO DO: Translate
|
||||
"commandList-notification/load": "\tlf [path] - load file",
|
||||
"syncplay-version-notification": "Versión de Syncplay: {}", # syncplay.version
|
||||
"more-info-notification": "Más información disponible en: {}", # projectURL
|
||||
|
||||
|
||||
@ -91,6 +91,7 @@ it = {
|
||||
"commandList-notification/playlist": "\tql - show the current playlist", # TO DO: Translate
|
||||
"commandList-notification/select": "\tqs [index] - select given entry in the playlist", # TO DO: Translate
|
||||
"commandList-notification/delete": "\tqd [index] - delete the given entry from the playlist", # TO DO: Translate
|
||||
"commandList-notification/load": "\tlf [path] - load file",
|
||||
"syncplay-version-notification": "Versione di Syncplay: {}", # syncplay.version
|
||||
"more-info-notification": "Maggiori informazioni a: {}", # projectURL
|
||||
|
||||
|
||||
@ -91,6 +91,7 @@ pt_BR = {
|
||||
"commandList-notification/playlist": "\tql - show the current playlist", # TO DO: Translate
|
||||
"commandList-notification/select": "\tqs [index] - select given entry in the playlist", # TO DO: Translate
|
||||
"commandList-notification/delete": "\tqd [index] - delete the given entry from the playlist", # TO DO: Translate
|
||||
"commandList-notification/load": "\tlf [path] - load file",
|
||||
"syncplay-version-notification": "Versão do Syncplay: {}", # syncplay.version
|
||||
"more-info-notification": "Mais informações disponíveis em: {}", # projectURL
|
||||
|
||||
|
||||
@ -91,6 +91,7 @@ pt_PT = {
|
||||
"commandList-notification/playlist": "\tql - show the current playlist", # TO DO: Translate
|
||||
"commandList-notification/select": "\tqs [index] - select given entry in the playlist", # TO DO: Translate
|
||||
"commandList-notification/delete": "\tqd [index] - delete the given entry from the playlist", # TO DO: Translate
|
||||
"commandList-notification/load": "\tlf [path] - load file",
|
||||
"syncplay-version-notification": "Versão do Syncplay: {}", # syncplay.version
|
||||
"more-info-notification": "Mais informações disponíveis em: {}", # projectURL
|
||||
|
||||
|
||||
@ -90,6 +90,7 @@ ru = {
|
||||
"commandList-notification/playlist": "\tql - показать текущий список воспроизведения",
|
||||
"commandList-notification/select": "\tqs [индекс] - выделить указанный пункт в списке воспроизведения",
|
||||
"commandList-notification/delete": "\tqd [индекс] - удалить указанный пункт из списка воспроизведения",
|
||||
"commandList-notification/load": "\tlf [path] - load file",
|
||||
"syncplay-version-notification": "Версия Syncplay: {}", # syncplay.version
|
||||
"more-info-notification": "Больше информации на {}", # projectURL
|
||||
|
||||
|
||||
@ -91,6 +91,7 @@ tr = {
|
||||
"commandList-notification/playlist": "\tql - mevcut oynatma listesini gösterir",
|
||||
"commandList-notification/select": "\tqs [index] - oynatma listesinde verilen girişi seçer",
|
||||
"commandList-notification/delete": "\tqd [index] - verilen girişi oynatma listesinden siler",
|
||||
"commandList-notification/load": "\tlf [path] - load file",
|
||||
"syncplay-version-notification": "Syncplay sürümü: {}", # syncplay.version
|
||||
"more-info-notification": "Daha fazla bilgiye şu adresten ulaşabilirsiniz: {}", # projectURL
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@ except ImportError:
|
||||
from syncplay.players.basePlayer import DummyPlayer
|
||||
IinaPlayer = DummyPlayer
|
||||
|
||||
from syncplay.players.httpPlayer import HttpPlayer
|
||||
|
||||
def getAvailablePlayers():
|
||||
return [MPCHCAPIPlayer, MpvPlayer, MpvnetPlayer, VlcPlayer, MpcBePlayer, MplayerPlayer, IinaPlayer]
|
||||
return [MPCHCAPIPlayer, MpvPlayer, MpvnetPlayer, VlcPlayer, MpcBePlayer, MplayerPlayer, IinaPlayer, HttpPlayer]
|
||||
|
||||
201
syncplay/players/httpPlayer.py
Normal file
201
syncplay/players/httpPlayer.py
Normal file
@ -0,0 +1,201 @@
|
||||
from syncplay.players.basePlayer import BasePlayer
|
||||
from syncplay import constants
|
||||
from mutagen.mp3 import MP3
|
||||
from time import time
|
||||
import requests
|
||||
import os
|
||||
|
||||
|
||||
class StreamData():
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
'''
|
||||
@type file_name: string
|
||||
@type position: float
|
||||
@type speed: float
|
||||
@type paused: bool
|
||||
@type address: tuple
|
||||
|
||||
Send formatted data to the given address
|
||||
'''
|
||||
|
||||
def sendto(self, position, speed, paused, address):
|
||||
try:
|
||||
data = {"position": position, "speed": speed,
|
||||
"paused": paused, "time": time()}
|
||||
requests.post(address, json=data)
|
||||
except:
|
||||
print("can't connect to the server right now")
|
||||
|
||||
|
||||
class HttpPlayer(BasePlayer):
|
||||
speedSupported = True
|
||||
customOpenDialog = False
|
||||
chatOSDSupported = False
|
||||
alertOSDSupported = False
|
||||
osdMessageSeparator = ""
|
||||
|
||||
SEND_ADDRESS = "http://127.0.0.1:5000/data"
|
||||
DEFAULT_PATH = "/HttpPlayer"
|
||||
DEFAULT_FILE = "want.mp3"
|
||||
|
||||
def __init__(self, client, playerPath, filePath, args):
|
||||
self._stream = StreamData()
|
||||
self._client = client
|
||||
|
||||
self._filepath = filePath if filePath else self.DEFAULT_FILE # For the audio file
|
||||
self._position = 0.0 # In seconds
|
||||
self._speed = 1.0 # Percentage
|
||||
self._paused = False
|
||||
self._done = False
|
||||
self._last_send = time()
|
||||
|
||||
try:
|
||||
self.openFile(self._filepath)
|
||||
self._client.updateFile(os.path.basename(self._filepath), MP3(
|
||||
self._filepath).info.length, self._filepath)
|
||||
self.setPaused(True)
|
||||
self.setPosition(0.0)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
self._client.initPlayer(self)
|
||||
|
||||
'''
|
||||
Send stream properties to the server through the StreamData object
|
||||
'''
|
||||
|
||||
def streamUpdate(self):
|
||||
self._stream.sendto(self._position, self._speed,
|
||||
self._paused, self.SEND_ADDRESS)
|
||||
|
||||
'''
|
||||
This method is supposed to
|
||||
execute updatePlayerStatus(paused, position) on client
|
||||
Given the arguments: boolean paused and float position in seconds
|
||||
'''
|
||||
|
||||
def askForStatus(self):
|
||||
if not self._client.userlist.currentUser.ready:
|
||||
self._client.toggleReady()
|
||||
if time() - self._last_send >= 5:
|
||||
self._position = self._client.getGlobalPosition()
|
||||
self._paused = self._client.getGlobalPaused()
|
||||
self.streamUpdate()
|
||||
self._last_send = time()
|
||||
|
||||
self._client.updatePlayerStatus(
|
||||
self._client.getGlobalPaused(), self._client.getGlobalPosition())
|
||||
|
||||
'''
|
||||
Display given message on player's OSD or similar means
|
||||
'''
|
||||
|
||||
def displayMessage(
|
||||
self, message, duration=(constants.OSD_DURATION*1000), secondaryOSD=False, mood=constants.MESSAGE_NEUTRAL
|
||||
):
|
||||
pass # Nothing to see here
|
||||
|
||||
'''
|
||||
Cleanup connection with player before syncplay will close down
|
||||
'''
|
||||
|
||||
def drop(self):
|
||||
self._stream.close()
|
||||
self._done = True
|
||||
|
||||
'''
|
||||
Start up the player, returns its instance
|
||||
'''
|
||||
@ staticmethod
|
||||
def run(client, playerPath, filePath, args):
|
||||
return HttpPlayer(client, playerPath, filePath, args)
|
||||
|
||||
'''
|
||||
@type value: boolean
|
||||
'''
|
||||
|
||||
def setPaused(self, value):
|
||||
print(f"set pause {value}")
|
||||
self._paused = value
|
||||
self.streamUpdate()
|
||||
|
||||
'''
|
||||
@type value: list
|
||||
'''
|
||||
|
||||
def setFeatures(self, featureList):
|
||||
pass # Nothing to see here...
|
||||
|
||||
'''
|
||||
@type value: float
|
||||
'''
|
||||
|
||||
def setPosition(self, value):
|
||||
print(f"set position: {value}")
|
||||
self._position = value
|
||||
self.streamUpdate()
|
||||
|
||||
'''
|
||||
@type value: float
|
||||
'''
|
||||
|
||||
def setSpeed(self, value):
|
||||
print(f"set speed {value}")
|
||||
self._speed = value
|
||||
self.streamUpdate()
|
||||
|
||||
'''
|
||||
@type filePath: string
|
||||
'''
|
||||
|
||||
def openFile(self, filePath, resetPosition=False):
|
||||
print(f"open file: {filePath}")
|
||||
self._filepath = filePath
|
||||
self.streamUpdate()
|
||||
|
||||
'''
|
||||
@return: list of strings
|
||||
'''
|
||||
@ staticmethod
|
||||
def getDefaultPlayerPathsList():
|
||||
pass
|
||||
|
||||
'''
|
||||
@type path: string
|
||||
'''
|
||||
@ staticmethod
|
||||
def isValidPlayerPath(path):
|
||||
# Always true because it's really a player
|
||||
return path == HTTPPlayer.DEFAULT_PATH
|
||||
|
||||
'''
|
||||
@type path: string
|
||||
@return: string
|
||||
'''
|
||||
@ staticmethod
|
||||
def getIconPath(path):
|
||||
return None # Nothing to see here
|
||||
|
||||
'''
|
||||
@type path: string
|
||||
@return: string
|
||||
'''
|
||||
@ staticmethod
|
||||
def getExpandedPath(path):
|
||||
return path # Not really a player
|
||||
|
||||
'''
|
||||
@type playerPath: string
|
||||
@type filePath: string
|
||||
@return errorMessage: string
|
||||
|
||||
Checks if the player has any problems with the given player/file path
|
||||
'''
|
||||
@ staticmethod
|
||||
def getPlayerPathErrors(playerPath, filePath):
|
||||
return None # Nothing to see here
|
||||
@ -10,6 +10,7 @@ from syncplay import constants
|
||||
from syncplay import utils
|
||||
from syncplay.messages import getMessage
|
||||
from syncplay.utils import formatTime, isURL
|
||||
from mutagen.mp3 import MP3
|
||||
|
||||
|
||||
class ConsoleUI(threading.Thread):
|
||||
@ -73,17 +74,22 @@ class ConsoleUI(threading.Thread):
|
||||
if user.isReady():
|
||||
userflags += "({}) ".format(getMessage("ready-userlist-userflag"))
|
||||
|
||||
username = userflags + "*<{}>*".format(user.username) if user == currentUser else userflags + "<{}>".format(user.username)
|
||||
username = userflags + \
|
||||
"*<{}>*".format(user.username) if user == currentUser else userflags + \
|
||||
"<{}>".format(user.username)
|
||||
if user.file:
|
||||
message = getMessage("userlist-playing-notification").format(username)
|
||||
message = getMessage(
|
||||
"userlist-playing-notification").format(username)
|
||||
self.showMessage(message, True)
|
||||
message = " {}: '{}' ({})".format(getMessage("userlist-file-notification"), user.file['name'], formatTime(user.file['duration']))
|
||||
message = " {}: '{}' ({})".format(getMessage(
|
||||
"userlist-file-notification"), user.file['name'], formatTime(user.file['duration']))
|
||||
if currentUser.file:
|
||||
if user.file['name'] == currentUser.file['name'] and user.file['size'] != currentUser.file['size']:
|
||||
message += getMessage("different-filesize-notification")
|
||||
self.showMessage(message, True)
|
||||
else:
|
||||
message = getMessage("no-file-played-notification").format(username)
|
||||
message = getMessage(
|
||||
"no-file-played-notification").format(username)
|
||||
self.showMessage(message, True)
|
||||
|
||||
def userListChange(self):
|
||||
@ -107,7 +113,8 @@ class ConsoleUI(threading.Thread):
|
||||
if noTimestamp:
|
||||
print(message)
|
||||
else:
|
||||
print(time.strftime(constants.UI_TIME_FORMAT, time.localtime()) + message)
|
||||
print(time.strftime(constants.UI_TIME_FORMAT,
|
||||
time.localtime()) + message)
|
||||
|
||||
def showDebugMessage(self, message):
|
||||
print(message)
|
||||
@ -136,9 +143,9 @@ class ConsoleUI(threading.Thread):
|
||||
if t is None:
|
||||
return
|
||||
if o.group('sign') == "/":
|
||||
t = self._syncplayClient.getPlayerPosition() - t
|
||||
t = self._syncplayClient.getPlayerPosition() - t
|
||||
elif sign:
|
||||
t = self._syncplayClient.getUserOffset() + sign * t
|
||||
t = self._syncplayClient.getUserOffset() + sign * t
|
||||
self._syncplayClient.setUserOffset(t)
|
||||
return True
|
||||
elif s:
|
||||
@ -158,7 +165,8 @@ class ConsoleUI(threading.Thread):
|
||||
return
|
||||
if command.group('command') in constants.COMMANDS_UNDO:
|
||||
tmp_pos = self._syncplayClient.getPlayerPosition()
|
||||
self._syncplayClient.setPosition(self._syncplayClient.playerPositionBeforeLastSeek)
|
||||
self._syncplayClient.setPosition(
|
||||
self._syncplayClient.playerPositionBeforeLastSeek)
|
||||
self._syncplayClient.playerPositionBeforeLastSeek = tmp_pos
|
||||
elif command.group('command') in constants.COMMANDS_LIST:
|
||||
self.getUserlist()
|
||||
@ -166,7 +174,8 @@ class ConsoleUI(threading.Thread):
|
||||
message = command.group('parameter')
|
||||
self._syncplayClient.sendChat(message)
|
||||
elif command.group('command') in constants.COMMANDS_PAUSE:
|
||||
self._syncplayClient.setPaused(not self._syncplayClient.getPlayerPaused())
|
||||
self._syncplayClient.setPaused(
|
||||
not self._syncplayClient.getPlayerPaused())
|
||||
elif command.group('command') in constants.COMMANDS_ROOM:
|
||||
room = command.group('parameter')
|
||||
if room is None:
|
||||
@ -197,7 +206,8 @@ class ConsoleUI(threading.Thread):
|
||||
self._syncplayClient.ui.addFileToPlaylist(filename)
|
||||
elif command.group('command') in constants.COMMANDS_PLAYLIST:
|
||||
playlist = self._syncplayClient.playlist
|
||||
playlist_elements = ["\t{}: {}".format(i+1, el) for i, el in enumerate(playlist._playlist)]
|
||||
playlist_elements = ["\t{}: {}".format(
|
||||
i+1, el) for i, el in enumerate(playlist._playlist)]
|
||||
|
||||
if playlist_elements:
|
||||
i = playlist._playlistIndex
|
||||
@ -213,41 +223,67 @@ class ConsoleUI(threading.Thread):
|
||||
|
||||
if index < 0 or index >= len(self._syncplayClient.playlist._playlist):
|
||||
raise TypeError("Invalid playlist index")
|
||||
self._syncplayClient.playlist.changeToPlaylistIndex(index, resetPosition=True)
|
||||
self._syncplayClient.playlist.changeToPlaylistIndex(
|
||||
index, resetPosition=True)
|
||||
self._syncplayClient.rewindFile()
|
||||
|
||||
except (TypeError, AttributeError):
|
||||
self.showErrorMessage(getMessage("playlist-invalid-index-error"))
|
||||
self.showErrorMessage(getMessage(
|
||||
"playlist-invalid-index-error"))
|
||||
elif command.group('command') in constants.COMMANDS_DELETE:
|
||||
try:
|
||||
index = int(command.group('parameter').strip()) - 1
|
||||
self._syncplayClient.playlist.deleteAtIndex(index)
|
||||
|
||||
except (TypeError, AttributeError):
|
||||
self.showErrorMessage(getMessage("playlist-invalid-index-error"))
|
||||
|
||||
self.showErrorMessage(getMessage(
|
||||
"playlist-invalid-index-error"))
|
||||
elif command.group('command') in constants.COMMANDS_FILE:
|
||||
try:
|
||||
path = command.group('parameter'.strip())
|
||||
if os.path.exists(path):
|
||||
self.showMessage(f'loading {path}', True)
|
||||
self._syncplayClient.updateFile(
|
||||
os.path.basename(path), MP3(path).info.length, path)
|
||||
self._syncplayClient._player.openFile(path)
|
||||
self.showMessage(f'{path} loaded', True)
|
||||
else:
|
||||
self.showErrorMessage("File doesn't exists")
|
||||
except Exception as e:
|
||||
print(e)
|
||||
else:
|
||||
if self._tryAdvancedCommands(data):
|
||||
return
|
||||
if command.group('command') not in constants.COMMANDS_HELP:
|
||||
self.showMessage(getMessage("unrecognized-command-notification"))
|
||||
self.showMessage(getMessage(
|
||||
"unrecognized-command-notification"))
|
||||
self.showMessage(getMessage("commandlist-notification"), True)
|
||||
self.showMessage(getMessage("commandlist-notification/room"), True)
|
||||
self.showMessage(getMessage("commandlist-notification/list"), True)
|
||||
self.showMessage(getMessage("commandlist-notification/undo"), True)
|
||||
self.showMessage(getMessage("commandlist-notification/pause"), True)
|
||||
self.showMessage(getMessage(
|
||||
"commandlist-notification/pause"), True)
|
||||
self.showMessage(getMessage("commandlist-notification/seek"), True)
|
||||
self.showMessage(getMessage("commandlist-notification/help"), True)
|
||||
self.showMessage(getMessage("commandlist-notification/toggle"), True)
|
||||
self.showMessage(getMessage("commandlist-notification/create"), True)
|
||||
self.showMessage(getMessage(
|
||||
"commandlist-notification/toggle"), True)
|
||||
self.showMessage(getMessage(
|
||||
"commandlist-notification/create"), True)
|
||||
self.showMessage(getMessage("commandlist-notification/auth"), True)
|
||||
self.showMessage(getMessage("commandlist-notification/chat"), True)
|
||||
self.showMessage(getMessage("commandList-notification/queue"), True)
|
||||
self.showMessage(getMessage("commandList-notification/playlist"), True)
|
||||
self.showMessage(getMessage("commandList-notification/select"), True)
|
||||
self.showMessage(getMessage("commandList-notification/delete"), True)
|
||||
self.showMessage(getMessage("syncplay-version-notification").format(syncplay.version), True)
|
||||
self.showMessage(getMessage("more-info-notification").format(syncplay.projectURL), True)
|
||||
self.showMessage(getMessage(
|
||||
"commandList-notification/queue"), True)
|
||||
self.showMessage(getMessage(
|
||||
"commandList-notification/playlist"), True)
|
||||
self.showMessage(getMessage(
|
||||
"commandList-notification/select"), True)
|
||||
self.showMessage(getMessage(
|
||||
"commandList-notification/delete"), True)
|
||||
self.showMessage(getMessage("commandList-notification/load"), True)
|
||||
self.showMessage(getMessage(
|
||||
"syncplay-version-notification").format(syncplay.version), True)
|
||||
self.showMessage(getMessage(
|
||||
"more-info-notification").format(syncplay.projectURL), True)
|
||||
|
||||
def getUserlist(self):
|
||||
self._syncplayClient.getUserList()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user