Næster version

This commit is contained in:
2026-04-14 14:05:11 +02:00
parent 9257f198eb
commit 66804681da
11 changed files with 647 additions and 364 deletions

View File

@@ -216,9 +216,38 @@ class Player(QObject):
self.levels_changed.emit(max(0.0, l), max(0.0, r))
def set_audio_device(self, device_id: str):
"""Sæt lydoutput-enhed. device_id fra get_audio_devices()."""
if VLC_AVAILABLE and self._media_player:
self._media_player.audio_output_device_set(None, device_id)
@staticmethod
def get_audio_devices() -> list[dict]:
"""Returner liste af tilgængelige lydenheder."""
if not VLC_AVAILABLE:
return []
try:
instance = vlc.Instance("--no-video", "--quiet")
mp = instance.media_player_new()
devices = []
d = mp.audio_output_device_enum()
if d:
node = d
while node:
devices.append({
"id": node.contents.device.decode("utf-8", errors="replace"),
"name": node.contents.description.decode("utf-8", errors="replace"),
})
node = node.contents.next
vlc.libvlc_audio_output_device_list_release(d)
mp.release()
instance.release()
return devices
except Exception:
return []
def _on_end_reached(self, event):
"""Kaldes fra VLC's event-tråd — må IKKE røre Qt-objekter direkte."""
# QTimer.singleShot er thread-safe og sender alt til main thread
from PyQt6.QtCore import QTimer as _QTimer
_QTimer.singleShot(0, self._handle_end_in_main_thread)
@@ -227,3 +256,77 @@ class Player(QObject):
self._poll_timer.stop()
self.song_ended.emit()
self.state_changed.emit("stopped")
class PreviewPlayer(QObject):
"""Simpel preview-afspiller til bibliotek — ingen signals, bare play/stop."""
def __init__(self, parent=None):
super().__init__(parent)
self._volume = 78
self._device_id = ""
if VLC_AVAILABLE:
self._instance = vlc.Instance("--no-video", "--quiet")
self._mp = self._instance.media_player_new()
else:
self._mp = None
def play(self, path: str):
if not VLC_AVAILABLE or not self._mp:
return
from player.player import Player
vlc_path = Player._resolve_path(self, path)
media = self._instance.media_new(vlc_path)
self._mp.set_media(media)
self._mp.audio_set_volume(self._volume)
self._mp.play()
# Sæt lydenhed efter play — VLC nulstiller den ved ny media
if self._device_id:
self._mp.audio_output_device_set(None, self._device_id)
def pause(self):
if VLC_AVAILABLE and self._mp:
self._mp.pause()
def resume(self):
if VLC_AVAILABLE and self._mp:
self._mp.play()
def stop(self):
if VLC_AVAILABLE and self._mp:
self._mp.stop()
def seek(self, fraction: float):
if VLC_AVAILABLE and self._mp:
self._mp.set_position(fraction)
def is_playing(self) -> bool:
if VLC_AVAILABLE and self._mp:
return bool(self._mp.is_playing())
return False
def get_position(self) -> float:
if VLC_AVAILABLE and self._mp:
return max(0.0, self._mp.get_position())
return 0.0
def get_time(self) -> int:
if VLC_AVAILABLE and self._mp:
return max(0, self._mp.get_time() // 1000)
return 0
def get_duration(self) -> int:
if VLC_AVAILABLE and self._mp:
ms = self._mp.get_length()
return max(0, ms // 1000)
return 0
def set_volume(self, volume: int):
self._volume = volume
if VLC_AVAILABLE and self._mp:
self._mp.audio_set_volume(volume)
def set_audio_device(self, device_id: str):
self._device_id = device_id
if VLC_AVAILABLE and self._mp:
self._mp.audio_output_device_set(None, device_id)