Commit 29a3bb96 authored by Jonas Jelten's avatar Jonas Jelten

use asyncio to handle multiple connections

fixes #4
parent f4921934
......@@ -2,49 +2,13 @@
The video screen.
"""
import socket
import asyncio
import subprocess
from threading import Thread
MPV_INVOCATION = ["mpv"]
class Player(Thread):
"""
Player wrapper to detect its termination.
"""
def __init__(self, cmd, start_hook=None, stop_hook=None):
super().__init__()
self.cmd = cmd
self.proc = None
self.start_hook = start_hook
self.stop_hook = stop_hook
def run(self):
if self.start_hook:
self.start_hook()
from .player import Player
from .urlreceiver import UrlReceiver
print("exec: %s" % self.cmd)
self.proc = subprocess.Popen(self.cmd)
self.proc.wait()
if self.stop_hook:
self.stop_hook()
def kill(self):
""" kill the contained process """
if self.proc:
try:
self.proc.wait(timeout=0.1)
return
except subprocess.TimeoutExpired:
self.proc.kill()
try:
self.proc.wait(timeout=0.5)
except subprocess.TimeoutExpired:
raise Exception("process doesn't die :(")
MPV_INVOCATION = ["mpv"]
class VideoScreen:
......@@ -63,10 +27,13 @@ class VideoScreen:
self.sock = None
def display(self, data):
""" show a new video and kill the old one """
def display(self, sender, data):
"""
show a new video and kill the old one
TODO: player selection e.g. for jpgs
"""
print(" showing '%s'" % data)
print("%s showing '%s'" % (sender, data))
# kill the existing mpv:
if self.mpv is not None:
......@@ -92,25 +59,18 @@ class VideoScreen:
def launch(self):
""" run the videoscreen """
print("launching on %s:%d" % (self.address, self.port))
self.sock = socket.socket()
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind((self.address, self.port))
self.sock.listen(1)
print("launching on %s:%d..." % (self.address, self.port))
while True:
(conn, addr) = self.sock.accept()
print("new link from '%s'" % (addr,))
loop = asyncio.get_event_loop()
coro = loop.create_server(lambda: UrlReceiver(self),
self.address, self.port)
server = loop.run_until_complete(coro)
buf = bytearray()
try:
loop.run_forever()
except KeyboardInterrupt:
pass
while True:
buf += conn.recv(2048)
npos = buf.find(b"\n")
if npos != -1:
data = buf[:npos]
self.display(data.decode())
conn.close()
break
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()
"""
Contains the a media player
"""
import subprocess
from threading import Thread
class Player(Thread):
"""
Player wrapper to detect its termination.
"""
def __init__(self, cmd, start_hook=None, stop_hook=None):
super().__init__()
self.cmd = cmd
self.proc = None
self.start_hook = start_hook
self.stop_hook = stop_hook
def run(self):
if self.start_hook:
self.start_hook()
self.proc = subprocess.Popen(self.cmd)
self.proc.wait()
if self.stop_hook:
self.stop_hook()
def kill(self):
""" kill the contained process """
if self.proc:
try:
self.proc.wait(timeout=0.1)
return
except subprocess.TimeoutExpired:
self.proc.kill()
try:
self.proc.wait(timeout=0.5)
except subprocess.TimeoutExpired:
raise Exception("process doesn't die :(")
"""
protocol definition for data reception
"""
import asyncio
class UrlReceiver(asyncio.Protocol):
"""
protocol for receiving the media url
"""
def __init__(self, screen):
self.buf = bytearray()
self.screen = screen
self.transport = None
self.peername = None
def connection_made(self, transport):
self.peername = transport.get_extra_info('peername')
self.transport = transport
def data_received(self, data):
self.buf += data
# a url is \n-terminated
npos = self.buf.find(b"\n")
if npos != -1:
data = self.buf[:npos]
self.screen.display(self.peername, data.decode())
self.transport.write(b"yay!\n")
self.transport.close()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment