~comcloudway/melon

7f54a39009abc3545e038c6506cd6f5783bc5225 — Jakob Meier 6 months ago b554a97
load player content on separate thread & add fallback title
6 files changed, 213 insertions(+), 121 deletions(-)

M melon/browse/channel.py
M melon/browse/playlist.py
M melon/player/__init__.py
M po/de.po
M po/fa.po
M po/melon.pot
M melon/browse/channel.py => melon/browse/channel.py +3 -0
@@ 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)

M melon/browse/playlist.py => melon/browse/playlist.py +3 -0
@@ 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)

M melon/player/__init__.py => melon/player/__init__.py +87 -53
@@ 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:

M po/de.po => po/de.po +40 -28
@@ 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 <noreply@weblate.org>\n"
"Language-Team: German <https://translate.codeberg.org/projects/melon/melon-"


@@ 79,7 79,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


@@ 112,30 112,38 @@ msgstr "Dienste"
msgid "Global Search"
msgstr "Globale Suche"

#: ../melon/browse/channel.py:99
#: ../melon/browse/channel.py:93
msgid "Subscribe to channel"
msgstr "Kanal abonnieren"

#: ../melon/browse/channel.py:100
#: ../melon/browse/channel.py:94
msgid "Add latest uploads to home feed"
msgstr "Zeige neue Videos im Home-Feed an"

#: ../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 "Merken"

#: ../melon/browse/playlist.py:62
#: ../melon/browse/playlist.py:48
msgid "Add Playlist to your local playlist collection"
msgstr "Wiedergabeliste zur lokalen Sammlung hinzufügen"

#: ../melon/browse/playlist.py:102
msgid "Playlist"
msgstr ""

#: ../melon/browse/search.py:44
msgid "No results"
msgstr "Keine Ergebnisse"


@@ 186,7 194,7 @@ msgstr "Suche nach einem Suchbegriff"
msgid "Try using a different query"
msgstr "Versuche nach einem anderen Begriff zu suchen"

#: ../melon/browse/server.py:126
#: ../melon/browse/server.py:128
msgid "This feed is empty"
msgstr ""



@@ 198,14 206,22 @@ msgstr "Du hast noch keine Videos geschaut"
msgid "Browse Servers"
msgstr "Dienste durchsuchen"

#: ../melon/home/history.py:35 ../melon/home/history.py:73
#: ../melon/home/history.py:36 ../melon/home/history.py:117
msgid "History"
msgstr "Verlauf"

#: ../melon/home/history.py:36
#: ../melon/home/history.py:37
msgid "These are the videos you opened in the past"
msgstr "Diese Videos hast du in der Vergangenheit geöffnet"

#: ../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 "Aktualisieren"


@@ 294,21 310,25 @@ msgstr "Die folgenden Import-Methoden wurden gefunden"
msgid "There are no available importer methods"
msgstr "Es gibt keine verfügbaren Import-Methoden"

#: ../melon/player/__init__.py:65
#: ../melon/player/__init__.py:33
msgid "Description"
msgstr "Beschreibung"

#: ../melon/player/__init__.py:44
msgid "Add this video to a playlist"
msgstr "Füge dieses Video einer Wiedergabeliste hinzu"

#: ../melon/player/__init__.py:62
msgid "Quality"
msgstr "Auflösung"

#: ../melon/player/__init__.py:66
#: ../melon/player/__init__.py:63
msgid "Video quality"
msgstr "Auflösung"

#: ../melon/player/__init__.py:76
msgid "Description"
msgstr "Beschreibung"

#: ../melon/player/__init__.py:92
msgid "Add this video to a playlist"
msgstr "Füge dieses Video einer Wiedergabeliste hinzu"
#: ../melon/player/__init__.py:101
msgid "Player"
msgstr ""

#: ../melon/playlist/__init__.py:39
msgid "Edit"


@@ 687,13 707,5 @@ msgstr "Eintrag von der Liste entfernen"
msgid "Stream videos on the go"
msgstr "Videos unterwegs streamen"

#: ../melon/playlist/__init__.py:117
msgid "Close without chaning anything"
msgstr ""

#: ../melon/playlist/__init__.py:150
msgid "Do you really wan't to delete this playlist?"
msgstr ""

#~ msgid "Playlist Name"
#~ msgstr "Name der Wiedergabeliste"

M po/fa.po => po/fa.po +41 -21
@@ 7,11 7,11 @@ 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-05 05:13+0000\n"
"Last-Translator: sohrabbehdani <behdanisohrab@gmail.com>\n"
"Language-Team: Persian <https://translate.codeberg.org/projects/melon/"
"melon-app/fa/>\n"
"Language-Team: Persian <https://translate.codeberg.org/projects/melon/melon-"
"app/fa/>\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 ""

M po/melon.pot => po/melon.pot +39 -19
@@ 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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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