added the new http player and lf command

This commit is contained in:
tom lot 2021-02-22 00:28:54 +02:00
parent 9b90dd50a7
commit c9cbfdb705
12 changed files with 272 additions and 25 deletions

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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]

View 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

View File

@ -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()