Merge pull request #128 from Dpeta/only-qsoundeffect
Only use QtMultimedia.QSoundEffect for audio.
This commit is contained in:
commit
dc6b646065
6 changed files with 57 additions and 179 deletions
10
README.md
10
README.md
|
@ -88,8 +88,6 @@ Pesterchum is a Python script. This means that as long as you have Python instal
|
|||
- [PyQt6] (prefered) or [PyQt5] (legacy)
|
||||
- Qt6 only supports maintained 64 bit operating systems, like Windows 10 or later for Windows. ([Qt 6.3 Supported Platforms](https://doc.qt.io/qt-6/supported-platforms.html))
|
||||
- Qt5 supports Windows 7 or later, but is past its EOL for non-commercial use. ([Qt 5.15 Supported Platforms](https://doc.qt.io/qt-6/supported-platforms.html))
|
||||
- (Optional) [pygame-ce] or [pygame] can provide an alternative audio backend for certain systems.
|
||||
- Useful for Linux systems that don't meet the Qt6 requirements, as Qt5 Multimedia has a GStreamer dependency.
|
||||
- (Optional) [certifi] can provide alternative root certificates for TLS certificate validation.
|
||||
- Useful for MacOS, as Python doesn't use the system-provided certificates because of MacOS' outdated SSL library. Also miscellaneous systems without usable root certificates.
|
||||
|
||||
|
@ -102,9 +100,9 @@ Pesterchum is a Python script. This means that as long as you have Python instal
|
|||
- On macOS it's also possible to install (a more recent version of) Python via [Brew](https://brew.sh/).
|
||||
2. Install Pesterchum's dependencies with pip, run: ``python -m pip install -r requirements.txt``
|
||||
- If this fails, try running ``python -m pip install -U pip setuptools wheel`` to update pip, setuptools & wheel and then trying again.
|
||||
- Alternatively, many linux distros also have packages for pyqt and pygame.
|
||||
- Debian: [python3-pyqt6](https://packages.debian.org/testing/python/python3-pyqt6), [python3-pygame](https://packages.debian.org/testing/python/python3-pygame)
|
||||
- Arch: [python-pyqt6](https://archlinux.org/packages/extra/x86_64/python-pyqt6/), [python-pygame](https://archlinux.org/packages/community/x86_64/python-pygame/)
|
||||
- Alternatively, many linux distros also have packages for PyQt6.
|
||||
- Debian: [python3-pyqt6](https://packages.debian.org/testing/python/python3-pyqt6)
|
||||
- Arch: [python-pyqt6](https://archlinux.org/packages/extra/x86_64/python-pyqt6/)
|
||||
3. Download [this repository's source](https://github.com/Dpeta/pesterchum-alt-servers/archive/refs/heads/main.zip), or choose the "Source Code" option on any release, and extract the archive to a folder of your choice.
|
||||
- Alternatively, clone the repository with git.
|
||||
4. Navigate your terminal to the folder you chose with ``cd /folder/you/chose``.
|
||||
|
@ -116,8 +114,6 @@ Pesterchum is a Python script. This means that as long as you have Python instal
|
|||
[pip]: https://pypi.org/project/pip/
|
||||
[PyQt5]: https://pypi.org/project/PyQt5/
|
||||
[PyQt6]: https://pypi.org/project/PyQt6/
|
||||
[pygame]: https://pypi.org/project/pygame/
|
||||
[pygame-ce]: https://pypi.org/project/pygame-ce/
|
||||
[certifi]: https://pypi.org/project/certifi/
|
||||
[GStreamer]: https://gstreamer.freedesktop.org/
|
||||
|
||||
|
|
14
generic.py
14
generic.py
|
@ -160,20 +160,6 @@ class MovingWindow(QtWidgets.QFrame):
|
|||
self.moving = None
|
||||
|
||||
|
||||
class NoneSound:
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def play(self):
|
||||
pass
|
||||
|
||||
def setVolume(self, v):
|
||||
pass
|
||||
|
||||
def set_volume(self, v):
|
||||
pass
|
||||
|
||||
|
||||
class WMButton(QtWidgets.QPushButton):
|
||||
def __init__(self, icon, parent=None):
|
||||
super().__init__(icon, "", parent)
|
||||
|
|
22
menus.py
22
menus.py
|
@ -1567,15 +1567,19 @@ class PesterOptions(QtWidgets.QDialog):
|
|||
self.audioDeviceBox = QtWidgets.QComboBox(self)
|
||||
current_audio_device = self.config.audioDevice()
|
||||
active_index = None
|
||||
try:
|
||||
for i, output in enumerate(QtMultimedia.QMediaDevices.audioOutputs()):
|
||||
self.audioDeviceBox.addItem(f"{output.description()}", output.id())
|
||||
if output.id() == current_audio_device:
|
||||
active_index = i
|
||||
if active_index is not None:
|
||||
self.audioDeviceBox.setCurrentIndex(active_index)
|
||||
except AttributeError:
|
||||
PchumLog.warning("Can't get audio devices, not using PyQt6 QtMultimedia?")
|
||||
if hasattr(QtMultimedia, "QMediaDevices"):
|
||||
# PyQt6
|
||||
try:
|
||||
for i, output in enumerate(QtMultimedia.QMediaDevices.audioOutputs()):
|
||||
self.audioDeviceBox.addItem(f"{output.description()}", output.id())
|
||||
if output.id() == current_audio_device:
|
||||
active_index = i
|
||||
if active_index is not None:
|
||||
self.audioDeviceBox.setCurrentIndex(active_index)
|
||||
except AttributeError:
|
||||
PchumLog.warning(
|
||||
"Can't get audio devices, not using PyQt6 QtMultimedia?"
|
||||
)
|
||||
|
||||
layout_sound = QtWidgets.QVBoxLayout(widget)
|
||||
layout_sound.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
|
||||
|
|
186
pesterchum.py
186
pesterchum.py
|
@ -46,7 +46,6 @@ from generic import (
|
|||
PesterList,
|
||||
CaseInsensitiveDict,
|
||||
MovingWindow,
|
||||
NoneSound,
|
||||
WMButton,
|
||||
)
|
||||
from convo import PesterTabWindow, PesterConvo
|
||||
|
@ -64,11 +63,20 @@ from randomer import RandomHandler, RANDNICK
|
|||
from toast import PesterToastMachine, PesterToast
|
||||
|
||||
try:
|
||||
from PyQt6 import QtCore, QtGui, QtWidgets
|
||||
from PyQt6 import QtCore, QtGui, QtWidgets, QtMultimedia
|
||||
from PyQt6.QtGui import QAction, QActionGroup
|
||||
|
||||
# Give Linux QtMultimedia warning.
|
||||
if ostools.isLinux():
|
||||
print(
|
||||
"QtMultimedia audio is a bit silly/goofy on Linux and relies on an appropriate"
|
||||
" backend being availible."
|
||||
"\nIf it doesn't work, try installing your distro's equivalent"
|
||||
" of the qt6-multimedia-backend/qt6-multimedia/gstreamer packages."
|
||||
)
|
||||
except ImportError:
|
||||
print("PyQt5 fallback (pesterchum.py)")
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets, QtMultimedia
|
||||
from PyQt5.QtWidgets import QAction, QActionGroup
|
||||
|
||||
# Data directory
|
||||
|
@ -142,60 +150,6 @@ BOTNAMES.extend(SERVICES)
|
|||
# Command line arguments
|
||||
_ARGUMENTS = parser.parse_args()
|
||||
|
||||
# Import audio module
|
||||
# Qt6.4's ffmpeg audio backend makes using QtMultimedia on linux less risky
|
||||
try:
|
||||
# PyQt6, QtMultimedia is prefered.
|
||||
from PyQt6 import QtMultimedia
|
||||
|
||||
print("Audio module is PyQt6 QtMultimedia.")
|
||||
except ImportError:
|
||||
if ostools.isWin32() or ostools.isOSX():
|
||||
# PyQt5 QtMultimedia has native backends for MacOS and Windows
|
||||
try:
|
||||
from PyQt5 import QtMultimedia
|
||||
|
||||
print(
|
||||
"Using PyQt5 QtMultimedia as sound module. (fallback, PyQt6 QtMultimedia not availible)"
|
||||
)
|
||||
except ImportError:
|
||||
try:
|
||||
import pygame
|
||||
|
||||
print(
|
||||
"Using pygame as sound module. (fallback, PyQt6 QtMultimedia and PyQt5 QtMultimedia not availible)"
|
||||
)
|
||||
except ImportError:
|
||||
print(
|
||||
"All possible audio modules failed to import."
|
||||
"\nPossible audio modules in order of preference (Windows/MacOS): PyQt6 QtMultimedia > PyQt5 QtMultimedia > pygame"
|
||||
)
|
||||
# Linux or misc.
|
||||
else:
|
||||
# PyQt5 QtMultimedia needs gstreamer on linux, so pygame is prefered.
|
||||
try:
|
||||
import pygame
|
||||
|
||||
print(
|
||||
"Using pygame as sound module. (fallback, PyQt6 QtMultimedia not availible)"
|
||||
)
|
||||
except ImportError:
|
||||
try:
|
||||
from PyQt5 import QtMultimedia
|
||||
|
||||
print(
|
||||
"Using PyQt5 QtMultimedia as sound module. (fallback, PyQt6 QtMultimedia and pygame not availible)"
|
||||
)
|
||||
print(
|
||||
"PyQt5 Multimedia will silently fail without GStreamer with relevant"
|
||||
" plugins on Linux, pygame is prefered when using PyQt5."
|
||||
)
|
||||
except ImportError:
|
||||
print(
|
||||
"All possible audio modules failed to import."
|
||||
"\nLPossible audio modules in order of preference (Linux/Unknown): PyQt6 QtMultimedia > pygame > PyQt5 QtMultimedia"
|
||||
)
|
||||
|
||||
|
||||
class waitingMessageHolder:
|
||||
def __init__(self, mainwindow, **msgfuncs):
|
||||
|
@ -1372,8 +1326,6 @@ class PesterWindow(MovingWindow):
|
|||
self.honk = True
|
||||
self.modes = ""
|
||||
|
||||
self.sound_type = None
|
||||
|
||||
self.randhandler = RandomHandler(self)
|
||||
|
||||
try:
|
||||
|
@ -2202,69 +2154,28 @@ class PesterWindow(MovingWindow):
|
|||
self._setup_sounds()
|
||||
self.setVolume(self.config.volume())
|
||||
|
||||
def _setup_sounds(self, soundclass=None):
|
||||
def _setup_sounds(self):
|
||||
"""Set up the event sounds for later use."""
|
||||
# Set up the sounds we're using.
|
||||
# Define and load sounds
|
||||
try:
|
||||
# Pygame
|
||||
soundclass = pygame.mixer.Sound # pylint: disable=used-before-assignment
|
||||
except (NameError, AttributeError):
|
||||
try:
|
||||
# QtMultimedia
|
||||
soundclass = QtMultimedia.QSoundEffect
|
||||
except (NameError, AttributeError):
|
||||
# death
|
||||
soundclass = NoneSound
|
||||
PchumLog.warning("No sound module loaded?")
|
||||
|
||||
self.sound_type = soundclass
|
||||
|
||||
# These get redefined if sound works
|
||||
self.alarm = NoneSound()
|
||||
self.memosound = NoneSound()
|
||||
self.namesound = NoneSound()
|
||||
self.ceasesound = NoneSound()
|
||||
self.honksound = NoneSound()
|
||||
|
||||
# Use the class we chose to build the sound set.
|
||||
try:
|
||||
if "pygame" in globals():
|
||||
if soundclass == pygame.mixer.Sound:
|
||||
self.alarm = soundclass(self.theme["main/sounds/alertsound"])
|
||||
self.memosound = soundclass(self.theme["main/sounds/memosound"])
|
||||
self.namesound = soundclass("themes/namealarm.wav")
|
||||
self.ceasesound = soundclass(self.theme["main/sounds/ceasesound"])
|
||||
self.honksound = soundclass("themes/honk.wav")
|
||||
if "QtMultimedia" in globals():
|
||||
if soundclass == QtMultimedia.QSoundEffect:
|
||||
self.alarm = soundclass()
|
||||
self.memosound = soundclass()
|
||||
self.namesound = soundclass()
|
||||
self.ceasesound = soundclass()
|
||||
self.honksound = soundclass()
|
||||
|
||||
self.alarm.setSource(
|
||||
QtCore.QUrl.fromLocalFile(self.theme["main/sounds/alertsound"])
|
||||
)
|
||||
self.memosound.setSource(
|
||||
QtCore.QUrl.fromLocalFile(self.theme["main/sounds/memosound"])
|
||||
)
|
||||
self.namesound.setSource(
|
||||
QtCore.QUrl.fromLocalFile("themes/namealarm.wav")
|
||||
)
|
||||
self.ceasesound.setSource(
|
||||
QtCore.QUrl.fromLocalFile(self.theme["main/sounds/ceasesound"])
|
||||
)
|
||||
self.honksound.setSource(
|
||||
QtCore.QUrl.fromLocalFile("themes/honk.wav")
|
||||
)
|
||||
self.alarm = QtMultimedia.QSoundEffect()
|
||||
self.alarm.setSource(
|
||||
QtCore.QUrl.fromLocalFile(self.theme["main/sounds/alertsound"])
|
||||
)
|
||||
self.memosound = QtMultimedia.QSoundEffect()
|
||||
self.memosound.setSource(
|
||||
QtCore.QUrl.fromLocalFile(self.theme["main/sounds/memosound"])
|
||||
)
|
||||
self.namesound = QtMultimedia.QSoundEffect()
|
||||
self.namesound.setSource(QtCore.QUrl.fromLocalFile("themes/namealarm.wav"))
|
||||
self.ceasesound = QtMultimedia.QSoundEffect()
|
||||
self.ceasesound.setSource(
|
||||
QtCore.QUrl.fromLocalFile(self.theme["main/sounds/ceasesound"])
|
||||
)
|
||||
self.honksound = QtMultimedia.QSoundEffect()
|
||||
self.honksound.setSource(QtCore.QUrl.fromLocalFile("themes/honk.wav"))
|
||||
except:
|
||||
PchumLog.exception("Warning: Error loading sounds!")
|
||||
self.alarm = NoneSound()
|
||||
self.memosound = NoneSound()
|
||||
self.namesound = NoneSound()
|
||||
self.ceasesound = NoneSound()
|
||||
self.honksound = NoneSound()
|
||||
|
||||
self.sounds = [
|
||||
self.alarm,
|
||||
|
@ -2282,12 +2193,7 @@ class PesterWindow(MovingWindow):
|
|||
vol = vol_percent / 100.0
|
||||
for sound in self.sounds:
|
||||
try:
|
||||
if "pygame" in globals():
|
||||
if self.sound_type == pygame.mixer.Sound:
|
||||
sound.set_volume(vol)
|
||||
if "QtMultimedia" in globals():
|
||||
if self.sound_type == QtMultimedia.QSoundEffect:
|
||||
sound.setVolume(vol)
|
||||
sound.setVolume(vol)
|
||||
except Exception as err:
|
||||
PchumLog.warning("Couldn't set volume: %s", err)
|
||||
|
||||
|
@ -2298,23 +2204,21 @@ class PesterWindow(MovingWindow):
|
|||
if "QtMultimedia" not in globals():
|
||||
PchumLog.warning("Not using QtMultimedia, can't set audio device.")
|
||||
return
|
||||
for output in QtMultimedia.QMediaDevices.audioOutputs():
|
||||
if device_id == output.id():
|
||||
for sound in self.sounds:
|
||||
sound.setAudioDevice(output)
|
||||
if hasattr(QtMultimedia, "QMediaDevices"):
|
||||
# PyQt6
|
||||
for output in QtMultimedia.QMediaDevices.audioOutputs():
|
||||
if device_id == output.id():
|
||||
for sound in self.sounds:
|
||||
if sound:
|
||||
sound.setAudioDevice(output)
|
||||
|
||||
def canSetVolume(self):
|
||||
"""Returns the state of volume setting capabilities."""
|
||||
# If the volume can be changed by Pesterchum.
|
||||
if self.sound_type is None:
|
||||
# We haven't initialized yet.
|
||||
return False
|
||||
elif self.sound_type == NoneSound:
|
||||
# Sound is dead
|
||||
return False
|
||||
else:
|
||||
# We can set volume
|
||||
return True
|
||||
for sound in self.sounds:
|
||||
if sound:
|
||||
return True
|
||||
return False # All None. . .
|
||||
|
||||
def changeTheme(self, theme):
|
||||
# check theme
|
||||
|
@ -4113,14 +4017,6 @@ class MainProgram(QtCore.QObject):
|
|||
msgbox.setIcon(QtWidgets.QMessageBox.Icon.Critical)
|
||||
msgbox.exec()
|
||||
|
||||
# If we're using pygame for sound we need to init
|
||||
if "pygame" in globals():
|
||||
# we could set the frequency higher but i love how cheesy it sounds
|
||||
try:
|
||||
pygame.mixer.init()
|
||||
except Exception as err:
|
||||
print("Warning: No sound! (pygame error: %s)" % err)
|
||||
|
||||
self.widget = PesterWindow(options, parent=self, app=self.app)
|
||||
# self.widget.show() <== Already called in showLoading()
|
||||
|
||||
|
|
|
@ -9,9 +9,6 @@ import PyInstaller.__main__
|
|||
is_64bit = sys.maxsize > 2**32
|
||||
# is_linux = sys.platform.startswith("linux")
|
||||
exclude_modules = []
|
||||
# if is_linux == False:
|
||||
# print("Not Linux, excluding pygame.")
|
||||
# exclude_modules.append('pygame')
|
||||
add_data = [
|
||||
"quirks;quirks",
|
||||
"smilies;smilies",
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
certifi==2022.12.7
|
||||
pygame-ce
|
||||
PyQt5==5.15.7
|
||||
PyQt5-Qt5==5.15.2
|
||||
PyQt5-sip==12.11.0
|
||||
|
|
Loading…
Reference in a new issue