diff --git a/app/tools/media.py b/app/tools/media.py index 718a2293..db4cedb7 100644 --- a/app/tools/media.py +++ b/app/tools/media.py @@ -20,7 +20,9 @@ class Player: log("{}: Load library error: {}".format(__class__.__name__, e)) raise ImportError else: - # initialize GStreamer + self._error_cb = error_cb + self._playing_cb = playing_cb + # Initialize GStreamer. Gst.init(sys.argv) self.STATE = Gst.State self.STAT_RETURN = Gst.StateChangeReturn @@ -31,8 +33,9 @@ class Player: bus = self._player.get_bus() bus.add_signal_watch() - bus.connect("message::error", error_cb) - bus.connect("message::state-changed", playing_cb) + bus.connect("message::error", self.on_error) + bus.connect("message::state-changed", self.on_state_changed) + bus.connect("message::eos", self.on_eos) @classmethod def get_instance(cls, mode, rewind_cb=None, position_cb=None, error_cb=None, playing_cb=None): @@ -44,11 +47,13 @@ class Player: return self._mode def play(self, mrl=None): - self.stop() + self._player.set_state(self.STATE.READY) + if not mrl: + return - if mrl: - self._player.set_property("uri", mrl) + self._player.set_property("uri", mrl) + log("Setting the URL for playback: : {}".format(mrl)) ret = self._player.set_state(self.STATE.PLAYING) if ret == self.STAT_RETURN.FAILURE: @@ -57,9 +62,9 @@ class Player: self._is_playing = True def stop(self): - if self._is_playing: - self._player.set_state(self.STATE.READY) - self._is_playing = False + log("Stop playback...") + self._player.set_state(self.STATE.READY) + self._is_playing = False def pause(self): self._player.set_state(self.STATE.PAUSED) @@ -67,12 +72,11 @@ class Player: def set_time(self, time): pass + @run_task def release(self): - if self._player: - self._is_playing = False - self.stop() - self._player.set_state(self.STATE.NULL) - self.__INSTANCE = None + self._is_playing = False + self._player.set_state(self.STATE.NULL) + self.__INSTANCE = None def set_xwindow(self, xid): self._player.set_xwindow(xid) @@ -106,8 +110,44 @@ class Player: def is_playing(self): return self._is_playing - def set_full_screen(self, full): - self._player.set_fullscreen(full) + def on_error(self, bus, msg): + err, dbg = msg.parse_error() + log(err) + self._error_cb() + + def on_state_changed(self, bus, msg): + if not msg.src == self._player: + # Not from the player. + return + + old_state, new_state, pending = msg.parse_state_changed() + if new_state is self.STATE.PLAYING: + log("Starting playback...") + self._playing_cb() + self.get_stream_info() + + def on_eos(self, bus, msg): + """ Called when an end-of-stream message appears. """ + self._player.set_state(self.STATE.READY) + self._is_playing = False + + def get_stream_info(self): + log("Getting stream info...") + nr_video = self._player.get_property("n-video") + for i in range(nr_video): + # Retrieve the stream's video tags. + tags = self._player.emit("get-video-tags", i) + if tags: + _, cod = tags.get_string("video-codec") + log("Video codec: {}".format(cod or "unknown")) + + nr_audio = self._player.get_property("n-audio") + for i in range(nr_audio): + # Retrieve the stream's video tags. + tags = self._player.emit("get-audio-tags", i) + if tags: + _, cod = tags.get_string("audio-codec") + log("Audio codec: {}".format(cod or "unknown")) class Recorder: diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index f9792bc6..de2d4472 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -1615,7 +1615,9 @@ class Application(Gtk.Application): data_id = ":".join(fav_id_data[:11]) picon_id = "{}_{}_{}_{}_{}_{}_{}_{}_{}_{}.png".format(*fav_id_data[:10]) locked = LOCKED_ICON if data_id in self._blacklist else None - srv = Service(None, None, icon, srv.name, locked, None, None, s_type.name, self._picons.get(picon_id, None), picon_id, None, None, None, None, None, None, None, data_id, fav_id, None) + srv = Service(None, None, icon, srv.name, locked, None, None, s_type.name, + self._picons.get(picon_id, None), picon_id, None, None, None, None, None, None, None, + data_id, fav_id, None) self._services[fav_id] = srv elif s_type is BqServiceType.ALT: self._alt_file.add("{}:{}".format(srv.data, bq_type)) @@ -2392,7 +2394,6 @@ class Application(Gtk.Application): def on_play_stream(self, item=None): self.on_player_play() - @run_idle def on_player_play(self, item=None): path, column = self._fav_view.get_cursor() if path: @@ -2428,9 +2429,9 @@ class Application(Gtk.Application): self.show_playback_window() elif self._playback_window: title = self.get_playback_title() - GLib.idle_add(self._playback_window.set_title, title) - GLib.idle_add(self._player.play, url, priority=GLib.PRIORITY_LOW) - GLib.idle_add(self._playback_window.show) + self._playback_window.set_title(title) + self._playback_window.show() + GLib.idle_add(self._player.play, url) else: self.show_error_dialog("Init player error!") finally: @@ -2442,19 +2443,22 @@ class Application(Gtk.Application): if not self._player_box.get_visible(): self.set_player_area_size(self._player_box) - GLib.idle_add(self._player.play, url, priority=GLib.PRIORITY_LOW) + GLib.idle_add(self._player.play, url) + self._player_box.set_visible(True) def on_player_stop(self, item=None): if self._player: - GLib.idle_add(self._player.stop) + self._player.stop() def on_player_previous(self, item): if self._fav_view.do_move_cursor(self._fav_view, Gtk.MovementStep.DISPLAY_LINES, -1): + self._fav_view.set_sensitive(False) self.set_player_action() def on_player_next(self, item): if self._fav_view.do_move_cursor(self._fav_view, Gtk.MovementStep.DISPLAY_LINES, 1): + self._fav_view.set_sensitive(False) self.set_player_action() @run_with_delay(1) @@ -2500,12 +2504,13 @@ class Application(Gtk.Application): if not self._full_screen and self._player_rewind_box.get_visible(): GLib.idle_add(self._player_current_time_label.set_text, self.get_time_str(t), priority=GLib.PRIORITY_LOW) - def on_player_error(self, bus=None, msg=None): + @run_with_delay(2) + def on_player_error(self): self.set_playback_elms_active() self.show_error_dialog("Can't Playback!") @run_idle - def set_playback_elms_active(self, bus=None, msg=None): + def set_playback_elms_active(self): self._fav_view.set_sensitive(True) self._fav_view.do_grab_focus(self._fav_view) @@ -2533,7 +2538,6 @@ class Application(Gtk.Application): self._player.set_xwindow(widget.get_window().get_xid()) self._player.play(self._current_mrl) finally: - self.set_playback_elms_active() if self._settings.play_streams_mode is PlayStreamsMode.BUILT_IN: self.set_player_area_size(widget) @@ -2567,7 +2571,6 @@ class Application(Gtk.Application): self._player_tool_bar.set_visible(not self._full_screen) self._playback_window.fullscreen() if self._full_screen else self._playback_window.unfullscreen() - @run_idle def update_state_on_full_screen(self, visible): self._main_data_box.set_visible(visible) self._player_tool_bar.set_visible(visible)