Added a "Playlist" class.
This commit is contained in:
parent
1190059218
commit
94269fdae4
7 changed files with 119 additions and 53 deletions
|
@ -13,7 +13,7 @@ class Settings:
|
|||
self.settings.visibilityChanged.connect(self.update_all)
|
||||
self.settings.save_button.pressed.connect(self.write_settings)
|
||||
|
||||
def update_all(self, settings_visible: bool=True):
|
||||
def update_all(self, _=True): # ignore visible parameter passed by visibilityChanged event
|
||||
self.settings.file_settings.library_path_input.setText(self.app.settings.library_path)
|
||||
|
||||
def update_settings(self, key, value):
|
||||
|
|
|
@ -37,24 +37,24 @@ class TrackControl:
|
|||
self.track_control.track_progress_slider.sliderReleased.connect(self.on_slider_release)
|
||||
|
||||
def previous_track(self):
|
||||
if len(self.app.player.current_playlist) > 0:
|
||||
if self.app.player.current_playlist.has_tracks():
|
||||
self.app.player.previous_track()
|
||||
|
||||
def stop(self):
|
||||
if len(self.app.player.current_playlist) > 0:
|
||||
if self.app.player.current_playlist.has_tracks():
|
||||
self.app.player.stop()
|
||||
|
||||
def next_track(self):
|
||||
if len(self.app.player.current_playlist) > 0:
|
||||
if self.app.player.current_playlist.has_tracks():
|
||||
self.app.player.next_track()
|
||||
|
||||
def on_slider_release(self):
|
||||
if len(self.app.player.current_playlist) > 0:
|
||||
if self.app.player.current_playlist.has_tracks():
|
||||
self.app.player.seek(self.track_control.track_progress_slider.value())
|
||||
|
||||
def on_track_start(self):
|
||||
if self.app.player.playing:
|
||||
duration = self.app.player.current_track.duration
|
||||
duration = self.app.player.current_playlist.current_track.duration
|
||||
|
||||
self.track_control.track_progress_slider.setRange(
|
||||
0,
|
||||
|
@ -73,7 +73,7 @@ class TrackControl:
|
|||
if remaining == -1:
|
||||
remaining = self.app.player.track_progress.remaining_time
|
||||
|
||||
track_duration = self.app.player.current_track.duration
|
||||
track_duration = self.app.player.current_playlist.current_track.duration
|
||||
|
||||
progress = track_duration - remaining
|
||||
|
||||
|
@ -95,7 +95,7 @@ class TrackControl:
|
|||
self.app.player.pause()
|
||||
self.track_control.toggle_play_button.setIcon(self.play_icon)
|
||||
|
||||
elif len(self.app.player.current_playlist) > 0: # stopped but tracks in the current playlist
|
||||
elif self.app.player.current_playlist.has_tracks(): # stopped but tracks in the current playlist
|
||||
self.app.player.start_playing()
|
||||
self.track_control.toggle_play_button.setIcon(self.pause_icon)
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import os
|
|||
import pygame.mixer
|
||||
import pygame.event
|
||||
from .track import Track
|
||||
from .playlist import Playlist
|
||||
from .track_progress_timer import TrackProgress
|
||||
|
||||
|
||||
|
@ -18,14 +19,11 @@ class Player:
|
|||
|
||||
self.track_progress = TrackProgress(self.app)
|
||||
|
||||
self.current_playlist = Playlist(self.app)
|
||||
|
||||
self.playing = False
|
||||
self.paused = False
|
||||
|
||||
self.current_playlist = []
|
||||
self.current_playlist_index = 0
|
||||
|
||||
self.current_track = None
|
||||
|
||||
self.current_sound = None
|
||||
self.current_sound_duration = 0
|
||||
|
||||
|
@ -34,19 +32,11 @@ class Player:
|
|||
Load tracks from list of paths.
|
||||
"""
|
||||
|
||||
tracks = []
|
||||
self.current_playlist = Playlist(self.app)
|
||||
self.current_playlist.load_from_paths(track_paths)
|
||||
|
||||
for track_path in track_paths:
|
||||
if os.path.isfile(track_path):
|
||||
tracks.append(Track(track_path, True))
|
||||
|
||||
self.current_playlist = tracks
|
||||
self.current_playlist_index = 0
|
||||
|
||||
self.current_track = self.current_playlist[0]
|
||||
|
||||
self.current_sound = self.current_track.sound
|
||||
self.current_sound_duration = self.current_track.duration
|
||||
self.current_sound = self.current_playlist.current_track.sound
|
||||
self.current_sound_duration = self.current_playlist.current_track.duration
|
||||
|
||||
def play(self):
|
||||
self.music_channel.play(self.current_sound)
|
||||
|
@ -55,14 +45,8 @@ class Player:
|
|||
self.paused = False
|
||||
|
||||
def track_finished(self):
|
||||
|
||||
# if the last track wasn't the last in the playlist
|
||||
if self.current_playlist_index < len(self.current_playlist) - 1:
|
||||
self.current_playlist_index += 1
|
||||
|
||||
self.current_track = self.current_playlist[self.current_playlist_index]
|
||||
self.current_sound = self.current_track.sound
|
||||
self.current_sound_duration = self.current_track.duration
|
||||
if not self.current_playlist.on_last_track():
|
||||
self.current_sound, self.current_sound_duration = self.current_playlist.next_track()
|
||||
|
||||
self.play()
|
||||
self.track_progress.start()
|
||||
|
@ -72,8 +56,8 @@ class Player:
|
|||
self.stop()
|
||||
|
||||
def start_playing(self):
|
||||
self.current_sound = self.current_track.sound
|
||||
self.current_sound_duration = self.current_track.duration
|
||||
self.current_sound = self.current_playlist.current_track.sound
|
||||
self.current_sound_duration = self.current_playlist.current_track.duration
|
||||
|
||||
self.play()
|
||||
self.track_progress.start()
|
||||
|
@ -91,23 +75,19 @@ class Player:
|
|||
self.paused = False
|
||||
|
||||
def next_track(self):
|
||||
if self.current_playlist_index < len(self.current_playlist) - 1: # if the playing track isn't the last
|
||||
if not self.current_playlist.on_last_track():
|
||||
self.music_channel.stop()
|
||||
self.track_progress.stop()
|
||||
self.track_finished()
|
||||
|
||||
def previous_track(self):
|
||||
if self.current_playlist_index > 0: # if the current track isn't the first in the playlist
|
||||
if not self.current_playlist.on_first_track():
|
||||
self.music_channel.stop()
|
||||
|
||||
self.current_playlist_index -= 1
|
||||
self.current_track = self.current_playlist[self.current_playlist_index]
|
||||
self.current_sound, self.current_sound_duration = self.current_playlist.previous_track()
|
||||
|
||||
self.track_progress.stop()
|
||||
|
||||
self.current_sound = self.current_track.sound
|
||||
self.current_sound_duration = self.current_track.duration
|
||||
|
||||
self.play()
|
||||
self.track_progress.start()
|
||||
|
||||
|
@ -116,7 +96,7 @@ class Player:
|
|||
def stop(self):
|
||||
self.music_channel.stop()
|
||||
self.track_progress.stop()
|
||||
self.current_sound_duration = self.current_track.duration
|
||||
self.current_sound_duration = self.current_playlist.current_track.duration
|
||||
|
||||
self.playing = False
|
||||
self.paused = False
|
||||
|
@ -125,7 +105,7 @@ class Player:
|
|||
self.music_channel.stop()
|
||||
self.track_progress.stop()
|
||||
|
||||
(self.current_sound, self.current_sound_duration) = self.current_track.remaining(position)
|
||||
(self.current_sound, self.current_sound_duration) = self.current_playlist.current_track.remaining(position)
|
||||
|
||||
self.play()
|
||||
self.track_progress.start()
|
||||
|
|
80
wobuzz/player/playlist.py
Normal file
80
wobuzz/player/playlist.py
Normal file
|
@ -0,0 +1,80 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import os
|
||||
from .track import Track
|
||||
|
||||
|
||||
class Playlist:
|
||||
def __init__(self, app):
|
||||
self.app = app
|
||||
self.tracks: list[Track] = []
|
||||
self.current_track_index = 0
|
||||
self.current_track: Track | None = None
|
||||
|
||||
def load_from_paths(self, paths):
|
||||
i = 0
|
||||
|
||||
while i < len(paths):
|
||||
path = paths[i]
|
||||
|
||||
if os.path.isfile(path):
|
||||
self.tracks.append(Track(self.app, path, cache=i==0)) # first track is cached
|
||||
|
||||
i += 1
|
||||
|
||||
self.current_track = self.tracks[0] # current track is the first track in the playlist
|
||||
|
||||
def load_from_m3u(self, path):
|
||||
file = open(path, "r")
|
||||
m3u = file.read()
|
||||
file.close()
|
||||
|
||||
lines = m3u.split("\n") # m3u entries
|
||||
|
||||
i = 0
|
||||
|
||||
while i < len(lines):
|
||||
line = lines[i]
|
||||
|
||||
if line.startswith("#") or line.startswith("http"): # filter out comments, extended m3u and urls
|
||||
continue
|
||||
|
||||
self.tracks.append(Track(self.app, line, cache=i==0)) # first track is cached
|
||||
|
||||
i += 1
|
||||
|
||||
def load_from_wbz(self, path):
|
||||
pass
|
||||
|
||||
def has_tracks(self):
|
||||
return len(self.tracks) > 0
|
||||
|
||||
def on_first_track(self):
|
||||
return self.current_track_index == 0
|
||||
|
||||
def on_last_track(self): # if the current track is the last
|
||||
return self.current_track_index == len(self.tracks) - 1
|
||||
|
||||
def next_track(self):
|
||||
self.current_track_index += 1
|
||||
self.current_track = self.tracks[self.current_track_index]
|
||||
|
||||
if not self.current_track.cached: # make sure the track is cached because else the player can't play it
|
||||
self.current_track.cache()
|
||||
self.current_track.cached = True
|
||||
|
||||
return self.current_track.sound, self.current_track.duration
|
||||
|
||||
def previous_track(self):
|
||||
if self.on_first_track():
|
||||
return self.current_track, self.current_track.duration
|
||||
|
||||
self.current_track_index -= 1
|
||||
self.current_track = self.tracks[self.current_track_index]
|
||||
|
||||
if not self.current_track.cached: # make sure the track is cached because else the player can't play it
|
||||
self.current_track.cache()
|
||||
self.current_track.cached = True
|
||||
|
||||
return self.current_track.sound, self.current_track.duration
|
||||
|
|
@ -10,22 +10,28 @@ class Track:
|
|||
Class containing data for a track like file path, raw data...
|
||||
"""
|
||||
|
||||
def __init__(self, path: str, cache: bool=False):
|
||||
def __init__(self, app, path: str, property_string: str=None, cache: bool=False):
|
||||
self.app = app
|
||||
self.path = path
|
||||
self.property_string = property_string
|
||||
self.cached = cache
|
||||
|
||||
(self.audio, self.sound, self.duration) = self.cache() if self.cached else (None, None, 0)
|
||||
self.audio = None
|
||||
self.sound = None
|
||||
self.duration = 0
|
||||
|
||||
if self.cached:
|
||||
self.cache()
|
||||
|
||||
def cache(self):
|
||||
audio = AudioSegment.from_mp3(self.path)
|
||||
self.audio = AudioSegment.from_mp3(self.path)
|
||||
# audio = normalize(audio)
|
||||
|
||||
wav = audio.export(format="wav")
|
||||
wav = self.audio.export(format="wav")
|
||||
|
||||
sound = Sound(wav)
|
||||
self.sound = Sound(wav)
|
||||
|
||||
# return pygame.mixer.Sound object and track duration in milliseconds
|
||||
return audio, sound, len(audio)
|
||||
self.duration = len(self.audio) # track duration in milliseconds
|
||||
|
||||
def remaining(self, position: int):
|
||||
remaining_audio = self.audio[position:]
|
||||
|
@ -34,4 +40,5 @@ class Track:
|
|||
|
||||
sound = Sound(wav)
|
||||
|
||||
# return the remaining part of the track's audio and the duration of the remaining part
|
||||
return sound, len(remaining_audio)
|
||||
|
|
|
@ -28,4 +28,4 @@ class TrackProgress:
|
|||
|
||||
def stop(self):
|
||||
self.timer.stop()
|
||||
self.remaining_time = self.app.player.current_track.duration
|
||||
self.remaining_time = self.app.player.current_playlist.current_track.duration
|
||||
|
|
|
@ -33,4 +33,3 @@ class MainWindow(QMainWindow):
|
|||
self.library_dock = LibraryDock()
|
||||
self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.library_dock)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue