diff --git a/screenstreamer/gui.py b/screenstreamer/gui.py index 747f531..6594789 100644 --- a/screenstreamer/gui.py +++ b/screenstreamer/gui.py @@ -19,6 +19,9 @@ class ScreenStreamerGUI(QtWidgets.QMainWindow): for disp in displays: self.ui.displaySelect.addItem("{} ({}x{})".format(disp['name'], disp['width'], disp['height']), userData=disp) + self.streamer = None + self.receiver = None + def get_displays(self): disp = display.Display() screen = disp.screen() @@ -53,6 +56,13 @@ class ScreenStreamerGUI(QtWidgets.QMainWindow): @QtCore.Slot() def stream_pressed(self): + if self.streamer: + # stream already running -> stopping + self.streamer = None + self.ui.statusbar.showMessage('stream stopped') + self.ui.streamBtn.setText('Stream') + return + displaydata = self.ui.displaySelect.currentData() self.streamer = Streamer( self.format_display(displaydata), @@ -61,15 +71,24 @@ class ScreenStreamerGUI(QtWidgets.QMainWindow): self.ui.sendto.text() ) self.streamer.start() - # TODO: add button to stop and feedback on error + self.ui.streamBtn.setText('Stop Stream') + # TODO: add feedback on error self.ui.statusbar.showMessage('stream started') @QtCore.Slot() def recieve_pressed(self): + if self.receiver: + # stream already running -> stopping + self.receiver = None + self.ui.statusbar.showMessage('recieve stopped') + self.ui.recieveBtn.setText('Recieve') + return + self.receiver = Reciever( self.ui.protocolSelect.currentText().lower(), self.ui.listenAddr.text() ) self.receiver.start() - # TODO: add button to stop and feedback on error - self.ui.statusbar.showMessage('stream started') + self.ui.recieveBtn.setText('Stop Recieve') + # TODO: add feedback on error + self.ui.statusbar.showMessage('recieve started') diff --git a/screenstreamer/reciever.py b/screenstreamer/reciever.py index e89d91a..b605490 100644 --- a/screenstreamer/reciever.py +++ b/screenstreamer/reciever.py @@ -5,6 +5,10 @@ class Reciever: def __init__(self, protocol: str, target: str) -> None: self.protocol = protocol # should be 'tcp' or 'udp' self.target = target + self.proc = None + + def __del__(self) -> None: + self.stop() def start(self): # currently there is no direct ffplay support in the ffmpeg package @@ -12,3 +16,10 @@ class Reciever: addr = self.protocol+ '://' + self.target + '?listen' self.proc = subprocess.Popen(['ffplay', '-fflags', 'nobuffer', '-flags', 'low_delay', '-f', 'mpegts', addr]) + def stop(self): + if self.proc: + self.proc.terminate() + self.proc.wait(1) + self.proc.kill() + self.proc = None + diff --git a/screenstreamer/streamer.py b/screenstreamer/streamer.py index 5254685..3c1abb7 100644 --- a/screenstreamer/streamer.py +++ b/screenstreamer/streamer.py @@ -7,9 +7,21 @@ class Streamer: self.screensize = screensize self.protocol = protocol # should be 'tcp' or 'udp' self.target = target + self.proc = None + + def __del__(self) -> None: + self.stop() def start(self): self.input = ffmpeg.input(self.screendef, f='x11grab', r=60, s=self.screensize) self.output = ffmpeg.output(self.input, self.protocol + '://' + self.target, f='mpegts', vcodec='nvenc_hevc', tune='zerolatency') self.proc = ffmpeg.run_async(self.output) + def stop(self): + if self.proc: + self.proc.terminate() + self.proc.wait(1) + self.proc.kill() + self.proc = None + +