From 92c49140e7ec9bf3c0c9da8a8916056e8c594e00 Mon Sep 17 00:00:00 2001 From: miruka Date: Mon, 1 Mar 2021 00:00:04 -0400 Subject: [PATCH] Play sound from python/ALSA instead QtMultimedia GStreamer sucks --- docs/INSTALL.md | 20 ++++++++------------ packaging/appimage/build.sh | 4 ++-- requirements.txt | 1 + src/backend/backend.py | 19 +++++++++++++++++++ src/config/settings.py | 5 +---- src/gui/PythonBridge/EventHandlers.qml | 9 ++------- src/gui/UI.qml | 13 ------------- 7 files changed, 33 insertions(+), 38 deletions(-) diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 0aae452a..b12b6832 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -202,8 +202,7 @@ export CFLAGS="-march=native -O2 -pipe" ```sh sudo apk add qt5-qtquickcontrols2-dev qt5-qtsvg-dev qt5-qtimageformats \ - qt5-qtmultimedia-dev \ - libx11-dev libxscrnsaver-dev \ + libx11-dev libxscrnsaver-dev alsa-lib-dev \ python3-dev py3-setuptools \ build-base git cmake \ libjpeg-turbo-dev zlib-dev tiff-dev libwebp-dev openjpeg-dev \ @@ -221,8 +220,8 @@ Alternatively, you can just use `pacman` and ```sh yay -Syu qt5-base qt5-declarative qt5-quickcontrols2 qt5-svg \ - qt5-graphicaleffects qt5-imageformats qt5-multimedia \ - libx11 libxss \ + qt5-graphicaleffects qt5-imageformats \ + libx11 libxss alsa-lib \ python python-pip \ python-pyotherside \ libolm \ @@ -237,9 +236,8 @@ sudo dnf groupinstall 'Development Tools' sudo dnf install qt5-devel qt5-qtbase-devel qt5-qtdeclarative-devel \ qt5-qtquickcontrols2-devel qt5-qtsvg-devel \ qt5-qtgraphicaleffects qt5-qtimageformats \ - qt5-qtmultimedia-devel \ python3-devel python3-pip pyotherside \ - libX11-devel libXScrnSaver-devel \ + libX11-devel libXScrnSaver-devel alsa-lib-devel \ git cmake \ libolm-devel \ libjpeg-turbo-devel zlib-devel libtiff-devel libwebp-devel \ @@ -257,8 +255,8 @@ if `emerge` says so. ```sh sudo emerge -av qtcore qtdeclarative qtquickcontrols2 \ - qtsvg qtgraphicaleffects qtimageformats qtmultimedia \ - libX11 libXScrnSaver \ + qtsvg qtgraphicaleffects qtimageformats \ + libX11 libXScrnSaver alsa-lib \ dev-python/pip pyotherside \ dev-vcs/git cmake \ libjpeg-turbo zlib tiff libwebp openjpeg libmediainfo @@ -276,10 +274,9 @@ sudo apt install qt5-default qt5-qmake qt5-image-formats-plugins \ qml-module-qtquick-layouts qml-module-qtquick-dialogs \ qml-module-qt-labs-platform \ qml-module-qtquick-shapes \ - qml-module-qtmultimedia \ qtdeclarative5-dev \ qtquickcontrols2-5-dev \ - libx11-dev libxss-dev \ + libx11-dev libxss-dev libasound2-dev \ python3-dev python3-pip \ qml-module-io-thp-pyotherside \ build-essential git cmake \ @@ -304,8 +301,7 @@ sudo apt install libolm-dev sudo xbps-install -Su qt5-devel qt5-declarative-devel \ qt5-quickcontrols2-devel \ qt5-svg-devel qt5-graphicaleffects qt5-imageformats \ - qt5-multimedia-devel \ - libx11-devel libXScrnSaver-devel \ + libx11-devel libXScrnSaver-devel alsa-lib-devel \ python3-devel python3-pip \ olm-devel \ base-devel git cmake \ diff --git a/packaging/appimage/build.sh b/packaging/appimage/build.sh index 2ebf2720..e974f06e 100755 --- a/packaging/appimage/build.sh +++ b/packaging/appimage/build.sh @@ -39,7 +39,7 @@ install_apt_packages() { apt install -y \ qt512base qt512declarative qt512graphicaleffects \ - qt512imageformats qt512quickcontrols2 qt512svg qt512multimedia \ + qt512imageformats qt512quickcontrols2 qt512svg \ zip git wget cmake ccache \ build-essential mesa-common-dev libglu1-mesa-dev freeglut3-dev \ libglfw3-dev libgles2-mesa-dev libssl-dev \ @@ -47,7 +47,7 @@ install_apt_packages() { libsqlite3-dev libffi-dev openssl libreadline-dev \ libjpeg-turbo8-dev zlib1g-dev \ libtiff5-dev liblcms2-dev libwebp-dev libopenjp2-7-dev \ - libx11-dev libxss-dev \ + libx11-dev libxss-dev libasound2-dev \ pkg-config libdbus-1-dev libglib2.0-dev \ desktop-file-utils # for appimage-lint.sh diff --git a/requirements.txt b/requirements.txt index 84bf9814..d5b2e8a1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,6 +13,7 @@ sortedcontainers >= 2.2.2, < 3 watchgod >= 0.6, < 0.7 redbaron >= 0.9.2, < 1 hsluv >= 5.0.0, < 6 +simpleaudio >= 1.0.4, < 2 dbus-python >= 1.2.16, < 2; platform_system == "Linux" async_generator >= 1.10, < 2; python_version < "3.7" diff --git a/src/backend/backend.py b/src/backend/backend.py index de7b0757..e4e3f960 100644 --- a/src/backend/backend.py +++ b/src/backend/backend.py @@ -2,12 +2,14 @@ # SPDX-License-Identifier: LGPL-3.0-or-later import asyncio +import io import logging as log import os import re import sys import time import traceback +import wave from datetime import datetime, timedelta from pathlib import Path from typing import Any, DefaultDict, Dict, List, Optional, Tuple, Union @@ -16,6 +18,8 @@ from urllib.parse import urlparse import aiohttp import nio import plyer +import pyotherside +import simpleaudio from appdirs import AppDirs from . import __app_name__ @@ -584,3 +588,18 @@ class Backend: trace = traceback.format_exc().rstrip() log.error("Sending desktop notification failed\n%s", trace) self.notifications_working = False + + + async def sound_notify(self) -> None: + path = self.settings.Notifications.default_sound + + if path == "default.wav": + path = "src/sounds/default.wav" + + try: + content = pyotherside.qrc_get_file_contents(path) + except ValueError: + simpleaudio.WaveObject.from_wave_file(path).play() + else: + wave_read = wave.open(io.BytesIO(content)) + simpleaudio.WaveObject.from_wave_read(wave_read).play() diff --git a/src/config/settings.py b/src/config/settings.py index 393f7205..029d73a6 100644 --- a/src/config/settings.py +++ b/src/config/settings.py @@ -58,12 +58,9 @@ class Notifications: # Default sound to play for notifications. Can be the filename # of a builtin sound (only "default.wav" currently exists), or the - # absolute path to an audio file, preferably in the WAV format. + # absolute path to a WAV file. default_sound: str = "default.wav" - # Volume at which the notification sound will be played, 0-100. - volume: int = 75 - # How long in seconds the window will flash in your dock or taskbar when # a new message, which matches a notification push rule with a # flash (lightbulb) action, is posted in a room. diff --git a/src/gui/PythonBridge/EventHandlers.qml b/src/gui/PythonBridge/EventHandlers.qml index a8d5aaf6..d7eec712 100644 --- a/src/gui/PythonBridge/EventHandlers.qml +++ b/src/gui/PythonBridge/EventHandlers.qml @@ -23,13 +23,8 @@ QtObject { if (Qt.application.state === Qt.ApplicationActive) return - if (bubble) - py.callCoro("desktop_notify", [title, body, image]) - - if (sound) { - window.mainUI.defaultNotificationSound.seek(0) - window.mainUI.defaultNotificationSound.play() - } + if (bubble) py.callCoro("desktop_notify", [title, body, image]) + if (sound) py.callCoro("sound_notify") if (urgencyHint) { const msec = diff --git a/src/gui/UI.qml b/src/gui/UI.qml index 03cc89c6..c4e5ba9f 100644 --- a/src/gui/UI.qml +++ b/src/gui/UI.qml @@ -6,7 +6,6 @@ import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 import QtQuick.Window 2.12 import QtGraphicalEffects 1.12 -import QtMultimedia 5.12 import "." import "Base" import "MainPane" @@ -36,7 +35,6 @@ Item { return ids } - readonly property alias defaultNotificationSound: defaultNotificationSound readonly property alias debugConsole: debugConsole readonly property alias mainPane: mainPane readonly property alias pageLoader: pageLoader @@ -116,17 +114,6 @@ Item { font.pointSize: -1 } - Audio { - id: defaultNotificationSound - - readonly property string sfx: - window.settings.Notifications.default_sound - - audioRole: Audio.NotificationRole - volume: window.settings.Notifications.volume / 100 - source: sfx.trim() === "default.wav" ? "../sounds/default.wav" : sfx - } - IdleManager { id: idleManager }