Create a Preference dialog for fonts and audio output devices Turn Preferences and SoundOff into singletons. No matter how many times you request a new one, the same instance is returned. Stop using singals on the parent() to access other instances, such as sound and Preferences.
115 lines
3.5 KiB
Python
115 lines
3.5 KiB
Python
from PyQt6.QtCore import QObject, Qt, QUrl, pyqtSlot
|
|
from PyQt6.QtMultimedia import (
|
|
QAudioDevice,
|
|
QAudioOutput,
|
|
QMediaDevices,
|
|
QMediaPlayer,
|
|
QSoundEffect,
|
|
)
|
|
|
|
# from PyQt6.QtWidgets import QWidget
|
|
|
|
|
|
class SoundOff(QObject):
|
|
_instance = None
|
|
def __new__(cls):
|
|
if cls._instance:
|
|
return cls._instance
|
|
cls._instance = super(SoundOff, cls).__new__(cls)
|
|
return cls._instance
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
#
|
|
# Setup devices
|
|
#
|
|
self.virtualDevice = None
|
|
dev = None
|
|
for output in QMediaDevices.audioOutputs():
|
|
if output.id().data().decode("utf-8") == "virt-input":
|
|
self.virtualDevice = output
|
|
if output.isDefault():
|
|
self.localDevice = output
|
|
|
|
self.alertEffect = QSoundEffect()
|
|
self.alertEffect.setSource(QUrl("qrc:/beep.wav"))
|
|
self.alertEffect.setAudioDevice(self.localDevice)
|
|
self.alertEffect.setVolume(0.25)
|
|
self.alertEffect.setLoopCount(1)
|
|
|
|
self.localPlayer = QMediaPlayer()
|
|
self.localPlayer.setObjectName("localPlayer")
|
|
self.localOutput = QAudioOutput()
|
|
self.localOutput.setDevice(self.localDevice)
|
|
self.localPlayer.setAudioOutput(self.localOutput)
|
|
if self.virtualDevice:
|
|
self.virtualPlayer = QMediaPlayer()
|
|
self.virtualPlayer.setObjectName("virtualPlayer")
|
|
self.virtualOutput = QAudioOutput()
|
|
self.virtualOutput.setDevice(self.virtualDevice)
|
|
self.virtualPlayer.setAudioOutput(self.virtualOutput)
|
|
#
|
|
# Connections
|
|
#
|
|
self.localPlayer.errorOccurred.connect(self.mediaError)
|
|
self.localPlayer.mediaStatusChanged.connect(self.mediaStatus)
|
|
self.localPlayer.playbackStateChanged.connect(self.playbackState)
|
|
if self.virtualDevice:
|
|
self.virtualPlayer.errorOccurred.connect(self.mediaError)
|
|
self.virtualPlayer.mediaStatusChanged.connect(self.mediaStatus)
|
|
self.virtualPlayer.playbackStateChanged.connect(self.playbackState)
|
|
|
|
@pyqtSlot()
|
|
def alert(self):
|
|
self.alertEffect.play()
|
|
return
|
|
|
|
@pyqtSlot(QMediaPlayer.Error, str)
|
|
def mediaError(self, error, string):
|
|
print(error)
|
|
print(str)
|
|
return
|
|
|
|
@pyqtSlot(QMediaPlayer.MediaStatus)
|
|
def mediaStatus(self, status):
|
|
if status == QMediaPlayer.MediaStatus.LoadedMedia:
|
|
self.sender().play()
|
|
return
|
|
|
|
@pyqtSlot(QMediaPlayer.PlaybackState)
|
|
def playbackState(self, state):
|
|
return
|
|
|
|
#
|
|
# Communications slots
|
|
#
|
|
@pyqtSlot()
|
|
def soundAlert(self):
|
|
self.alertEffect.play()
|
|
return
|
|
|
|
@pyqtSlot(str)
|
|
def playSound(self, url):
|
|
src = QUrl(url)
|
|
if not self.localPlayer.audioOutput():
|
|
self.localPlayer.setAudioOutput(self.localOutput)
|
|
self.localPlayer.setSource(src)
|
|
self.localPlayer.setPosition(0)
|
|
if (
|
|
self.localPlayer.mediaStatus()
|
|
== QMediaPlayer.MediaStatus.LoadedMedia
|
|
):
|
|
self.localPlayer.play()
|
|
if not self.virtualDevice:
|
|
return
|
|
self.virtualPlayer.setSource(src)
|
|
self.virtualPlayer.setPosition(0)
|
|
if not self.virtualPlayer.audioOutput():
|
|
self.virtualPlayer.setAudioOutput(self.virtualOutput)
|
|
if (
|
|
self.virtualPlayer.mediaStatus()
|
|
== QMediaPlayer.MediaStatus.LoadedMedia
|
|
):
|
|
self.virtualPlayer.play()
|
|
return
|