Added initial, not yet working code for client and mplayer controller
This commit is contained in:
parent
8db7e1223a
commit
338e36514d
39
syncplay/client.py
Normal file
39
syncplay/client.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#coding:utf8
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
from twisted.internet.protocol import Factory
|
||||||
|
|
||||||
|
from .network_utils import CommandProtocol
|
||||||
|
from .utils import parse_state
|
||||||
|
|
||||||
|
|
||||||
|
class SyncClientProtocol(CommandProtocol):
|
||||||
|
def __init__(self, factory):
|
||||||
|
CommandProtocol.__init__(self)
|
||||||
|
|
||||||
|
self.factory = factory
|
||||||
|
|
||||||
|
def connectionMade(self):
|
||||||
|
self.send_message('iam', self.factory.name)
|
||||||
|
|
||||||
|
def handle_connected_state(self, arg):
|
||||||
|
arg = parse_state(arg)
|
||||||
|
if not arg:
|
||||||
|
self.drop_with_error('Malformed state attributes')
|
||||||
|
return
|
||||||
|
|
||||||
|
paused, position, name = arg
|
||||||
|
|
||||||
|
self.factory.update_state(self, paused, position, name)
|
||||||
|
|
||||||
|
|
||||||
|
states = dict(
|
||||||
|
connected = dict(
|
||||||
|
state = 'handle_connected_state',
|
||||||
|
seek = 'handle_connected_seek',
|
||||||
|
#ping = 'handle_connected_ping',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
initial_state = 'connected'
|
||||||
|
|
||||||
@ -1,5 +1,10 @@
|
|||||||
#coding:utf8
|
#coding:utf8
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
RE_NL_SPLIT = re.compile(r'(?:\r\n|\n|\r)')
|
||||||
|
|
||||||
|
from twisted.internet.protocol import ProcessProtocol
|
||||||
from twisted.protocols.basic import LineReceiver
|
from twisted.protocols.basic import LineReceiver
|
||||||
|
|
||||||
class CommandProtocol(LineReceiver):
|
class CommandProtocol(LineReceiver):
|
||||||
@ -47,3 +52,28 @@ class CommandProtocol(LineReceiver):
|
|||||||
self.send_message('error', error)
|
self.send_message('error', error)
|
||||||
self.drop()
|
self.drop()
|
||||||
|
|
||||||
|
|
||||||
|
def parse_lines(leftovers, data):
|
||||||
|
data = leftovers+data
|
||||||
|
lines = RE_NL.split(data)
|
||||||
|
leftovers = lines.pop(-1)
|
||||||
|
return leftovers, lines
|
||||||
|
|
||||||
|
class LineProcessProtocol(ProcessProtocol)
|
||||||
|
__leftover_out = ''
|
||||||
|
__leftover_err = ''
|
||||||
|
|
||||||
|
def outReceived(self, data):
|
||||||
|
self.__leftover_out, lines = parse_lines(__leftover_out, data)
|
||||||
|
for line in lines:
|
||||||
|
self.outLineReceived(line)
|
||||||
|
|
||||||
|
def errReceived(self, data):
|
||||||
|
self.__leftover_err, lines = parse_lines(__leftover_err, data)
|
||||||
|
for line in lines:
|
||||||
|
self.errLineReceived(line)
|
||||||
|
|
||||||
|
def writeLines(self, *lines):
|
||||||
|
for line in lines:
|
||||||
|
self.transport.write(line+'\n')
|
||||||
|
|
||||||
|
|||||||
0
syncplay/players/__init__.py
Normal file
0
syncplay/players/__init__.py
Normal file
58
syncplay/players/mplayer.py
Normal file
58
syncplay/players/mplayer.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#coding:utf8
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
from twisted.internet import reactor
|
||||||
|
|
||||||
|
from ..network_utils import network_utils
|
||||||
|
|
||||||
|
RE_ANSWER = re.compile('^ANS_([a-zA-Z_])=(.+)$')
|
||||||
|
|
||||||
|
|
||||||
|
class MplayerProtocol(ProcessProtocol):
|
||||||
|
def outLineReceived(self, line):
|
||||||
|
if not line.starts_with('ANS_'):
|
||||||
|
return
|
||||||
|
m = RE_ANSWER.match(line)
|
||||||
|
if not m:
|
||||||
|
return
|
||||||
|
|
||||||
|
name, value = m.group(1).lower, m.group(2)
|
||||||
|
handler = getattr(self, 'answer_' + name, None)
|
||||||
|
if handler:
|
||||||
|
handler(value)
|
||||||
|
|
||||||
|
|
||||||
|
def send_set_paused(self, value):
|
||||||
|
# docs say i can't set "pause" property, but it works...
|
||||||
|
self.set_property('paused', 'yes' if value else 'no')
|
||||||
|
|
||||||
|
def send_get_paused(self):
|
||||||
|
self.get_property('paused')
|
||||||
|
|
||||||
|
def answer_pause(self, value):
|
||||||
|
value = value == 'yes'
|
||||||
|
|
||||||
|
|
||||||
|
def send_set_position(self, value):
|
||||||
|
self.set_property('time_pos', '%0.2f'%value)
|
||||||
|
|
||||||
|
def send_get_position(self):
|
||||||
|
self.get_property('time_pos')
|
||||||
|
|
||||||
|
def answer_time_pos(self, value):
|
||||||
|
value = float(value)
|
||||||
|
|
||||||
|
|
||||||
|
def send_set_speed(self, value):
|
||||||
|
self.set_property('speed', '%0.2f'%value)
|
||||||
|
|
||||||
|
def send_get_speed(self):
|
||||||
|
self.get_property('speed')
|
||||||
|
|
||||||
|
def answer_speed(self, value):
|
||||||
|
value = float(value)
|
||||||
|
|
||||||
|
|
||||||
|
def run_mplayer(manager, mplayer_path, args):
|
||||||
|
pass
|
||||||
@ -5,6 +5,8 @@ import time
|
|||||||
from twisted.internet.protocol import Factory
|
from twisted.internet.protocol import Factory
|
||||||
|
|
||||||
from .network_utils import CommandProtocol
|
from .network_utils import CommandProtocol
|
||||||
|
from .utils import parse_state
|
||||||
|
|
||||||
|
|
||||||
class SyncServerProtocol(CommandProtocol):
|
class SyncServerProtocol(CommandProtocol):
|
||||||
def __init__(self, factory):
|
def __init__(self, factory):
|
||||||
@ -20,24 +22,12 @@ class SyncServerProtocol(CommandProtocol):
|
|||||||
self.change_state('connected')
|
self.change_state('connected')
|
||||||
|
|
||||||
def handle_connected_state(self, arg):
|
def handle_connected_state(self, arg):
|
||||||
arg = arg.split(None, 1)
|
arg = parse_state(arg)
|
||||||
if len(arg) != 2:
|
if not arg:
|
||||||
self.drop_with_error('Malformed state attributes')
|
self.drop_with_error('Malformed state attributes')
|
||||||
return
|
return
|
||||||
state, position = arg
|
|
||||||
|
|
||||||
if not state in ('paused', 'playing'):
|
paused, position, _ = arg
|
||||||
self.drop_with_error('Unknown state')
|
|
||||||
return
|
|
||||||
|
|
||||||
paused = state == 'paused'
|
|
||||||
|
|
||||||
try:
|
|
||||||
position = int(position)
|
|
||||||
except ValueError:
|
|
||||||
self.drop_with_error('Invalid position numeral')
|
|
||||||
|
|
||||||
position /= 100.0
|
|
||||||
|
|
||||||
self.factory.update_state(self, paused, position)
|
self.factory.update_state(self, paused, position)
|
||||||
|
|
||||||
|
|||||||
31
syncplay/utils.py
Normal file
31
syncplay/utils.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#coding:utf8
|
||||||
|
|
||||||
|
def split_args(args, number):
|
||||||
|
# FIXME Make argument format smarter
|
||||||
|
return args.split(None, number-1)
|
||||||
|
|
||||||
|
def parse_state(args):
|
||||||
|
args = split_args(args, 3)
|
||||||
|
l = len(args)
|
||||||
|
if l == 2:
|
||||||
|
state, position = args
|
||||||
|
who_changed_state = None
|
||||||
|
elif l == 3:
|
||||||
|
state, position, who_changed_state = args
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not state in ('paused', 'playing'):
|
||||||
|
return
|
||||||
|
|
||||||
|
paused = state == 'paused'
|
||||||
|
|
||||||
|
try:
|
||||||
|
position = int(position)
|
||||||
|
except ValueError:
|
||||||
|
return
|
||||||
|
|
||||||
|
position /= 100.0
|
||||||
|
|
||||||
|
return paused, position, who_changed_state
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user