Audioausgabe pro Tab: YouTube und YouTube Musik auf verschiedene Geraete legen
In den Einstellungen (Gruppe "Audioausgabe", Felder "YouTube" und "YouTube Musik") laesst sich getrennt waehlen, ueber welches Ausgabegeraet der Ton jedes Tabs laeuft - z.B. auf getrennte Sonar-Kanaele. Die Auswahl gilt sofort, auch fuer bereits geoeffnete Seiten. Warum ueber die Seite: QtWebEngine spielt beide Tabs ueber einen gemeinsamen Audio-Prozess ab, Windows kann sie daher nicht einzeln routen. Chromium kann aber pro Medienelement ein Geraet waehlen (setSinkId). - audio_routing.py (neu): Router-Skript (findet das Geraet ueber seinen Namen, kennt den Hardware-ID-Suffix von Chromium, behandelt dynamisch erzeugte Elemente, Zielwechsel, Zuruecksetzen und fehlende Geraete), Geraeteliste (QMediaDevices), Freigabe der Geraetenamen (Chromium blendet sie ohne Mikrofon-Berechtigung aus) - Freigabe nur solange ein Tab ein eigenes Geraet nutzt, nur fuer die beiden YouTube- Seiten, nur fuer die laufende Sitzung (Qt speichert sie nicht) - bei jedem Start und nach jedem Seitenaufbau neu erteilt, weil sie auf der YouTube-Startseite sonst nicht greift - browser: BrowserTab.set_audio_output (Skript pro Seite; ohne Auswahl wird die Seite gar nicht angefasst) - settings_tab: neue Gruppe, Hot-Plug-Aktualisierung, fehlendes Geraet bleibt als "nicht verfuegbar" gespeichert, Discord-Anzeige nennt das bearbeitete Feld - config: audio.youtube_output / audio.music_output (leer = Systemstandard) - README: Abschnitt inkl. Hinweis, dass Windows weiter einen Eintrag "Playtube" zeigt
This commit is contained in:
+35
-1
@@ -20,7 +20,8 @@ from PySide6.QtWidgets import (
|
||||
)
|
||||
|
||||
from . import __version__ as APP_VERSION
|
||||
from .browser import BrowserTab
|
||||
from .audio_routing import sync_audio_permissions
|
||||
from .browser import BrowserTab, get_shared_profile
|
||||
from .config import APP_NAME
|
||||
from .discord_rpc import DiscordRPCWorker
|
||||
from .settings_tab import SettingsTab
|
||||
@@ -54,13 +55,20 @@ class MainWindow(QMainWindow):
|
||||
self._tabs.setDocumentMode(True)
|
||||
self.setCentralWidget(self._tabs)
|
||||
|
||||
self._sync_audio_permission()
|
||||
self._youtube_tab = BrowserTab(config["home_youtube"], self)
|
||||
self._music_tab = BrowserTab(config["home_music"], self)
|
||||
# Zusaetzlich nach JEDEM Seitenaufbau erneut erteilen: eine nur VOR dem Laden erteilte
|
||||
# Freigabe greift auf der YouTube-Startseite nicht (per Test ermittelt), eine danach
|
||||
# erteilte schon (siehe audio_routing.py).
|
||||
for tab in (self._youtube_tab, self._music_tab):
|
||||
tab.loadFinished.connect(self._on_tab_load_finished)
|
||||
self._settings_tab = SettingsTab(config, self)
|
||||
self._tabs.addTab(self._youtube_tab, "YouTube")
|
||||
self._tabs.addTab(self._music_tab, "YouTube Music")
|
||||
self._tabs.addTab(self._settings_tab, "Einstellungen")
|
||||
self._tabs.setCurrentIndex(0 if config.get("start_tab") != "music" else 1)
|
||||
self._apply_audio_routing()
|
||||
self._settings_tab.settingsSaved.connect(self._on_settings_saved)
|
||||
self._settings_tab.activityChanged.connect(lambda _activity: self._update_discord_presence())
|
||||
self._settings_tab.checkUpdatesRequested.connect(self._check_for_updates)
|
||||
@@ -232,8 +240,34 @@ class MainWindow(QMainWindow):
|
||||
)
|
||||
self._rpc_worker.start()
|
||||
|
||||
def _audio_outputs(self) -> tuple[str, str]:
|
||||
"""(Geraet fuer YouTube, Geraet fuer YouTube Musik) aus der Konfiguration; leer =
|
||||
Systemstandard."""
|
||||
audio_cfg = self._config.get("audio", {})
|
||||
return (
|
||||
str(audio_cfg.get("youtube_output", "") or ""),
|
||||
str(audio_cfg.get("music_output", "") or ""),
|
||||
)
|
||||
|
||||
def _sync_audio_permission(self) -> None:
|
||||
"""Erteilt bzw. entzieht die Freigabe der Geraetenamen (siehe audio_routing.py) -
|
||||
nur solange mindestens ein Tab ein eigenes Geraet nutzt."""
|
||||
sync_audio_permissions(get_shared_profile(), any(self._audio_outputs()))
|
||||
|
||||
def _on_tab_load_finished(self, _ok: bool) -> None:
|
||||
if any(self._audio_outputs()):
|
||||
self._sync_audio_permission()
|
||||
|
||||
def _apply_audio_routing(self) -> None:
|
||||
"""Wendet die in den Einstellungen gewaehlten Ausgabegeraete pro Tab an."""
|
||||
youtube_output, music_output = self._audio_outputs()
|
||||
self._youtube_tab.set_audio_output(youtube_output)
|
||||
self._music_tab.set_audio_output(music_output)
|
||||
|
||||
def _on_settings_saved(self, new_config: dict) -> None:
|
||||
self._config = new_config
|
||||
self._sync_audio_permission()
|
||||
self._apply_audio_routing()
|
||||
|
||||
if self._rpc_worker is not None:
|
||||
self._rpc_worker.stop()
|
||||
|
||||
Reference in New Issue
Block a user