158 lines
4.9 KiB
Python
158 lines
4.9 KiB
Python
from operator import indexOf
|
|
from PySide6 import QtCore, QtWidgets
|
|
from generated.mainwindow import Ui_ScreenStreamer
|
|
from streamer import Streamer
|
|
from reciever import Reciever
|
|
from pulse import Pulse
|
|
from Xlib import display
|
|
from Xlib.ext import randr
|
|
|
|
class ScreenStreamerGUI(QtWidgets.QMainWindow):
|
|
|
|
def __init__(self, parent = None) -> None:
|
|
QtWidgets.QMainWindow.__init__(self, parent)
|
|
|
|
self.ui = Ui_ScreenStreamer()
|
|
self.ui.setupUi(self)
|
|
|
|
displays = self.get_displays()
|
|
print(displays)
|
|
|
|
for disp in displays:
|
|
self.ui.displaySelect.addItem("{} ({}x{})".format(disp['name'], disp['width'], disp['height']), userData=disp)
|
|
|
|
audiodevices = Pulse.get_audio_inputs()
|
|
print(audiodevices)
|
|
|
|
self.ui.audioSource.addItem('No Audio', userData=-1) # always add this option
|
|
|
|
for audio in audiodevices:
|
|
text = audio['description'] if audio['description'] else audio['name']
|
|
if audio.get('monitor', False):
|
|
text += ' (Monitor)'
|
|
|
|
self.ui.audioSource.addItem(text, userData=audio['id'])
|
|
|
|
if audio.get('isdefault', False):
|
|
self.ui.audioSource.setCurrentIndex(indexOf(audiodevices, audio))
|
|
|
|
self.streamer = None
|
|
self.receiver = None
|
|
|
|
def get_displays(self):
|
|
disp = display.Display()
|
|
screen = disp.screen()
|
|
window = screen.root
|
|
res = randr.get_screen_resources(window)
|
|
|
|
result = list()
|
|
allwidth = 0
|
|
allheight = 0
|
|
for output in res.outputs:
|
|
params = disp.xrandr_get_output_info(output, res.config_timestamp)
|
|
|
|
if not params.crtc:
|
|
continue # non connected display ports
|
|
|
|
crtc = disp.xrandr_get_crtc_info(params.crtc, res.config_timestamp)
|
|
result.append({'name': params.name , 'width': crtc.width, 'height': crtc.height, 'x': crtc.x, 'y': crtc.y})
|
|
|
|
if crtc.width + crtc.x > allwidth:
|
|
allwidth = crtc.width + crtc.x
|
|
if crtc.height + crtc.y > allheight:
|
|
allheight = crtc.height + crtc.y
|
|
|
|
result.append({'name': 'All', 'width': allwidth, 'height': allheight, 'x': 0, 'y': 0})
|
|
return result
|
|
|
|
def format_display(self, displayinfo):
|
|
return ":0.0+{},{}".format(displayinfo['x'], displayinfo['y'])
|
|
|
|
def format_screensize(self, displayinfo):
|
|
return "{}:{}".format(displayinfo['width'], displayinfo['height'])
|
|
|
|
@QtCore.Slot()
|
|
def stream_pressed(self):
|
|
if self.streamer:
|
|
# stream already running -> stopping
|
|
self.streamer.stop()
|
|
self.ui.streamBtn.setEnabled(False)
|
|
return
|
|
|
|
displaydata = self.ui.displaySelect.currentData()
|
|
self.streamer = Streamer(
|
|
self.format_display(displaydata),
|
|
self.format_screensize(displaydata),
|
|
self.ui.videoCodec.currentText(),
|
|
self.ui.audioSource.currentData(),
|
|
self.ui.protocolSelect.currentText().lower(),
|
|
"{}:{}".format(self.ui.sendto.text(), self.ui.streamPort.value())
|
|
)
|
|
self.streamer.process_manager.process_terminated.connect(self.stream_terminated)
|
|
self.streamer.start()
|
|
self.set_stream_status(True)
|
|
self.ui.statusbar.showMessage('stream started')
|
|
|
|
@QtCore.Slot()
|
|
def recieve_pressed(self):
|
|
if self.receiver:
|
|
# recieve already running -> stopping
|
|
self.receiver.stop()
|
|
self.ui.recieveBtn.setEnabled(False)
|
|
return
|
|
|
|
self.receiver = Reciever(
|
|
self.ui.protocolSelect.currentText().lower(),
|
|
"{}:{}".format(self.ui.listenAddr.text(), self.ui.listenPort.value()),
|
|
self.ui.disableAudio.checkState() == 'Checked'
|
|
)
|
|
self.receiver.process_manager.process_terminated.connect(self.recieve_terminated)
|
|
self.receiver.start()
|
|
self.set_recieve_status(True)
|
|
self.ui.statusbar.showMessage('recieve started')
|
|
|
|
def set_recieve_status(self, status: bool):
|
|
"""status = True - stream is running"""
|
|
self.ui.recieveBtn.setEnabled(True)
|
|
self.ui.listenAddr.setEnabled(not status)
|
|
self.ui.listenPort.setEnabled(not status)
|
|
self.ui.disableAudio.setEnabled(not status)
|
|
if status:
|
|
self.ui.recieveBtn.setText('Stop Recieve')
|
|
else:
|
|
self.ui.recieveBtn.setText('Recieve')
|
|
|
|
def set_stream_status(self, status: bool):
|
|
"""status = True - stream is running"""
|
|
self.ui.streamBtn.setEnabled(True)
|
|
self.ui.displaySelect.setEnabled(not status)
|
|
self.ui.videoCodec.setEnabled(not status)
|
|
self.ui.audioSource.setEnabled(not status)
|
|
self.ui.sendto.setEnabled(not status)
|
|
self.ui.streamPort.setEnabled(not status)
|
|
if status:
|
|
self.ui.streamBtn.setText('Stop Stream')
|
|
else:
|
|
self.ui.streamBtn.setText('Stream')
|
|
|
|
def show_error(self, tag: str, returncode: int, errormsg: str):
|
|
if errormsg:
|
|
error = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, tag + ' Error', tag + ' Error: ' + errormsg, QtWidgets.QMessageBox.Ok, self)
|
|
error.show()
|
|
error.exec()
|
|
|
|
@QtCore.Slot(int, str)
|
|
def recieve_terminated(self, returncode, errormsg):
|
|
self.receiver = None
|
|
self.ui.statusbar.showMessage('recieve stopped')
|
|
self.show_error('Recieve', returncode, errormsg)
|
|
self.set_recieve_status(False)
|
|
|
|
@QtCore.Slot(int, str)
|
|
def stream_terminated(self, returncode, errormsg):
|
|
self.streamer = None
|
|
self.ui.statusbar.showMessage('stream stopped')
|
|
self.show_error('Stream', returncode, errormsg)
|
|
self.set_stream_status(False)
|
|
|