added extra playback menus

This commit is contained in:
DYefremov
2021-09-25 14:43:43 +03:00
parent e755e9eb6e
commit 5036ecee37
3 changed files with 279 additions and 42 deletions

View File

@@ -52,7 +52,7 @@
<attribute name="label" translatable="yes">Save</attribute>
<attribute name="action">app.on_data_save</attribute>
</item>
<item>
<item>
<attribute name="label" translatable="yes">Save as</attribute>
<attribute name="action">app.on_data_save_as</attribute>
</item>
@@ -191,6 +191,16 @@
<attribute name="label" translatable="yes">Playback</attribute>
<attribute name="action">app.hide_media_bar</attribute>
<attribute name="hidden-when">action-disabled</attribute>
<section>
<item>
<attribute name="label" translatable="yes">Play</attribute>
<attribute name="action">app.on_play</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Stop</attribute>
<attribute name="action">app.on_stop</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Close</attribute>
@@ -238,7 +248,7 @@
<attribute name="label" translatable="yes">Save</attribute>
<attribute name="action">app.on_data_save</attribute>
</item>
<item>
<item>
<attribute name="label" translatable="yes">Save as</attribute>
<attribute name="action">app.on_data_save_as</attribute>
</item>
@@ -255,15 +265,15 @@
<attribute name="action">app.hide_menu_bar</attribute>
<attribute name="hidden-when">action-disabled</attribute>
<section>
<item>
<attribute name="label" translatable="yes">Lock</attribute>
<attribute name="action">app.on_locked</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Hide</attribute>
<attribute name="action">app.on_hide</attribute>
</item>
</section>
<item>
<attribute name="label" translatable="yes">Lock</attribute>
<attribute name="action">app.on_locked</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Hide</attribute>
<attribute name="action">app.on_hide</attribute>
</item>
</section>
</submenu>
<submenu>
<attribute name="label" translatable="yes">View</attribute>
@@ -365,4 +375,75 @@
</item>
</section>
</menu>
<menu id="audio_menu">
<submenu>
<attribute name="label" translatable="yes">Audio</attribute>
<attribute name="action">app.hide_media_bar</attribute>
<attribute name="hidden-when">action-disabled</attribute>
<section>
<submenu id="audio_track_menu">
<attribute name="label" translatable="yes">Audio Track</attribute>
</submenu>
</section>
</submenu>
</menu>
<menu id="video_menu">
<submenu>
<attribute name="label" translatable="yes">Video</attribute>
<attribute name="action">app.hide_media_bar</attribute>
<attribute name="hidden-when">action-disabled</attribute>
<section>
<submenu id="aspect_ratio_menu">
<attribute name="label" translatable="yes">Aspect ratio</attribute>
<item>
<attribute name="label" translatable="yes">Default</attribute>
<attribute name="action">app.on_set_aspect_ratio</attribute>
<attribute name="target"/>
</item>
<item>
<attribute name="label" translatable="yes">16:9</attribute>
<attribute name="action">app.on_set_aspect_ratio</attribute>
<attribute name="target">16:9</attribute>
</item>
<item>
<attribute name="label" translatable="yes">4:3</attribute>
<attribute name="action">app.on_set_aspect_ratio</attribute>
<attribute name="target">4:3</attribute>
</item>
<item>
<attribute name="label" translatable="yes">1:1</attribute>
<attribute name="action">app.on_set_aspect_ratio</attribute>
<attribute name="target">1:1</attribute>
</item>
<item>
<attribute name="label" translatable="yes">16:10</attribute>
<attribute name="action">app.on_set_aspect_ratio</attribute>
<attribute name="target">16:10</attribute>
</item>
<item>
<attribute name="label" translatable="yes">5:4</attribute>
<attribute name="action">app.on_set_aspect_ratio</attribute>
<attribute name="target">5:4</attribute>
</item>
</submenu>
</section>
</submenu>
</menu>
<menu id="subtitle_menu">
<submenu>
<attribute name="label" translatable="yes">Subtitle</attribute>
<attribute name="action">app.hide_media_bar</attribute>
<attribute name="hidden-when">action-disabled</attribute>
<section>
<submenu id="subtitle_track_menu">
<attribute name="label" translatable="yes">Subtitle Track</attribute>
<item>
<attribute name="label" translatable="yes">Default</attribute>
<attribute name="action">app.on_set_subtitle_track</attribute>
<attribute name="target"/>
</item>
</submenu>
</section>
</submenu>
</menu>
</interface>

View File

@@ -16,7 +16,6 @@
<property name="can_focus">False</property>
<child>
<object class="GtkToolButton" id="prev_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Previous stream in the list</property>
<property name="use_underline">True</property>
@@ -33,8 +32,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Play</property>
<property name="action_name">app.on_play</property>
<property name="stock_id">gtk-media-play</property>
<signal name="clicked" handler="on_play" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@@ -46,9 +45,9 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Stop playback</property>
<property name="action_name">app.on_stop</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-media-stop</property>
<signal name="clicked" handler="on_stop" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@@ -57,7 +56,6 @@
</child>
<child>
<object class="GtkToolButton" id="next_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Next stream in the list</property>
<property name="use_underline">True</property>
@@ -76,6 +74,8 @@
<child>
<object class="GtkBox" id="rewind_box">
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="spacing">2</property>
<child>
<object class="GtkLabel" id="current_time_label">
@@ -125,6 +125,91 @@
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolItem" id="extras_item">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="extras_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="spacing">2</property>
<child>
<object class="GtkMenuButton" id="audio_menu_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus_on_click">False</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="audio_menu_button_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Audio Track</property>
<property name="icon_name">multimedia-volume-control</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkMenuButton" id="video_menu_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus_on_click">False</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="video_menu_button_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Aspect ratio</property>
<property name="icon_name">view-restore</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkMenuButton" id="subtitle_menu_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus_on_click">False</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="subtitle_menu_button_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Subtitle Track</property>
<property name="icon_name">format-text-underline</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="full_button">
<property name="visible">True</property>

View File

@@ -29,7 +29,7 @@
""" Additional module for playback. """
from functools import lru_cache
from gi.repository import GLib, GObject
from gi.repository import GLib, GObject, Gio
from app.commons import run_idle, run_with_delay
from app.connections import HttpAPI
@@ -38,7 +38,7 @@ from app.settings import PlayStreamsMode, IS_DARWIN
from app.tools.media import Player
from app.ui.dialogs import get_builder
from app.ui.main_helper import get_iptv_url
from app.ui.uicommons import Gtk, Gdk, UI_RESOURCES_PATH, FavClickMode, Column
from app.ui.uicommons import Gtk, Gdk, UI_RESOURCES_PATH, FavClickMode, Column, IS_GNOME_SESSION
class PlayerBox(Gtk.Box):
@@ -65,12 +65,12 @@ class PlayerBox(Gtk.Box):
self._current_mrl = None
self._full_screen = False
self._playback_window = None
self._audio_track_menu = None
self._subtitle_track_menu = None
self._play_mode = self._app.app_settings.play_streams_mode
handlers = {"on_realize": self.on_realize,
"on_press": self.on_press,
"on_play": self.on_play,
"on_stop": self.on_stop,
"on_next": self.on_next,
"on_previous": self.on_previous,
"on_rewind": self.on_rewind,
@@ -82,18 +82,20 @@ class PlayerBox(Gtk.Box):
self.set_orientation(Gtk.Orientation.VERTICAL)
self._event_box = builder.get_object("event_box")
self.pack_start(self._event_box, True, True, 0)
self.pack_end(builder.get_object("tool_bar"), False, True, 0)
self._scale = builder.get_object("scale")
self._full_time_label = builder.get_object("full_time_label")
self._current_time_label = builder.get_object("current_time_label")
self._rewind_box = builder.get_object("rewind_box")
self._tool_bar = builder.get_object("tool_bar")
self._prev_button = builder.get_object("prev_button")
self._next_button = builder.get_object("next_button")
self._play_button = builder.get_object("play_button")
self._fav_view.bind_property("sensitive", self._prev_button, "sensitive")
self._fav_view.bind_property("sensitive", self._next_button, "sensitive")
if not IS_DARWIN:
self.pack_end(builder.get_object("tool_bar"), False, True, 0)
self._scale = builder.get_object("scale")
self._full_time_label = builder.get_object("full_time_label")
self._current_time_label = builder.get_object("current_time_label")
self._rewind_box = builder.get_object("rewind_box")
self._tool_bar = builder.get_object("tool_bar")
self._prev_button = builder.get_object("prev_button")
self._next_button = builder.get_object("next_button")
self._audio_menu_button = builder.get_object("audio_menu_button")
self._video_menu_button = builder.get_object("video_menu_button")
self._subtitle_menu_button = builder.get_object("subtitle_menu_button")
self._fav_view.bind_property("sensitive", self._prev_button, "sensitive")
self._fav_view.bind_property("sensitive", self._next_button, "sensitive")
self.connect("delete-event", self.on_delete)
self.connect("show", self.set_player_area_size)
@@ -125,23 +127,61 @@ class PlayerBox(Gtk.Box):
settings = self._app.app_settings
try:
self._player = Player.make(settings.stream_lib, settings.play_streams_mode, self._event_box)
self._player.connect("error", self.on_error)
self._player.connect("played", self.on_played)
self._player.connect("position", self.on_time_changed)
except (ImportError, NameError) as e:
self._app.show_error_message(str(e))
return True
else:
self._app.app_window.connect("key-press-event", self.on_key_press)
self.init_playback_elements()
self.emit("play", self._current_mrl)
finally:
if settings.play_streams_mode is PlayStreamsMode.BUILT_IN:
self.set_player_area_size(box)
def on_play(self, button=None):
def init_playback_elements(self):
self._player.connect("error", self.on_error)
self._player.connect("played", self.on_played)
self._player.connect("audio-track", self.on_audio_track_changed)
self._player.connect("subtitle-track", self.on_subtitle_track_changed)
self._app.app_window.connect("key-press-event", self.on_key_press)
builder = get_builder(UI_RESOURCES_PATH + "app_menu.ui")
self._audio_track_menu = builder.get_object("audio_track_menu")
self._subtitle_track_menu = builder.get_object("subtitle_track_menu")
audio_menu = builder.get_object("audio_menu")
video_menu = builder.get_object("video_menu")
subtitle_menu = builder.get_object("subtitle_menu")
if not IS_GNOME_SESSION:
menu_bar = self._app.get_menubar()
menu_bar.insert_section(1, None, audio_menu)
menu_bar.insert_section(2, None, video_menu)
menu_bar.insert_section(3, None, subtitle_menu)
if not IS_DARWIN:
self._player.connect("position", self.on_time_changed)
self._audio_menu_button.set_menu_model(self._audio_track_menu)
self._video_menu_button.set_menu_model(builder.get_object("aspect_ratio_menu"))
self._subtitle_menu_button.set_menu_model(self._subtitle_track_menu)
# Actions.
self._app.set_action("on_play", self.on_play)
self._app.set_action("on_stop", self.on_stop)
audio_track_action = Gio.SimpleAction.new_stateful("on_set_audio_track", GLib.VariantType.new("i"),
GLib.Variant("i", 0))
audio_track_action.connect("activate", self.on_set_audio_track)
self._app.add_action(audio_track_action)
aspect_action = Gio.SimpleAction.new_stateful("on_set_aspect_ratio", GLib.VariantType.new("s"),
GLib.Variant("s", ""))
aspect_action.connect("activate", self.on_set_aspect_ratio)
self._app.add_action(aspect_action)
subtitle_track_action = Gio.SimpleAction.new_stateful("on_set_subtitle_track", GLib.VariantType.new("i"),
GLib.Variant("i", -1))
subtitle_track_action.connect("activate", self.on_set_subtitle_track)
self._app.add_action(subtitle_track_action)
def on_play(self, action=None, value=None):
self.emit("play", None)
def on_stop(self, button=None):
def on_stop(self, action=None, value=None):
self.emit("stop", None)
def on_next(self, button):
@@ -161,7 +201,8 @@ class PlayerBox(Gtk.Box):
self._tool_bar.set_visible(not self._full_screen)
self.emit("playback-full-screen", not self._full_screen)
elif self._playback_window:
self._tool_bar.set_visible(not self._full_screen)
if not IS_DARWIN:
self._tool_bar.set_visible(not self._full_screen)
self._playback_window.fullscreen() if self._full_screen else self._playback_window.unfullscreen()
def on_close(self, action=None, value=None):
@@ -175,6 +216,34 @@ class PlayerBox(Gtk.Box):
return True
@run_with_delay(1)
def on_audio_track_changed(self, player, tracks):
self._audio_track_menu.remove_all()
for t in tracks:
item = Gio.MenuItem.new(t[1], None)
item.set_action_and_target_value("app.on_set_audio_track", GLib.Variant("i", t[0]))
self._audio_track_menu.append_item(item)
@run_with_delay(1)
def on_subtitle_track_changed(self, player, tracks):
self._subtitle_track_menu.remove_all()
for t in tracks:
item = Gio.MenuItem.new(t[1], None)
item.set_action_and_target_value("app.on_set_subtitle_track", GLib.Variant("i", t[0]))
self._subtitle_track_menu.append_item(item)
def on_set_audio_track(self, action, value):
action.set_state(value)
self._player.set_audio_track(value.get_int32())
def on_set_aspect_ratio(self, action, value):
action.set_state(value)
self._player.set_aspect_ratio(value.get_string())
def on_set_subtitle_track(self, action, value):
action.set_state(value)
self._player.set_subtitle_track(value.get_int32())
def on_press(self, area, event):
if event.button == Gdk.BUTTON_PRIMARY:
if event.type == Gdk.EventType.DOUBLE_BUTTON_PRESS:
@@ -192,12 +261,13 @@ class PlayerBox(Gtk.Box):
@run_with_delay(1)
def set_player_action(self):
click_mode = self._app.app_settings.fav_click_mode
self._fav_view.set_sensitive(False)
if self._fav_click_mode is FavClickMode.PLAY:
if click_mode is FavClickMode.PLAY:
self.on_play_service()
elif self._fav_click_mode is FavClickMode.ZAP_PLAY:
elif click_mode is FavClickMode.ZAP_PLAY:
self.on_zap(self.on_watch)
elif self._fav_click_mode is FavClickMode.STREAM:
elif click_mode is FavClickMode.STREAM:
self.on_play_stream()
def update_buttons(self):
@@ -320,7 +390,8 @@ class PlayerBox(Gtk.Box):
def on_played(self, player, duration):
GLib.idle_add(self._fav_view.set_sensitive, True)
self.on_duration_changed(duration)
if not IS_DARWIN:
self.on_duration_changed(duration)
def on_error(self, player, msg):
self._app.show_error_message(msg)