Audio support and UI tidying

This commit is contained in:
Ezra Taimuty-Loomis 2021-02-17 19:07:47 -05:00
parent 31fe3cc2d8
commit b5a0820ac2
6 changed files with 930 additions and 148 deletions

View File

@ -0,0 +1,64 @@
import vlc
import time
#instance = vlc.Instance("-vvv", "--no-video", "--repeat")
#player = instance.media_player_new()
#media = instance.media_new("rtsp://piscan-arbor:8554/audio", "network-caching=25")
#player.set_media(media)
#player.play()
#while(True):
# time.sleep(1)
class AudioManager:
vlc = None
player = None
media = None
def __init__(self):
self.vlc = vlc.Instance('--no-video', '--repeat', '-v')
def close(self):
if self.player:
self.player.stop()
self.player.release()
self.vlc.release()
def startRtspAudioStream(self, host, port):
print('create media')
self.media = self.vlc.media_new('rtsp://' + host + ':' + port + '/audio', 'network-caching=50')
print('create new player')
self.player = self.media.player_new_from_media()
print('start player')
self.player.play()
def stopRtspAudioStream(self):
print('stopping audio')
if self.player:
self.player.stop()
self.player.release()
self.player = None
self.media.release()
self.media = None
def setAudioVolume(self, level : int):
self.player.audio_set_volume(level)
def setAudioMute(self, mute : bool):
self.player.audio_set_mute(mute)
if __name__ == '__main__':
audio = AudioManager()
audio.startRtspAudioStream("pibox-airglow", "8554")
try:
while(True):
time.sleep(1)
except KeyboardInterrupt:
pass
audio.stopRtspAudioStream()
audio.close()

View File

@ -12,6 +12,7 @@ from threading import Thread
from time import sleep
import audio_manager
import common
import constants
import connect
@ -27,6 +28,7 @@ import google.protobuf.message as proto
class PiScanClient(QWidget, common.AppInterface):
dataReceived = Signal(bytes)
manualDisconnectInitiated = False
def __init__(self, parent=None, address=None, port=None):
super(PiScanClient, self).__init__(parent)
@ -59,6 +61,8 @@ class PiScanClient(QWidget, common.AppInterface):
self.inmsg = messages_pb2.ServerToClient()
self.audio = audio_manager.AudioManager()
def mainWidget(self):
return self.window
@ -72,16 +76,28 @@ class PiScanClient(QWidget, common.AppInterface):
self.setWindowMode(common.WindowMode.DIALOG)
def receive(self):
disconnectMessage = ''
while True:
try:
data = self.sock.recv(2048)
if not data:
disconnectMessage = 'Connection closed by host'
break
self.dataReceived.emit(data)
except ConnectionAbortedError:
if not self.manualDisconnectInitiated:
disconnectMessage = 'Connection aborted'
break
except:
e = sys.exc_info()[0]
self.showConnectDialog(repr(e))
disconnectMessage = 'Unhandled exception: ' + str(e)
break
print("Closing connection")
print("Closing connection. Reason: " + disconnectMessage)
self.audio.stopRtspAudioStream()
self.manualDisconnectInitiated = False
self.showConnectDialog(disconnectMessage)
def handleReceived(self, data):
self.inmsg.ParseFromString(data)
@ -110,18 +126,13 @@ class PiScanClient(QWidget, common.AppInterface):
def closeEvent(self, event):
print('Exiting...')
try:
if self.sock:
self.sock.close()
#self.rcv_thread.join()
except:
pass
self.disconnect()
## AppInterface methods
#def attemptConnection(self, sock):
def completeConnection(self, sock):
def completeConnection(self, sock, host, use_audio, audio_port):
self.sock = sock
self.rcv_thread = Thread(target=self.receive)
self.rcv_thread.start()
@ -141,7 +152,12 @@ class PiScanClient(QWidget, common.AppInterface):
message3 = messages_pb2.ClientToServer()
message3.type = messages_pb2.ClientToServer.Type.Value('GENERAL_REQUEST')
message3.generalRequest.type = request_pb2.GeneralRequest.RequestType.Value('SYSTEM_INFO')
self.sock.send(message3.SerializeToString())
self.sock.send(message3.SerializeToString())
if use_audio:
self.audio.startRtspAudioStream(host, audio_port)
self.setAudioVolume(50)
self.scanner.setVolumeVisible(use_audio)
def scan(self):
message = messages_pb2.ClientToServer()
@ -216,6 +232,21 @@ class PiScanClient(QWidget, common.AppInterface):
else:
self.setWindowTitle('PiScan')
def disconnect(self):
self.manualDisconnectInitiated = True
try:
if self.sock:
self.sock.close()
#self.rcv_thread.join()
except:
pass
def setAudioVolume(self, level):
self.audio.setAudioVolume(level)
def setAudioMute(self, mute):
self.audio.setAudioMute(mute)
class HostWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None, address=None, port=None):
super(HostWindow, self).__init__(parent)

View File

@ -31,7 +31,7 @@ class AppInterface:
#def attemptConnection(self, sock):
# pass
def completeConnection(self, sock):
def completeConnection(self, sock, host, use_audio, audio_port):
pass
def scan(self):
@ -75,3 +75,12 @@ class AppInterface:
def clearWindowTitleInfo(self):
pass
def disconnect(self):
pass
def setAudioVolume(self, level):
pass
def setAudioMute(self, mute):
pass

View File

@ -1,7 +1,7 @@
import sys
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QWidget, QLabel, QPushButton, QLineEdit
from PySide2.QtWidgets import QWidget, QLabel, QPushButton, QLineEdit, QCheckBox
from PySide2.QtCore import QObject
from PySide2.QtGui import QMovie, QPixmap
@ -21,6 +21,9 @@ class ConnectDialog:
self.logo = parentWindow.findChild(QLabel, 'connect_logoImage')
self.hostLabel = parentWindow.findChild(QLabel, 'hostLabel')
self.portLabel = parentWindow.findChild(QLabel, 'hostPortLabel')
self.audioCheckBox = parentWindow.findChild(QCheckBox, 'connect_audioCheckBox')
self.rtspPortPanel = parentWindow.findChild(QWidget, 'connect_rtspPortPanel')
self.rtspPortLineEdit = parentWindow.findChild(QLineEdit, 'connect_rtspPortLineEdit')
self.logo.setPixmap(QPixmap("resources/icon-256.png"))
self.logo.setVisible(False)
@ -39,6 +42,8 @@ class ConnectDialog:
self.hostLineEdit.returnPressed.connect(self.onConfirm)
self.portLineEdit.returnPressed.connect(self.onConfirm)
self.rtspPortPanel.setVisible(False)
def onConfirm(self):
host = self.hostLineEdit.text()
port = int(self.portLineEdit.text())
@ -62,11 +67,19 @@ class ConnectDialog:
self.connectIndicator.setVisible(False)
common.getApp().completeConnection(sock)
use_audio = self.audioCheckBox.isChecked()
audio_port = self.rtspPortLineEdit.text()
common.getApp().completeConnection(sock, address, use_audio, audio_port)
except ConnectionRefusedError:
self.connectFailed('Connect failed - Connection refused')
except gaierror as err:
self.connectFailed('Connect failed - ' + str(err))
except TimeoutError:
self.connectFailed('Connect failed - Timed out')
except:
e = sys.exc_info()[0]
self.connectFailed(repr(e))
self.connectFailed('Connect failed - Unhandled exception: ' + str(e))
def contextWait(self):

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,8 @@ class Scanner:
self.modulationLabel = parentWindow.findChild(QLabel, 'scanner_modulationLabel')
self.systemTagLabel = parentWindow.findChild(QLabel, 'scanner_systemTagLabel')
self.entryNumLabel = parentWindow.findChild(QLabel, 'scanner_entryNumLabel')
self.lockoutCheckbox = parentWindow.findChild(QCheckBox, 'scanner_lockoutCheckbox')
self.lockoutDurationLabel = parentWindow.findChild(QLabel, 'scanner_lockoutDurationLabel')
self.lockoutDurationButton = parentWindow.findChild(QPushButton, 'scanner_lockoutDurationButton')
self.scanIndicator = parentWindow.findChild(QLabel, 'scanner_scanIndicator')
self.gainSlider = parentWindow.findChild(QSlider, 'scanner_gainSlider')
##self.gainLabel = parentWindow.findChild(QLabel, 'scanner_gainLabel')
@ -42,6 +43,16 @@ class Scanner:
self.sidebarToggleButton = parentWindow.findChild(QToolButton, 'scanner_sidebarToggle')
self.sidebarPanel = parentWindow.findChild(QWidget, 'scanner_sidebarPanel')
self.disconnectButton = parentWindow.findChild(QToolButton, 'scanner_disconnectButton')
self.settingsButton = parentWindow.findChild(QToolButton, 'scanner_settingsButton')
self.connectInfoButton = parentWindow.findChild(QToolButton, 'scanner_connectInfoButton')
self.volumeControlPanel = parentWindow.findChild(QWidget, 'scanner_volumeControl')
self.volumeSlider = parentWindow.findChild(QWidget, 'scanner_volumeSlider')
self.muteButton = parentWindow.findChild(QWidget, 'scanner_volumeMute')
self.entryEditButton = parentWindow.findChild(QToolButton, 'scanner_entryEditButton')
self.fnButton1.clicked.connect(self.onFnButton1)
self.fnButton2.clicked.connect(self.onFnButton2)
self.fnButton3.clicked.connect(self.onFnButton3)
@ -50,10 +61,22 @@ class Scanner:
self.squelchSlider.valueChanged.connect(self.onsquelchSlider)
self.sidebarToggleButton.clicked.connect(self.onSidebarToggle)
self.sidebarOpen = True
self.sidebarOpen = False
self.sidebarPanel.setVisible(False)
self.disconnectButton.clicked.connect(self.onDisconnectButton)
self.volumeSlider.valueChanged.connect(self.onVolumeSlider)
self.muteButton.toggled.connect(self.onMuteButton)
#temporary since settins dialog is not yet implemented
self.fnButton4.setEnabled(False)
self.volumeControlPanel.setVisible(False)
self.lockoutDurationButton.setVisible(False)
self.lockoutDurationLabel.setVisible(False)
self.fnButton4.setVisible(False)
self.settingsButton.setVisible(False)
self.connectInfoButton.setVisible(False)
self.entryEditButton.setVisible(False)
movie = QMovie("resources/bar-scan.gif")
movie.start()
@ -178,9 +201,11 @@ class Scanner:
def onSidebarToggle(self):
if self.sidebarOpen:
self.sidebarToggleButton.setText('<')
self.sidebarPanel.setVisible(False)
self.sidebarOpen = False
else:
self.sidebarToggleButton.setText('>')
self.sidebarPanel.setVisible(True)
self.sidebarOpen = True
@ -190,4 +215,17 @@ class Scanner:
def setGainRange(self, minimum, maximum):
self.gainSlider.setMinimum(minimum)
self.gainSlider.setMaximum(maximum)
self.gainSlider.setMaximum(maximum)
def onDisconnectButton(self):
common.getApp().disconnect()
def onVolumeSlider(self, value):
common.getApp().setAudioVolume(value)
def onMuteButton(self, value):
self.volumeSlider.setEnabled(not value)
common.getApp().setAudioMute(value)
def setVolumeVisible(self, visible):
self.volumeControlPanel.setVisible(visible)