From 7f54a39009abc3545e038c6506cd6f5783bc5225 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Fri, 8 Mar 2024 16:44:57 +0100 Subject: [PATCH] load player content on separate thread & add fallback title --- melon/browse/channel.py | 3 + melon/browse/playlist.py | 3 + melon/player/__init__.py | 140 ++++++++++++++++++++++++--------------- po/de.po | 68 +++++++++++-------- po/fa.po | 62 +++++++++++------ po/melon.pot | 58 ++++++++++------ 6 files changed, 213 insertions(+), 121 deletions(-) diff --git a/melon/browse/channel.py b/melon/browse/channel.py index dd0beec..390248c 100644 --- a/melon/browse/channel.py +++ b/melon/browse/channel.py @@ -155,6 +155,9 @@ class BrowseChannelScreen(Adw.NavigationPage): server = get_servers_list()[server_id] self.instance = get_server_instance(server) + # show fallback title + self.set_title(_("Channel")) + self.header_bar = Adw.HeaderBar() self.external_btn = IconButton("","modem-symbolic") self.external_btn.connect("clicked", self.on_open_in_browser) diff --git a/melon/browse/playlist.py b/melon/browse/playlist.py index e782c6f..ee240c4 100644 --- a/melon/browse/playlist.py +++ b/melon/browse/playlist.py @@ -98,6 +98,9 @@ class BrowsePlaylistScreen(Adw.NavigationPage): server = get_servers_list()[server_id] self.instance = get_server_instance(server) + # show fallback title + self.set_title(_("Playlist")) + self.header_bar = Adw.HeaderBar() self.external_btn = IconButton("","modem-symbolic") self.external_btn.connect("clicked", self.on_open_in_browser) diff --git a/melon/player/__init__.py b/melon/player/__init__.py index 0259464..993facd 100644 --- a/melon/player/__init__.py +++ b/melon/player/__init__.py @@ -5,6 +5,7 @@ gi.require_version('Adw', '1') from gi.repository import Gtk, Adw, WebKit, GLib from unidecode import unidecode from gettext import gettext as _ +import threading from melon.servers.utils import get_server_instance, get_servers_list from melon.servers import SearchMode @@ -16,60 +17,16 @@ from melon.models import get_app_settings, notify, add_to_history class PlayerScreen(Adw.NavigationPage): def on_open_in_browser(self, arg): Gtk.UriLauncher.new(uri=self.video.url).launch() - def __init__(self, server_id, video_id, *args, **kwargs): - super().__init__(*args, **kwargs) - self.video_id = video_id - # get instance handle - server = get_servers_list()[server_id] - self.instance = get_server_instance(server) - # obtain video_information - self.video = self.instance.get_video_info(video_id) - # add video to history - add_to_history(self.video) - notify("history_changed") + quality_select = None + def display_info(self): self.set_title(self.video.title) - - self.header_bar = Adw.HeaderBar() - self.external_btn = IconButton("","modem-symbolic") - self.external_btn.connect("clicked", self.on_open_in_browser) - self.header_bar.pack_end(self.external_btn) - - self.toolbar_view = Adw.ToolbarView() - self.toolbar_view.add_top_bar(self.header_bar) - self.set_child(self.toolbar_view) - - self.wrapper = Adw.Clamp() - self.toolbar_view.set_content(self.wrapper) - self.scrollview = Gtk.ScrolledWindow() - self.wrapper.set_child(self.scrollview) - self.box = Gtk.Box(orientation = Gtk.Orientation.VERTICAL) self.scrollview.set_child(self.box) - # video details self.about = Adw.PreferencesGroup() self.about.set_title(unidecode(self.video.title).replace("&","&")) - - # Load the media element in a webview - self.streams = self.instance.get_video_streams(self.video_id) - if len(self.streams) > 0: - self.view = WebKit.WebView() - self.view.set_hexpand(True) - self.view.set_vexpand(True) - default_stream = self.streams[0].quality - self.select_stream(default_stream) - self.box.append(self.view) - # stream selector - pref = Preference( - "quality", - _("Quality"), - _("Video quality"), - PreferenceType.DROPDOWN, - [ unidecode(stream.quality) for stream in self.streams ], - default_stream) - row = PreferenceRow(pref) - row.set_callback(self.select_stream) - self.about.add(row.get_widget()) + if not self.quality_select is None: + self.about.add(self.quality_select) # expandable description field desc_field = Adw.ExpanderRow() @@ -81,11 +38,6 @@ class PlayerScreen(Adw.NavigationPage): self.about.add(desc_field) self.box.append(self.about) - # get channel details - channel = self.instance.get_channel_info(self.video.channel[1]) - if not channel is None: - self.about.add(AdaptiveFeedItem(channel)) - # add to playlist button btn_bookmark = Adw.ActionRow() btn_bookmark.set_title(_("Bookmark")) @@ -97,6 +49,88 @@ class PlayerScreen(Adw.NavigationPage): GLib.Variant("as", [self.video.server, self.video.id])) self.about.add(btn_bookmark) + def display_webview(self): + self.view = WebKit.WebView() + self.view.set_hexpand(True) + self.view.set_vexpand(True) + default_stream = self.streams[0].quality + self.select_stream(default_stream) + self.box.append(self.view) + # stream selector + pref = Preference( + "quality", + _("Quality"), + _("Video quality"), + PreferenceType.DROPDOWN, + [ unidecode(stream.quality) for stream in self.streams ], + default_stream) + row = PreferenceRow(pref) + row.set_callback(self.select_stream) + self.quality_select = row.get_widget() + + channel = None + def display_channel(self): + if not self.channel is None: + self.about.add(AdaptiveFeedItem(self.channel)) + + def background(self, video_id): + # obtain video_information + self.video = self.instance.get_video_info(video_id) + # add video to history + add_to_history(self.video) + GLib.idle_add(notify, "history_changed") + + # Load the media element in a webview + self.streams = self.instance.get_video_streams(self.video_id) + if self.streams: + GLib.idle_add(self.display_webview) + GLib.idle_add(self.display_info) + + # get channel details + channel = self.instance.get_channel_info(self.video.channel[1]) + GLib.idle_add(self.display_channel) + + def __init__(self, server_id, video_id, *args, **kwargs): + super().__init__(*args, **kwargs) + self.video_id = video_id + # get instance handle + server = get_servers_list()[server_id] + self.instance = get_server_instance(server) + + # show fallback title + self.set_title(_("Player")) + + self.header_bar = Adw.HeaderBar() + self.external_btn = IconButton("","modem-symbolic") + self.external_btn.connect("clicked", self.on_open_in_browser) + self.header_bar.pack_end(self.external_btn) + + self.toolbar_view = Adw.ToolbarView() + self.toolbar_view.add_top_bar(self.header_bar) + self.set_child(self.toolbar_view) + + self.wrapper = Adw.Clamp() + self.toolbar_view.set_content(self.wrapper) + + self.scrollview = Gtk.ScrolledWindow() + # show spinner + # will be cleared by display_info + spinner = Gtk.Spinner() + spinner.set_size_request(50, 50) + spinner.start() + cb = Gtk.CenterBox() + cb.set_center_widget(spinner) + self.scrollview.set_child(cb) + + self.wrapper.set_child(self.scrollview) + + self.box = Gtk.Box(orientation = Gtk.Orientation.VERTICAL) + + # start background thread + self.thread = threading.Thread(target=self.background, args=[video_id]) + self.thread.daemon = True + self.thread.start() + def select_stream(self, quality): for stream in self.streams: if stream.quality == quality: diff --git a/po/de.po b/po/de.po index 8c4d609..68b3fc8 100644 --- a/po/de.po +++ b/po/de.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Melon 0.1.2\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-03-03 18:09+0100\n" +"POT-Creation-Date: 2024-03-08 16:47+0100\n" "PO-Revision-Date: 2024-03-01 11:23+0000\n" "Last-Translator: Anonymous \n" "Language-Team: German \n" -"Language-Team: Persian \n" +"Language-Team: Persian \n" "Language: fa\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -74,7 +74,7 @@ msgid "" msgstr "" #: ../melon/browse/__init__.py:18 ../melon/browse/search.py:58 -#: ../melon/browse/server.py:101 ../melon/browse/server.py:125 +#: ../melon/browse/server.py:101 ../melon/browse/server.py:127 #: ../melon/home/history.py:23 ../melon/home/new.py:28 #: ../melon/home/playlists.py:21 ../melon/home/subs.py:20 #: ../melon/importer.py:61 ../melon/playlist/__init__.py:44 @@ -106,30 +106,38 @@ msgstr "" msgid "Global Search" msgstr "" -#: ../melon/browse/channel.py:99 +#: ../melon/browse/channel.py:93 msgid "Subscribe to channel" msgstr "" -#: ../melon/browse/channel.py:100 +#: ../melon/browse/channel.py:94 msgid "Add latest uploads to home feed" msgstr "افزودن آخرین بارگذاری‌ها به صفحه‌خانه" -#: ../melon/browse/channel.py:127 +#: ../melon/browse/channel.py:106 msgid "Channel feed" msgstr "خوراک کانال" -#: ../melon/browse/channel.py:128 +#: ../melon/browse/channel.py:107 msgid "This channel provides multiple feeds, choose which one to view" msgstr "" -#: ../melon/browse/playlist.py:61 ../melon/player/__init__.py:91 +#: ../melon/browse/channel.py:159 +msgid "Channel" +msgstr "" + +#: ../melon/browse/playlist.py:47 ../melon/player/__init__.py:43 msgid "Bookmark" msgstr "نشانک گذاری" -#: ../melon/browse/playlist.py:62 +#: ../melon/browse/playlist.py:48 msgid "Add Playlist to your local playlist collection" msgstr "افزودن این لیست‌پخش به مجموعه لیست‌پخش های محلی" +#: ../melon/browse/playlist.py:102 +msgid "Playlist" +msgstr "" + #: ../melon/browse/search.py:44 msgid "No results" msgstr "" @@ -179,7 +187,7 @@ msgstr "" msgid "Try using a different query" msgstr "" -#: ../melon/browse/server.py:126 +#: ../melon/browse/server.py:128 msgid "This feed is empty" msgstr "" @@ -191,14 +199,22 @@ msgstr "" msgid "Browse Servers" msgstr "جستجو در کارساز ها" -#: ../melon/home/history.py:35 ../melon/home/history.py:73 +#: ../melon/home/history.py:36 ../melon/home/history.py:117 msgid "History" msgstr "" -#: ../melon/home/history.py:36 +#: ../melon/home/history.py:37 msgid "These are the videos you opened in the past" msgstr "" +#: ../melon/home/history.py:76 +msgid "Show more" +msgstr "" + +#: ../melon/home/history.py:77 +msgid "Load older videos" +msgstr "" + #: ../melon/home/new.py:22 msgid "Refresh" msgstr "" @@ -282,22 +298,26 @@ msgstr "" msgid "There are no available importer methods" msgstr "" -#: ../melon/player/__init__.py:65 +#: ../melon/player/__init__.py:33 +msgid "Description" +msgstr "" + +#: ../melon/player/__init__.py:44 +msgid "Add this video to a playlist" +msgstr "افزودن این ویدئو به لیست‌پخش" + +#: ../melon/player/__init__.py:62 msgid "Quality" msgstr "" -#: ../melon/player/__init__.py:66 +#: ../melon/player/__init__.py:63 msgid "Video quality" msgstr "" -#: ../melon/player/__init__.py:76 -msgid "Description" +#: ../melon/player/__init__.py:101 +msgid "Player" msgstr "" -#: ../melon/player/__init__.py:92 -msgid "Add this video to a playlist" -msgstr "افزودن این ویدئو به لیست‌پخش" - #: ../melon/playlist/__init__.py:39 msgid "Edit" msgstr "" diff --git a/po/melon.pot b/po/melon.pot index 02da3e8..bb597bc 100644 --- a/po/melon.pot +++ b/po/melon.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Melon 0.1.2\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-03-03 18:09+0100\n" +"POT-Creation-Date: 2024-03-08 16:47+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -73,7 +73,7 @@ msgid "" msgstr "" #: ../melon/browse/__init__.py:18 ../melon/browse/search.py:58 -#: ../melon/browse/server.py:101 ../melon/browse/server.py:125 +#: ../melon/browse/server.py:101 ../melon/browse/server.py:127 #: ../melon/home/history.py:23 ../melon/home/new.py:28 #: ../melon/home/playlists.py:21 ../melon/home/subs.py:20 #: ../melon/importer.py:61 ../melon/playlist/__init__.py:44 @@ -105,30 +105,38 @@ msgstr "" msgid "Global Search" msgstr "" -#: ../melon/browse/channel.py:99 +#: ../melon/browse/channel.py:93 msgid "Subscribe to channel" msgstr "" -#: ../melon/browse/channel.py:100 +#: ../melon/browse/channel.py:94 msgid "Add latest uploads to home feed" msgstr "" -#: ../melon/browse/channel.py:127 +#: ../melon/browse/channel.py:106 msgid "Channel feed" msgstr "" -#: ../melon/browse/channel.py:128 +#: ../melon/browse/channel.py:107 msgid "This channel provides multiple feeds, choose which one to view" msgstr "" -#: ../melon/browse/playlist.py:61 ../melon/player/__init__.py:91 +#: ../melon/browse/channel.py:159 +msgid "Channel" +msgstr "" + +#: ../melon/browse/playlist.py:47 ../melon/player/__init__.py:43 msgid "Bookmark" msgstr "" -#: ../melon/browse/playlist.py:62 +#: ../melon/browse/playlist.py:48 msgid "Add Playlist to your local playlist collection" msgstr "" +#: ../melon/browse/playlist.py:102 +msgid "Playlist" +msgstr "" + #: ../melon/browse/search.py:44 msgid "No results" msgstr "" @@ -178,7 +186,7 @@ msgstr "" msgid "Try using a different query" msgstr "" -#: ../melon/browse/server.py:126 +#: ../melon/browse/server.py:128 msgid "This feed is empty" msgstr "" @@ -190,14 +198,22 @@ msgstr "" msgid "Browse Servers" msgstr "" -#: ../melon/home/history.py:35 ../melon/home/history.py:73 +#: ../melon/home/history.py:36 ../melon/home/history.py:117 msgid "History" msgstr "" -#: ../melon/home/history.py:36 +#: ../melon/home/history.py:37 msgid "These are the videos you opened in the past" msgstr "" +#: ../melon/home/history.py:76 +msgid "Show more" +msgstr "" + +#: ../melon/home/history.py:77 +msgid "Load older videos" +msgstr "" + #: ../melon/home/new.py:22 msgid "Refresh" msgstr "" @@ -281,20 +297,24 @@ msgstr "" msgid "There are no available importer methods" msgstr "" -#: ../melon/player/__init__.py:65 -msgid "Quality" +#: ../melon/player/__init__.py:33 +msgid "Description" msgstr "" -#: ../melon/player/__init__.py:66 -msgid "Video quality" +#: ../melon/player/__init__.py:44 +msgid "Add this video to a playlist" msgstr "" -#: ../melon/player/__init__.py:76 -msgid "Description" +#: ../melon/player/__init__.py:62 +msgid "Quality" msgstr "" -#: ../melon/player/__init__.py:92 -msgid "Add this video to a playlist" +#: ../melon/player/__init__.py:63 +msgid "Video quality" +msgstr "" + +#: ../melon/player/__init__.py:101 +msgid "Player" msgstr "" #: ../melon/playlist/__init__.py:39 -- 2.38.5