diff --git a/lazy_player/__init__.py b/lazy_player/__init__.py index c53bc9c..c051232 100644 --- a/lazy_player/__init__.py +++ b/lazy_player/__init__.py @@ -157,6 +157,7 @@ class MainWindow(Gtk.ApplicationWindow): file_item.full_path, position, file_item.saved_subtitle_track, + file_item.saved_audio_track, ) self.last_position_save = self.now @@ -359,11 +360,24 @@ class MainWindow(Gtk.ApplicationWindow): self.show_overlay_text(f"Subtitles #{index} ({lang})") else: self.show_overlay_text("Subtitles turned off") + + self.selection.saved_subtitle_track = index - 1 else: self.show_overlay_text("No subtitles available") return True + elif keyval == Gdk.keyval_from_name("a"): + has_audio, index, lang = self.video_player.cycle_audio() + + if has_audio: + self.show_overlay_text(f"Audio #{index} ({lang})") + self.selection.saved_audio_track = index - 1 + else: + self.show_overlay_text("No audio tracks available") + + return True + return False def _toggle_watched_status(self) -> None: diff --git a/lazy_player/file_model.py b/lazy_player/file_model.py index 85e4105..ae49f2c 100644 --- a/lazy_player/file_model.py +++ b/lazy_player/file_model.py @@ -60,6 +60,15 @@ class FileItem(GObject.Object): self._save_attribute("subtitle_track", value if value >= -1 else None) self.notify("saved-subtitle-track") + @GObject.Property(type=int) + def saved_audio_track(self): + return self._load_attribute("audio_track", 0) + + @saved_audio_track.setter + def set_saved_audio_track(self, value: int): + self._save_attribute("audio_track", value if value > 0 else None) + self.notify("saved-audio-track") + @GObject.Property(type=bool, default=False) def has_thumbnail(self): return self._has_thumbnail diff --git a/lazy_player/video_player.py b/lazy_player/video_player.py index c30e916..4789e71 100644 --- a/lazy_player/video_player.py +++ b/lazy_player/video_player.py @@ -41,7 +41,13 @@ class VideoPlayer(GObject.Object): paintable = video_sink.get_property("paintable") picture.set_paintable(paintable) - def play(self, file_path: Path | str, position: int = 0, subtitle_track: int = -2) -> None: + def play( + self, + file_path: Path | str, + position: int = 0, + subtitle_track: int = -2, + audio_track: int = 0, + ) -> None: """Start playing a video file""" self.playbin.set_property("uri", Gst.filename_to_uri(str(file_path))) @@ -56,6 +62,8 @@ class VideoPlayer(GObject.Object): flags &= ~0x00000004 # TEXT flag self.playbin.set_property("flags", flags) + self.playbin.set_property("current-audio", audio_track) + # Pause and wait for it to complete self.pipeline.set_state(Gst.State.PAUSED) self.pipeline.get_state(Gst.CLOCK_TIME_NONE) @@ -147,7 +155,7 @@ class VideoPlayer(GObject.Object): flags |= 0x00000004 self.playbin.set_property("flags", flags) self.playbin.set_property("current-text", 0) - return True, 1, self._get_subtitle_lang(0) + return True, 1, self._get_track_lang("text", 0) if current >= n_text - 1: flags &= ~0x00000004 # TEXT flag @@ -156,10 +164,23 @@ class VideoPlayer(GObject.Object): next_track = current + 1 self.playbin.set_property("current-text", next_track) - return True, next_track + 1, self._get_subtitle_lang(next_track) + return True, next_track + 1, self._get_track_lang("text", next_track) - def _get_subtitle_lang(self, track_index: int) -> str: - caps: Gst.TagList | None = self.playbin.emit("get-text-tags", track_index) + def cycle_audio(self) -> tuple[bool, int, str]: + """Cycle through available audio tracks""" + + current = self.playbin.get_property("current-audio") + n_audio = self.playbin.get_property("n-audio") + + if n_audio == 0: + return False, 0, "" + + next_track = (current + 1) % n_audio + self.playbin.set_property("current-audio", next_track) + return True, next_track + 1, self._get_track_lang("audio", next_track) + + def _get_track_lang(self, track_type: str, track_index: int) -> str: + caps: Gst.TagList | None = self.playbin.emit(f"get-{track_type}-tags", track_index) if not caps: return str(track_index)