From 6926fffc22fde2a12fa2024fc270bfe13e52beba Mon Sep 17 00:00:00 2001 From: "Christopher T. Johnson" Date: Tue, 2 Apr 2024 11:02:29 -0400 Subject: [PATCH] Networking glitchs sort of fixed. --- lib/sounds.py | 74 ++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/lib/sounds.py b/lib/sounds.py index ac1d21f..28ba34a 100644 --- a/lib/sounds.py +++ b/lib/sounds.py @@ -3,6 +3,7 @@ from typing import Optional, Self, Type, cast from PyQt6.QtCore import ( QBuffer, QByteArray, + QCryptographicHash, QDir, QObject, QStandardPaths, @@ -18,6 +19,7 @@ from PyQt6.QtMultimedia import ( from PyQt6.QtNetwork import ( QNetworkAccessManager, QNetworkDiskCache, + QNetworkReply, QNetworkRequest, ) @@ -85,6 +87,7 @@ class SoundOff(QObject): netCache.setCacheDirectory(cacheDir.path()) self.nam = QNetworkAccessManager() self.nam.setCache(netCache) + self.nam.finished.connect(self.finished) return @pyqtSlot(QMediaPlayer.Error, str) @@ -95,7 +98,7 @@ class SoundOff(QObject): @pyqtSlot(QMediaPlayer.MediaStatus) def mediaStatus(self, status: QMediaPlayer.MediaStatus) -> None: - print(f"mediaStatus: {status}") + # print(f"mediaStatus: {status}") if status == QMediaPlayer.MediaStatus.LoadedMedia: player: Optional[QMediaPlayer] = cast(QMediaPlayer, self.sender()) assert player is not None @@ -104,7 +107,7 @@ class SoundOff(QObject): @pyqtSlot(QMediaPlayer.PlaybackState) def playbackState(self, state: QMediaPlayer.PlaybackState) -> None: - print(f"playbackState: {state}") + # print(f"playbackState: {state}") return # @@ -121,10 +124,19 @@ class SoundOff(QObject): url = QUrl(url) if not self.localPlayer.audioOutput(): self.localPlayer.setAudioOutput(self.localOutput) - request = QNetworkRequest(url) - self.reply = self.nam.get(request) - assert self.reply is not None - self.reply.finished.connect(self.finished) + if self.virtualPlayer and not self.virtualPlayer.audioOutput(): + self.virtualPlayer.setAudioOutput(self.virtualOutput) + if url != self._lastUrl: + request = QNetworkRequest(url) + self.nam.get(request) + self._lastUrl = url + return + for player in [self.localPlayer, self.virtualPlayer]: + if not player: + continue + player.setPosition(0) + if player.mediaStatus() == QMediaPlayer.MediaStatus.LoadedMedia: + player.play() return @pyqtSlot() @@ -135,33 +147,27 @@ class SoundOff(QObject): # # Network slots # - _buffer = QBuffer() - _storage = QByteArray() + _storage: dict[QMediaPlayer, QByteArray] = {} + _buffer: dict[QMediaPlayer, QBuffer] = {} + _lastUrl = QUrl() - @pyqtSlot() - def finished(self) -> None: - assert self.reply is not None - self._storage = self.reply.readAll() - if self.localPlayer.sourceDevice() != self._buffer: - self._buffer.setBuffer(self._storage) - self.localPlayer.setSourceDevice(self._buffer) - self.localPlayer.setPosition(0) - if ( - self.localPlayer.mediaStatus() - == QMediaPlayer.MediaStatus.LoadedMedia - ): - self.localPlayer.play() - print("play") - if not self.virtualDevice: - return - if self.virtualPlayer.sourceDevice() != self._buffer: - self.virtualPlayer.setSourceDevice(self._buffer) - self.virtualPlayer.setPosition(0) - if not self.virtualPlayer.audioOutput(): - self.virtualPlayer.setAudioOutput(self.virtualOutput) - if ( - self.virtualPlayer.mediaStatus() - == QMediaPlayer.MediaStatus.LoadedMedia - ): - self.virtualPlayer.play() + @pyqtSlot(QNetworkReply) + def finished(self, reply: QNetworkReply) -> None: + storage = reply.readAll() + + crypto = QCryptographicHash(QCryptographicHash.Algorithm.Sha256) + for player in [self.localPlayer, self.virtualPlayer]: + if not player: + continue + self._storage[player] = QByteArray(storage) + crypto.addData(self._storage[player]) + print(player, crypto.result().toHex()) + crypto.reset() + self._buffer[player] = QBuffer(self._storage[player]) + url = reply.request().url() + player.setSourceDevice(self._buffer[player], url) + player.setPosition(0) + if player.mediaStatus() == QMediaPlayer.MediaStatus.LoadedMedia: + player.play() + print("play") return