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:
@@ -17,6 +17,8 @@ from PySide6.QtWebEngineCore import (
|
||||
)
|
||||
from PySide6.QtWebEngineWidgets import QWebEngineView
|
||||
|
||||
from .audio_routing import SCRIPT_NAME as AUDIO_SCRIPT_NAME
|
||||
from .audio_routing import build_router_script
|
||||
from .chrome_shim import CHROME_FULL, CHROME_MAJOR, CHROME_SHIM_JS
|
||||
from .config import profile_dir
|
||||
from .media_probe import MEDIA_PROBE_JS, NEXT_TRACK_JS, PREV_TRACK_JS, TOGGLE_PLAYBACK_JS
|
||||
@@ -116,6 +118,7 @@ class BrowserTab(QWebEngineView):
|
||||
def __init__(self, home_url: str, parent=None):
|
||||
super().__init__(parent)
|
||||
self._home_url = home_url
|
||||
self._audio_output_set = False # war schon ein eigenes Ausgabegeraet gewaehlt? (siehe set_audio_output)
|
||||
|
||||
page = QWebEnginePage(get_shared_profile(), self)
|
||||
self.setPage(page)
|
||||
@@ -142,6 +145,32 @@ class BrowserTab(QWebEngineView):
|
||||
def go_home(self) -> None:
|
||||
self.load(QUrl(self._home_url))
|
||||
|
||||
def set_audio_output(self, device_name: str) -> None:
|
||||
"""Legt den Ton dieses Tabs auf das Ausgabegeraet `device_name` (leer =
|
||||
Systemstandard), siehe audio_routing.py. Wirkt sofort auf die geoeffnete Seite und
|
||||
bleibt bei Seitenwechseln/Neuladen erhalten (Skript pro Seite)."""
|
||||
page = self.page()
|
||||
scripts = page.scripts()
|
||||
for old in scripts.find(AUDIO_SCRIPT_NAME):
|
||||
scripts.remove(old)
|
||||
|
||||
source = build_router_script(device_name)
|
||||
if device_name:
|
||||
script = QWebEngineScript()
|
||||
script.setName(AUDIO_SCRIPT_NAME)
|
||||
script.setInjectionPoint(QWebEngineScript.InjectionPoint.DocumentReady)
|
||||
script.setWorldId(QWebEngineScript.ScriptWorldId.MainWorld)
|
||||
script.setRunsOnSubFrames(False)
|
||||
script.setSourceCode(source)
|
||||
scripts.insert(script)
|
||||
|
||||
# Bereits geladene Seite sofort umstellen - auch zurueck auf den Systemstandard,
|
||||
# falls vorher ein eigenes Geraet gewaehlt war. Ohne jemals gewaehltes Geraet wird die
|
||||
# Seite gar nicht angefasst.
|
||||
if device_name or self._audio_output_set:
|
||||
page.runJavaScript(source)
|
||||
self._audio_output_set = bool(device_name)
|
||||
|
||||
def toggle_playback(self) -> None:
|
||||
self.page().runJavaScript(TOGGLE_PLAYBACK_JS)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user