All preview/intro management working
This commit is contained in:
parent
09fdd7e4dc
commit
909fb27bed
@ -52,7 +52,6 @@ class Config(object):
|
||||
HEADER_TITLE = "Title"
|
||||
HIDE_AFTER_PLAYING_OFFSET = 5000
|
||||
INFO_TAB_TITLE_LENGTH = 15
|
||||
INTRO_END_GAP_MS = 1000
|
||||
INTRO_SECONDS_FORMAT = ".1f"
|
||||
INTRO_SECONDS_WARNING_MS = 3000
|
||||
LAST_PLAYED_TODAY_STRING = "Today"
|
||||
@ -78,6 +77,7 @@ class Config(object):
|
||||
PLAY_SETTLE = 500000
|
||||
PREVIEW_ADVANCE_MS = 5000
|
||||
PREVIEW_BACK_MS = 5000
|
||||
PREVIEW_END_BUFFER_MS = 1000
|
||||
REPLACE_FILES_DEFAULT_SOURCE = "/home/kae/music/Singles/tmp"
|
||||
RETURN_KEY_DEBOUNCE_MS = 500
|
||||
ROOT = os.environ.get("ROOT") or "/home/kae/music"
|
||||
|
||||
@ -1062,22 +1062,30 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
|
||||
if self.btnPreview.isChecked():
|
||||
# Get track_id for first selected track if there is one
|
||||
track_id = self.active_tab().get_selected_row_track_id()
|
||||
if not track_id:
|
||||
# Otherwise get path to next track to play
|
||||
row_number_and_track_id = self.active_tab().get_selected_row_and_track_id()
|
||||
if row_number_and_track_id:
|
||||
row_number, track_id = row_number_and_track_id
|
||||
else:
|
||||
# Otherwise get track_id to next track to play
|
||||
if track_sequence.next:
|
||||
track_id = track_sequence.next.track_id
|
||||
if not track_id:
|
||||
self.btnPreview.setChecked(False)
|
||||
return
|
||||
row_number = track_sequence.next.row_number
|
||||
if not track_id or row_number is None:
|
||||
self.btnPreview.setChecked(False)
|
||||
return
|
||||
|
||||
with db.Session() as session:
|
||||
self.preview_track_player = PreviewTrackManager(session, track_id)
|
||||
self.preview_track_player = PreviewTrackManager(
|
||||
session=session, track_id=track_id, row_number=row_number
|
||||
)
|
||||
self.preview_track_player.play()
|
||||
|
||||
else:
|
||||
if self.preview_track_player:
|
||||
self.preview_track_player.stop_playing()
|
||||
self.preview_track_player.stop()
|
||||
self.preview_track_player = None
|
||||
self.label_intro_timer.setText("0.0")
|
||||
self.label_intro_timer.setStyleSheet("")
|
||||
self.btnPreviewMark.setEnabled(False)
|
||||
self.btnPreviewArm.setChecked(False)
|
||||
|
||||
@ -1089,51 +1097,45 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
def preview_back(self) -> None:
|
||||
"""Wind back preview file"""
|
||||
|
||||
self.preview_track_player.move_back(Config.PREVIEW_BACK_MS)
|
||||
if self.preview_track_player:
|
||||
self.preview_track_player.move_back()
|
||||
|
||||
def preview_end(self) -> None:
|
||||
"""Advance preview file to just before end of intro"""
|
||||
"""Advance preview file to Config.PREVIEW_END_BUFFER_MS before end of intro"""
|
||||
|
||||
return
|
||||
|
||||
# preview_track_path = self.preview_player.path
|
||||
# if not preview_track_path:
|
||||
# return
|
||||
|
||||
# with Session() as session:
|
||||
# preview_track = Tracks.get_by_path(session, preview_track_path)
|
||||
# if not preview_track or not preview_track.intro:
|
||||
# return
|
||||
|
||||
# new_position = max(0, preview_track.intro - Config.INTRO_END_GAP_MS)
|
||||
# self.preview_player.set_position(new_position)
|
||||
if self.preview_track_player:
|
||||
self.preview_track_player.move_to_intro_end()
|
||||
|
||||
def preview_fwd(self) -> None:
|
||||
"""Advance preview file"""
|
||||
|
||||
self.preview_player.move_forward(Config.PREVIEW_ADVANCE_MS)
|
||||
if self.preview_track_player:
|
||||
self.preview_track_player.move_forward()
|
||||
|
||||
def preview_mark(self) -> None:
|
||||
"""Set intro time"""
|
||||
|
||||
track_id = self.active_tab().get_selected_row_track_id()
|
||||
row_number = self.active_tab().get_selected_row()
|
||||
if track_id:
|
||||
if self.preview_track_player:
|
||||
track_id = self.preview_track_player.track_id
|
||||
row_number = self.preview_track_player.row_number
|
||||
with db.Session() as session:
|
||||
track = session.get(Tracks, track_id)
|
||||
if track:
|
||||
# Save intro as millisends rounded to nearest 0.1
|
||||
# second because editor spinbox only resolves to 0.1
|
||||
# seconds
|
||||
track.intro = round(self.preview_player.get_playtime() / 100) * 100
|
||||
intro = round(self.preview_track_player.time_playing() / 100) * 100
|
||||
track.intro = intro
|
||||
session.commit()
|
||||
self.preview_track_player.intro = intro
|
||||
self.active_tab().source_model.refresh_row(session, row_number)
|
||||
self.active_tab().source_model.invalidate_row(row_number)
|
||||
|
||||
def preview_start(self) -> None:
|
||||
"""Advance preview file"""
|
||||
"""Restart preview"""
|
||||
|
||||
self.preview_track_player.set_position(0)
|
||||
if self.preview_track_player:
|
||||
self.preview_track_player.restart()
|
||||
|
||||
def rename_playlist(self) -> None:
|
||||
"""
|
||||
@ -1504,6 +1506,24 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
# currnent track ended during servicing tick
|
||||
pass
|
||||
|
||||
# Ensure preview button is reset if preview finishes playing
|
||||
if self.preview_track_player:
|
||||
self.btnPreview.setChecked(self.preview_track_player.is_playing())
|
||||
|
||||
# Update preview timer
|
||||
if self.preview_track_player.is_playing():
|
||||
playtime = self.preview_track_player.time_playing()
|
||||
self.label_intro_timer.setText(f"{playtime / 1000:.1f}")
|
||||
if self.preview_track_player.time_remaining_intro() <= 50:
|
||||
self.label_intro_timer.setStyleSheet(
|
||||
f"background: {Config.COLOUR_WARNING_TIMER}"
|
||||
)
|
||||
else:
|
||||
self.label_intro_timer.setStyleSheet("")
|
||||
else:
|
||||
self.label_intro_timer.setText("0.0")
|
||||
self.label_intro_timer.setStyleSheet("")
|
||||
self.btnPreview.setChecked(False)
|
||||
|
||||
def tick_1000ms(self) -> None:
|
||||
"""
|
||||
|
||||
@ -631,21 +631,23 @@ class PlaylistTab(QTableView):
|
||||
self.source_model.delete_rows(self.selected_model_row_numbers())
|
||||
self.clear_selection()
|
||||
|
||||
def get_selected_row_track_id(self) -> Optional[int]:
|
||||
def get_selected_row_and_track_id(self) -> Optional[tuple[int, int]]:
|
||||
"""
|
||||
Return the track_id of the selected row. If no row selected or selected
|
||||
Return the (row_number, track_id) of the selected row. If no row selected or selected
|
||||
row does not have a track, return None.
|
||||
"""
|
||||
|
||||
log.debug("get_selected_row_track_id() called")
|
||||
|
||||
model_row_number = self.source_model_selected_row_number()
|
||||
if model_row_number is None:
|
||||
row_number = self.source_model_selected_row_number()
|
||||
if row_number is None:
|
||||
result = None
|
||||
else:
|
||||
result = self.source_model.get_row_track_id(model_row_number)
|
||||
track_id = self.source_model.get_row_track_id(row_number)
|
||||
if not track_id:
|
||||
result = None
|
||||
else:
|
||||
result = (row_number, track_id)
|
||||
|
||||
log.debug(f"get_selected_row_track_id() returned: {result=}")
|
||||
log.debug(f"get_selected_row_and_track_id() returned: {result=}")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@ -170,7 +170,7 @@ class _Music:
|
||||
self.max_volume = Config.VLC_VOLUME_DEFAULT
|
||||
self.start_dt: Optional[dt.datetime] = None
|
||||
|
||||
def _adjust_by_ms(self, ms: int) -> None:
|
||||
def adjust_by_ms(self, ms: int) -> None:
|
||||
"""Move player position by ms milliseconds"""
|
||||
|
||||
if not self.player:
|
||||
@ -275,20 +275,6 @@ class _Music:
|
||||
< dt.timedelta(microseconds=Config.PLAY_SETTLE)
|
||||
)
|
||||
|
||||
def move_back(self, ms: int) -> None:
|
||||
"""
|
||||
Rewind player by ms milliseconds
|
||||
"""
|
||||
|
||||
self._adjust_by_ms(ms * -1)
|
||||
|
||||
def move_forward(self, ms: int) -> None:
|
||||
"""
|
||||
Rewind player by ms milliseconds
|
||||
"""
|
||||
|
||||
self._adjust_by_ms(ms)
|
||||
|
||||
def play(
|
||||
self,
|
||||
path: str,
|
||||
@ -304,7 +290,7 @@ class _Music:
|
||||
the start time is the same
|
||||
"""
|
||||
|
||||
log.info(f"Music[{self.name}].play({path=}, {position=}")
|
||||
log.debug(f"Music[{self.name}].play({path=}, {position=}")
|
||||
|
||||
if file_is_unreadable(path):
|
||||
log.error(f"play({path}): path not readable")
|
||||
@ -374,7 +360,7 @@ class _TrackManager:
|
||||
typically the previous, current and next track.
|
||||
"""
|
||||
|
||||
def __init__(self, session: db.Session, player_name: str, track_id: int) -> None:
|
||||
def __init__(self, session: db.Session, player_name: str, track_id: int, row_number: int) -> None:
|
||||
"""
|
||||
Initialises data structure.
|
||||
Define a player.
|
||||
@ -385,6 +371,7 @@ class _TrackManager:
|
||||
if not track:
|
||||
raise ValueError(f"_TrackPlayer: unable to retreived {track_id=}")
|
||||
self.player_name = player_name
|
||||
self.row_number = row_number
|
||||
|
||||
self.artist = track.artist
|
||||
self.bitrate = track.bitrate
|
||||
@ -462,6 +449,33 @@ class _TrackManager:
|
||||
|
||||
return self.player.is_playing()
|
||||
|
||||
def move_back(self, ms: int = Config.PREVIEW_BACK_MS) -> None:
|
||||
"""
|
||||
Rewind player by ms milliseconds
|
||||
"""
|
||||
|
||||
self.player.adjust_by_ms(ms * -1)
|
||||
|
||||
def move_forward(self, ms: int = Config.PREVIEW_ADVANCE_MS) -> None:
|
||||
"""
|
||||
Rewind player by ms milliseconds
|
||||
"""
|
||||
|
||||
self.player.adjust_by_ms(ms)
|
||||
|
||||
def move_to_intro_end(self, buffer: int = Config.PREVIEW_END_BUFFER_MS) -> None:
|
||||
"""
|
||||
Move play position to 'buffer' milliseconds before end of intro.
|
||||
|
||||
If no intro defined, do nothing.
|
||||
"""
|
||||
|
||||
if self.intro is None:
|
||||
return
|
||||
|
||||
new_position = max(0, self.intro - Config.PREVIEW_END_BUFFER_MS)
|
||||
self.player.adjust_by_ms(new_position - self.time_playing())
|
||||
|
||||
def play(self, position: Optional[float] = None) -> None:
|
||||
"""Play track"""
|
||||
|
||||
@ -481,6 +495,13 @@ class _TrackManager:
|
||||
milliseconds=update_graph_at_ms
|
||||
)
|
||||
|
||||
def restart(self) -> None:
|
||||
"""
|
||||
Restart player
|
||||
"""
|
||||
|
||||
self.player.adjust_by_ms(self.time_playing() * -1)
|
||||
|
||||
def stop(self, fade_seconds: int = 0) -> None:
|
||||
"""
|
||||
Stop this track playing
|
||||
@ -575,12 +596,12 @@ class MainTrackManager(_TrackManager):
|
||||
session=session,
|
||||
player_name=Config.VLC_MAIN_PLAYER_NAME,
|
||||
track_id=self.track_id,
|
||||
row_number=plr.plr_rownum
|
||||
)
|
||||
|
||||
# Save non-track plr info
|
||||
self.plr_id: int = plr.id
|
||||
self.playlist_id: int = plr.playlist_id
|
||||
self.row_number: int = plr.plr_rownum
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return (
|
||||
@ -594,11 +615,12 @@ class PreviewTrackManager(_TrackManager):
|
||||
Manage previewing tracks
|
||||
"""
|
||||
|
||||
def __init__(self, session: db.Session, track_id: int) -> None:
|
||||
def __init__(self, session: db.Session, track_id: int, row_number: int) -> None:
|
||||
super().__init__(
|
||||
session=session,
|
||||
player_name=Config.VLC_PREVIEW_PLAYER_NAME,
|
||||
track_id=track_id,
|
||||
row_number=row_number
|
||||
)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user