Næster version
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user