mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-30 16:02:00 +02:00
Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7a508fef39 | ||
|
d465d9f150 | ||
|
5e4dfb322c | ||
|
0c561ab4b3 | ||
|
46ce261524 | ||
|
50aac8cdd8 | ||
|
810aea476f | ||
|
24905f1d60 | ||
|
82e3c9a52f | ||
|
654b8aaf60 | ||
|
3c0e33e4a4 | ||
|
d2df1c3bd8 | ||
|
af24073590 | ||
|
44cee14eb2 | ||
|
b853685dd4 | ||
|
15461dd38a | ||
|
1c1989bc32 | ||
|
e9c9ae073f |
@@ -10,6 +10,9 @@ scrolledwindow scrollbar.vertical slider {
|
||||
}
|
||||
|
||||
/* Adwaita is missing osd ListBox */
|
||||
.clapperplaylist {
|
||||
background: none;
|
||||
}
|
||||
.clapperplaylist row {
|
||||
border-radius: 5px;
|
||||
}
|
||||
@@ -28,9 +31,6 @@ scrolledwindow scrollbar.vertical slider {
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
.osd .clapperplaylist {
|
||||
background: none;
|
||||
}
|
||||
.osd .clapperplaylist row image {
|
||||
-gtk-icon-shadow: none;
|
||||
}
|
||||
@@ -223,6 +223,9 @@ scale trough slider {
|
||||
.fullscreen.tvmode .positionscale marks.bottom {
|
||||
margin-top: 2px;
|
||||
}
|
||||
.fullscreen.tvmode .positionscale trough {
|
||||
border-radius: 3px;
|
||||
}
|
||||
.fullscreen.tvmode .positionscale trough highlight {
|
||||
border-radius: 3px;
|
||||
min-height: 20px;
|
||||
|
@@ -48,6 +48,34 @@
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<releases>
|
||||
<release version="0.4.1" date="2021-12-20">
|
||||
<description>
|
||||
<p>Fixes:</p>
|
||||
<ul>
|
||||
<li>Compatibility with more recent libadwaita versions</li>
|
||||
<li>Toggle mute with M button alone</li>
|
||||
<li>Allow handling YouTube with external GStreamer plugins</li>
|
||||
<li>Fix catching errors when reading clipboard</li>
|
||||
<li>Fix missing translator-credits</li>
|
||||
<li>Fix missing gio-unix-2.0 dep</li>
|
||||
<li>Fix playback pausing when entering fullscreen with touchscreen</li>
|
||||
<li>Fix GST_PLUGIN_FEATURE_RANK env usage</li>
|
||||
<li>Fix video/audio decoder change detection</li>
|
||||
<li>Merge global video tags instead replacing them</li>
|
||||
<li>Few other misc bug fixes</li>
|
||||
</ul>
|
||||
<p>New translations:</p>
|
||||
<ul>
|
||||
<li>Chinese Simplified</li>
|
||||
<li>Czech</li>
|
||||
<li>Hungarian</li>
|
||||
<li>Portuguese</li>
|
||||
<li>Portuguese, Brazilian</li>
|
||||
<li>Russian</li>
|
||||
<li>Spanish</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.4.0" date="2021-09-12">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
|
291
lib/gst/clapper/gstclapper.c
vendored
291
lib/gst/clapper/gstclapper.c
vendored
@@ -253,6 +253,9 @@ static void gst_clapper_audio_info_update (GstClapper * self,
|
||||
static void gst_clapper_subtitle_info_update (GstClapper * self,
|
||||
GstClapperStreamInfo * stream_info);
|
||||
|
||||
static gboolean find_active_decoder_with_stream_id (GstClapper * self,
|
||||
GstElementFactoryListType type, const gchar * stream_id);
|
||||
|
||||
/* For playbin3 */
|
||||
static void gst_clapper_streams_info_create_from_collection (GstClapper * self,
|
||||
GstClapperMediaInfo * media_info, GstStreamCollection * collection);
|
||||
@@ -1862,6 +1865,15 @@ media_info_update (GstClapper * self, GstClapperMediaInfo * info)
|
||||
"image_sample: %p", info->title, info->container, info->image_sample);
|
||||
}
|
||||
|
||||
static void
|
||||
merge_tags (GstTagList **my_tags, GstTagList *tags)
|
||||
{
|
||||
if (*my_tags)
|
||||
gst_tag_list_insert (*my_tags, tags, GST_TAG_MERGE_REPLACE);
|
||||
else
|
||||
*my_tags = gst_tag_list_ref (tags);
|
||||
}
|
||||
|
||||
static void
|
||||
tags_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg, gpointer user_data)
|
||||
{
|
||||
@@ -1877,17 +1889,12 @@ tags_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg, gpointer user_data)
|
||||
if (gst_tag_list_get_scope (tags) == GST_TAG_SCOPE_GLOBAL) {
|
||||
g_mutex_lock (&self->lock);
|
||||
if (self->media_info) {
|
||||
if (self->media_info->tags)
|
||||
gst_tag_list_unref (self->media_info->tags);
|
||||
self->media_info->tags = gst_tag_list_ref (tags);
|
||||
merge_tags (&self->media_info->tags, tags);
|
||||
media_info_update (self, self->media_info);
|
||||
g_mutex_unlock (&self->lock);
|
||||
} else {
|
||||
if (self->global_tags)
|
||||
gst_tag_list_unref (self->global_tags);
|
||||
self->global_tags = gst_tag_list_ref (tags);
|
||||
g_mutex_unlock (&self->lock);
|
||||
merge_tags (&self->global_tags, tags);
|
||||
}
|
||||
g_mutex_unlock (&self->lock);
|
||||
}
|
||||
|
||||
gst_tag_list_unref (tags);
|
||||
@@ -2050,6 +2057,7 @@ streams_selected_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg,
|
||||
{
|
||||
GstClapper *self = GST_CLAPPER (user_data);
|
||||
GstStreamCollection *collection = NULL;
|
||||
gchar *video_sid, *audio_sid;
|
||||
guint i, len;
|
||||
|
||||
gst_message_parse_streams_selected (msg, &collection);
|
||||
@@ -2098,7 +2106,22 @@ streams_selected_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg,
|
||||
|
||||
*current_sid = g_strdup (stream_id);
|
||||
}
|
||||
|
||||
video_sid = g_strdup (self->video_sid);
|
||||
audio_sid = g_strdup (self->audio_sid);
|
||||
|
||||
g_mutex_unlock (&self->lock);
|
||||
|
||||
if (video_sid) {
|
||||
find_active_decoder_with_stream_id (self, GST_ELEMENT_FACTORY_TYPE_DECODER
|
||||
| GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO, video_sid);
|
||||
g_free (video_sid);
|
||||
}
|
||||
if (audio_sid) {
|
||||
find_active_decoder_with_stream_id (self, GST_ELEMENT_FACTORY_TYPE_DECODER
|
||||
| GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO, audio_sid);
|
||||
g_free (audio_sid);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -3009,11 +3032,12 @@ decoder_changed_signal_data_free (DecoderChangedSignalData * data)
|
||||
|
||||
static void
|
||||
emit_decoder_changed (GstClapper * self, gchar * decoder_name,
|
||||
gboolean is_video)
|
||||
GstElementFactoryListType type)
|
||||
{
|
||||
GstClapperSignalDispatcherFunc func = NULL;
|
||||
|
||||
if (is_video) {
|
||||
if ((type & GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO) ==
|
||||
GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO) {
|
||||
if (g_signal_handler_find (self, G_SIGNAL_MATCH_ID,
|
||||
signals[SIGNAL_VIDEO_DECODER_CHANGED], 0, NULL, NULL, NULL) != 0 &&
|
||||
g_strcmp0 (self->last_vdecoder, decoder_name) != 0) {
|
||||
@@ -3021,7 +3045,8 @@ emit_decoder_changed (GstClapper * self, gchar * decoder_name,
|
||||
g_free (self->last_vdecoder);
|
||||
self->last_vdecoder = g_strdup (decoder_name);
|
||||
}
|
||||
} else {
|
||||
} else if ((type & GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO) ==
|
||||
GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO) {
|
||||
if (g_signal_handler_find (self, G_SIGNAL_MATCH_ID,
|
||||
signals[SIGNAL_AUDIO_DECODER_CHANGED], 0, NULL, NULL, NULL) != 0 &&
|
||||
g_strcmp0 (self->last_adecoder, decoder_name) != 0) {
|
||||
@@ -3042,6 +3067,138 @@ emit_decoder_changed (GstClapper * self, gchar * decoder_name,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
iterate_decoder_pads (GstClapper * self, GstElement * element,
|
||||
const gchar * stream_id, GstElementFactoryListType type)
|
||||
{
|
||||
GstIterator *iter;
|
||||
GValue value = { 0, };
|
||||
gboolean found = FALSE;
|
||||
|
||||
iter = gst_element_iterate_src_pads (element);
|
||||
|
||||
while (gst_iterator_next (iter, &value) == GST_ITERATOR_OK) {
|
||||
GstPad *decoder_pad = g_value_get_object (&value);
|
||||
gchar *decoder_stream_id = gst_pad_get_stream_id (decoder_pad);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Decoder stream: %s", decoder_stream_id);
|
||||
|
||||
/* In case of playbin3, pad may not be active yet */
|
||||
if ((found = (g_strcmp0 (decoder_stream_id, stream_id) == 0
|
||||
|| (!decoder_stream_id && self->use_playbin3)))) {
|
||||
GstElementFactory *factory;
|
||||
gchar *plugin_name;
|
||||
|
||||
factory = gst_element_get_factory (element);
|
||||
plugin_name = gst_object_get_name (GST_OBJECT_CAST (factory));
|
||||
|
||||
if (plugin_name) {
|
||||
GST_DEBUG_OBJECT (self, "Found decoder: %s", plugin_name);
|
||||
emit_decoder_changed (self, plugin_name, type);
|
||||
|
||||
g_free (plugin_name);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (decoder_stream_id);
|
||||
g_value_unset (&value);
|
||||
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
gst_iterator_free (iter);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
find_active_decoder_with_stream_id (GstClapper * self, GstElementFactoryListType type,
|
||||
const gchar * stream_id)
|
||||
{
|
||||
GstIterator *iter;
|
||||
GValue value = { 0, };
|
||||
gboolean found = FALSE;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Searching for decoder with stream: %s", stream_id);
|
||||
|
||||
iter = gst_bin_iterate_recurse (GST_BIN (self->playbin));
|
||||
|
||||
while (gst_iterator_next (iter, &value) == GST_ITERATOR_OK) {
|
||||
GstElement *element = g_value_get_object (&value);
|
||||
GstElementFactory *factory = gst_element_get_factory (element);
|
||||
|
||||
if (factory && gst_element_factory_list_is_type (factory, type))
|
||||
found = iterate_decoder_pads (self, element, stream_id, type);
|
||||
|
||||
g_value_unset (&value);
|
||||
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
gst_iterator_free (iter);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static void
|
||||
update_current_decoder (GstClapper *self, GstElementFactoryListType type)
|
||||
{
|
||||
GstIterator *iter;
|
||||
GValue value = { 0, };
|
||||
|
||||
iter = gst_bin_iterate_all_by_element_factory_name (
|
||||
GST_BIN (self->playbin), "input-selector");
|
||||
|
||||
while (gst_iterator_next (iter, &value) == GST_ITERATOR_OK) {
|
||||
GstElement *element = g_value_get_object (&value);
|
||||
GstPad *active_pad;
|
||||
gboolean found = FALSE;
|
||||
|
||||
g_object_get (G_OBJECT (element), "active-pad", &active_pad, NULL);
|
||||
|
||||
if (active_pad) {
|
||||
gchar *stream_id;
|
||||
|
||||
stream_id = gst_pad_get_stream_id (active_pad);
|
||||
gst_object_unref (active_pad);
|
||||
|
||||
if (stream_id) {
|
||||
found = find_active_decoder_with_stream_id (self, type, stream_id);
|
||||
g_free (stream_id);
|
||||
}
|
||||
}
|
||||
|
||||
g_value_unset (&value);
|
||||
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
gst_iterator_free (iter);
|
||||
}
|
||||
|
||||
static void
|
||||
current_video_notify_cb (G_GNUC_UNUSED GObject * obj, G_GNUC_UNUSED GParamSpec * pspec,
|
||||
GstClapper * self)
|
||||
{
|
||||
GstElementFactoryListType type = GST_ELEMENT_FACTORY_TYPE_DECODER
|
||||
| GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO;
|
||||
|
||||
update_current_decoder (self, type);
|
||||
}
|
||||
|
||||
static void
|
||||
current_audio_notify_cb (G_GNUC_UNUSED GObject * obj, G_GNUC_UNUSED GParamSpec * pspec,
|
||||
GstClapper * self)
|
||||
{
|
||||
GstElementFactoryListType type = GST_ELEMENT_FACTORY_TYPE_DECODER
|
||||
| GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO;
|
||||
|
||||
update_current_decoder (self, type);
|
||||
}
|
||||
|
||||
static void
|
||||
element_setup_cb (GstElement * playbin, GstElement * element, GstClapper * self)
|
||||
{
|
||||
@@ -3054,13 +3211,6 @@ element_setup_cb (GstElement * playbin, GstElement * element, GstClapper * self)
|
||||
if (plugin_name) {
|
||||
GST_INFO_OBJECT (self, "Plugin setup: %s", plugin_name);
|
||||
|
||||
if (gst_element_factory_list_is_type (factory,
|
||||
GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO))
|
||||
emit_decoder_changed (self, plugin_name, TRUE);
|
||||
else if (gst_element_factory_list_is_type (factory,
|
||||
GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO))
|
||||
emit_decoder_changed (self, plugin_name, FALSE);
|
||||
|
||||
/* TODO: Set plugin props */
|
||||
}
|
||||
g_free (plugin_name);
|
||||
@@ -3229,6 +3379,11 @@ gst_clapper_main (gpointer data)
|
||||
G_CALLBACK (audio_tags_changed_cb), self);
|
||||
g_signal_connect (self->playbin, "text-tags-changed",
|
||||
G_CALLBACK (subtitle_tags_changed_cb), self);
|
||||
|
||||
g_signal_connect (self->playbin, "notify::current-video",
|
||||
G_CALLBACK (current_video_notify_cb), self);
|
||||
g_signal_connect (self->playbin, "notify::current-audio",
|
||||
G_CALLBACK (current_audio_notify_cb), self);
|
||||
}
|
||||
|
||||
g_signal_connect (self->playbin, "notify::volume",
|
||||
@@ -3324,6 +3479,103 @@ gst_clapper_has_plugin_with_features (const gchar * name)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_feature_name (gchar * str, const gchar ** feature)
|
||||
{
|
||||
if (!str)
|
||||
return FALSE;
|
||||
|
||||
g_strstrip (str);
|
||||
|
||||
if (str[0] != '\0') {
|
||||
*feature = str;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_feature_rank (gchar * str, GstRank * rank)
|
||||
{
|
||||
if (!str)
|
||||
return FALSE;
|
||||
|
||||
g_strstrip (str);
|
||||
|
||||
if (g_ascii_isdigit (str[0])) {
|
||||
unsigned long l;
|
||||
char *endptr;
|
||||
l = strtoul (str, &endptr, 10);
|
||||
if (endptr > str && endptr[0] == 0) {
|
||||
*rank = (GstRank) l;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
} else if (g_ascii_strcasecmp (str, "NONE") == 0) {
|
||||
*rank = GST_RANK_NONE;
|
||||
} else if (g_ascii_strcasecmp (str, "MARGINAL") == 0) {
|
||||
*rank = GST_RANK_MARGINAL;
|
||||
} else if (g_ascii_strcasecmp (str, "SECONDARY") == 0) {
|
||||
*rank = GST_RANK_SECONDARY;
|
||||
} else if (g_ascii_strcasecmp (str, "PRIMARY") == 0) {
|
||||
*rank = GST_RANK_PRIMARY;
|
||||
} else if (g_ascii_strcasecmp (str, "MAX") == 0) {
|
||||
*rank = (GstRank) G_MAXINT;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_env_feature_rank_update (void)
|
||||
{
|
||||
const gchar *env;
|
||||
gchar **split, **walk;
|
||||
|
||||
env = g_getenv ("GST_PLUGIN_FEATURE_RANK");
|
||||
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
split = g_strsplit (env, ",", 0);
|
||||
|
||||
for (walk = split; *walk; walk++) {
|
||||
if (strchr (*walk, ':')) {
|
||||
gchar **values;
|
||||
|
||||
values = g_strsplit (*walk, ":", 2);
|
||||
if (values[0] && values[1]) {
|
||||
GstRank rank;
|
||||
const gchar *name;
|
||||
|
||||
if (parse_feature_name (values[0], &name)
|
||||
&& parse_feature_rank (values[1], &rank)) {
|
||||
GstPluginFeature *feature;
|
||||
|
||||
feature = gst_registry_find_feature (gst_registry_get (), name,
|
||||
GST_TYPE_ELEMENT_FACTORY);
|
||||
if (feature) {
|
||||
GstRank old_rank;
|
||||
|
||||
old_rank = gst_plugin_feature_get_rank (feature);
|
||||
if (old_rank != rank) {
|
||||
gst_plugin_feature_set_rank (feature, rank);
|
||||
GST_DEBUG ("Updated rank from env: %i -> %i for %s", old_rank, rank, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev (values);
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev (split);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_prepare_gstreamer (void)
|
||||
{
|
||||
@@ -3346,6 +3598,9 @@ gst_clapper_prepare_gstreamer (void)
|
||||
gst_clapper_set_feature_rank ("v4l2slvp8dec", GST_RANK_NONE);
|
||||
}
|
||||
|
||||
/* After setting defaults, update them from ENV */
|
||||
_env_feature_rank_update ();
|
||||
|
||||
gst_clapper_gstreamer_prepared = TRUE;
|
||||
GST_DEBUG ("GStreamer plugins prepared");
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
project('com.github.rafostar.Clapper', 'c', 'cpp',
|
||||
version: '0.4.0',
|
||||
version: '0.4.1',
|
||||
meson_version: '>= 0.50.0',
|
||||
license: 'GPL-3.0-or-later',
|
||||
default_options: [
|
||||
|
@@ -33,6 +33,7 @@
|
||||
"flathub/lib/libass.json",
|
||||
"flathub/lib/ffmpeg.json",
|
||||
"testing/gstreamer.json",
|
||||
"testing/gtuber.json",
|
||||
{
|
||||
"name": "clapper",
|
||||
"buildsystem": "meson",
|
||||
|
@@ -42,6 +42,7 @@
|
||||
"flathub/gstreamer-1.0/gstreamer-vaapi.json",
|
||||
"flathub/lib/gtk4.json",
|
||||
"flathub/lib/libadwaita.json",
|
||||
"testing/gtuber.json",
|
||||
{
|
||||
"name": "clapper",
|
||||
"buildsystem": "meson",
|
||||
|
@@ -23,6 +23,7 @@
|
||||
"-Dintrospection=enabled",
|
||||
"-Ddoc=disabled",
|
||||
"-Dgtk_doc=disabled",
|
||||
"-Dgpl=enabled",
|
||||
|
||||
"-Dgstreamer:benchmarks=disabled",
|
||||
"-Dgstreamer:gobject-cast-checks=disabled",
|
||||
|
20
pkgs/flatpak/testing/gtuber.json
Normal file
20
pkgs/flatpak/testing/gtuber.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "gtuber",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"-Dintrospection=disabled",
|
||||
"-Dvapi=disabled",
|
||||
"-Dgst-gtuber=enabled"
|
||||
],
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"/lib/pkgconfig"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/Rafostar/gtuber.git",
|
||||
"branch": "main"
|
||||
}
|
||||
]
|
||||
}
|
@@ -26,7 +26,7 @@
|
||||
%global glib2_version 2.56.0
|
||||
|
||||
Name: clapper
|
||||
Version: 0.4.0
|
||||
Version: 0.4.1
|
||||
Release: 1%{?dist}
|
||||
Summary: Simple and modern GNOME media player
|
||||
|
||||
@@ -129,6 +129,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
|
||||
%{_libdir}/%{appname}/
|
||||
|
||||
%changelog
|
||||
* Mon Dec 20 2021 Rafostar <rafostar.github@gmail.com> - 0.4.1-1
|
||||
- New version
|
||||
|
||||
* Sun Sep 12 2021 Rafostar <rafostar.github@gmail.com> - 0.4.0-1
|
||||
- New version
|
||||
|
||||
|
@@ -1 +1 @@
|
||||
ca cs de es hu it nl pl pt_BR ru zh_CN
|
||||
ca cs de es hu it nl pl pt pt_BR ru zh_CN
|
||||
|
44
po/pt.po
44
po/pt.po
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:25\n"
|
||||
"PO-Revision-Date: 2021-10-21 00:29\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Portuguese\n"
|
||||
"Language: pt_PT\n"
|
||||
@@ -19,88 +19,88 @@ msgstr ""
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgstr ""
|
||||
msgstr "Abrir Arquivos..."
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgstr ""
|
||||
msgstr "Abrir URI..."
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
msgstr "Preferências"
|
||||
|
||||
#: ui/clapper.ui:20
|
||||
msgid "Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Atalhos"
|
||||
|
||||
#: ui/clapper.ui:26
|
||||
msgid "About Clapper"
|
||||
msgstr ""
|
||||
msgstr "Sobre o Clapper"
|
||||
|
||||
#: ui/elapsed-time-button.ui:27
|
||||
msgid "Speed"
|
||||
msgstr ""
|
||||
msgstr "Velocidade"
|
||||
|
||||
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:83
|
||||
#: ui/preferences-window.ui:215
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
msgstr "Predefinido"
|
||||
|
||||
#: ui/help-overlay.ui:10 ui/preferences-window.ui:12
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
msgstr "Geral"
|
||||
|
||||
#: ui/help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Mostrar atalhos"
|
||||
|
||||
#: ui/help-overlay.ui:19
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Mudar modo de ecrã"
|
||||
|
||||
#: ui/help-overlay.ui:20
|
||||
msgid "Double tap | Double click"
|
||||
msgstr ""
|
||||
msgstr "Toque duplo duplo Clique duplo"
|
||||
|
||||
#: ui/help-overlay.ui:26
|
||||
msgid "Leave fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Sair do modo de ecrã completo"
|
||||
|
||||
#: ui/help-overlay.ui:32
|
||||
msgid "Reveal OSD (fullscreen only)"
|
||||
msgstr ""
|
||||
msgstr "Revelar OSD (apenas em tela cheia)"
|
||||
|
||||
#: ui/help-overlay.ui:33
|
||||
msgid "Tap"
|
||||
msgstr ""
|
||||
msgstr "Tocar"
|
||||
|
||||
#: ui/help-overlay.ui:39
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
msgstr "Sair"
|
||||
|
||||
#: ui/help-overlay.ui:47
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
msgstr "Multimédia"
|
||||
|
||||
#: ui/help-overlay.ui:50
|
||||
msgid "Open files"
|
||||
msgstr ""
|
||||
msgstr "Abrir ficheiro"
|
||||
|
||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||
msgid "Open URI"
|
||||
msgstr ""
|
||||
msgstr "Abrir URI"
|
||||
|
||||
#: ui/help-overlay.ui:64
|
||||
msgid "Playlist"
|
||||
msgstr ""
|
||||
msgstr "Lista de reprodução"
|
||||
|
||||
#: ui/help-overlay.ui:67
|
||||
msgid "Next item"
|
||||
msgstr ""
|
||||
msgstr "Próximo item"
|
||||
|
||||
#: ui/help-overlay.ui:68
|
||||
msgid "Double tap (right side)"
|
||||
msgstr ""
|
||||
msgstr "Toque duplo (lado direito)"
|
||||
|
||||
#: ui/help-overlay.ui:74
|
||||
msgid "Previous item"
|
||||
|
@@ -96,13 +96,6 @@ class ClapperAppBase extends Gtk.Application
|
||||
if(accels)
|
||||
this.set_accels_for_action(`app.${name}`, accels);
|
||||
}
|
||||
|
||||
const gtkSettings = Gtk.Settings.get_default();
|
||||
settings.bind(
|
||||
'dark-theme', gtkSettings,
|
||||
'gtk-application-prefer-dark-theme',
|
||||
Gio.SettingsBindFlags.GET
|
||||
);
|
||||
this.doneFirstActivate = true;
|
||||
}
|
||||
});
|
||||
|
@@ -1,4 +1,4 @@
|
||||
const { Gdk, Gio, GObject, Gst, GstClapper, Gtk } = imports.gi;
|
||||
const { Adw, Gdk, Gio, GObject, Gst, GstClapper, Gtk } = imports.gi;
|
||||
const ByteArray = imports.byteArray;
|
||||
const Debug = imports.src.debug;
|
||||
const Misc = imports.src.misc;
|
||||
@@ -74,6 +74,7 @@ class ClapperPlayer extends GstClapper.Clapper
|
||||
set_and_bind_settings()
|
||||
{
|
||||
const settingsToSet = [
|
||||
'dark-theme',
|
||||
'after-playback',
|
||||
'seeking-mode',
|
||||
'audio-offset',
|
||||
@@ -657,6 +658,19 @@ class ClapperPlayer extends GstClapper.Clapper
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'dark-theme':
|
||||
/* TODO: Remove libadwaita alpha2 compat someday */
|
||||
if (Adw.StyleManager != null) {
|
||||
const styleManager = Adw.StyleManager.get_default();
|
||||
styleManager.color_scheme = (settings.get_boolean(key))
|
||||
? Adw.ColorScheme.FORCE_DARK
|
||||
: Adw.ColorScheme.FORCE_LIGHT;
|
||||
}
|
||||
else {
|
||||
const gtkSettings = Gtk.Settings.get_default();
|
||||
gtkSettings.gtk_application_prefer_dark_theme = settings.get_boolean(key);
|
||||
}
|
||||
break;
|
||||
case 'render-shadows':
|
||||
root = this.widget.get_root();
|
||||
if(!root) break;
|
||||
|
16
src/prefs.js
16
src/prefs.js
@@ -440,8 +440,15 @@ class ClapperPrefsPluginExpander extends Adw.ExpanderRow
|
||||
const featuresNames = Object.keys(pluginsData[this.title]);
|
||||
debug(`Adding ${featuresNames.length} features to the list of plugin: ${this.title}`);
|
||||
|
||||
for(let featureObj of pluginsData[this.title])
|
||||
this.add(new PrefsPluginFeature(featureObj));
|
||||
for(let featureObj of pluginsData[this.title]) {
|
||||
const prefsPluginFeature = new PrefsPluginFeature(featureObj);
|
||||
|
||||
/* TODO: Remove old libadwaita compat */
|
||||
if(this.add_row)
|
||||
this.add_row(prefsPluginFeature);
|
||||
else
|
||||
this.add(prefsPluginFeature);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -546,6 +553,11 @@ class ClapperPrefsWindow extends Adw.PreferencesWindow
|
||||
transient_for: window,
|
||||
});
|
||||
|
||||
/* FIXME: old libadwaita compat, should be
|
||||
* normally in prefs UI file */
|
||||
this.can_swipe_back = true;
|
||||
this.can_navigate_back = true;
|
||||
|
||||
this.show();
|
||||
}
|
||||
});
|
||||
|
@@ -321,6 +321,8 @@ class ClapperControlsRevealer extends Gtk.Revealer
|
||||
|
||||
const isStick = (isFloating && settings.get_boolean('floating-stick'));
|
||||
DBus.shellWindowEval('stick', isStick);
|
||||
|
||||
this.root.child.refreshWindowTitle(this.root.title);
|
||||
}
|
||||
|
||||
_onControlsRevealed()
|
||||
|
@@ -278,7 +278,8 @@ class ClapperWidget extends Gtk.Grid
|
||||
|
||||
if(currStream && type !== 'subtitle') {
|
||||
const caps = currStream.get_caps();
|
||||
debug(`${type} caps: ${caps.to_string()}`);
|
||||
if (caps)
|
||||
debug(`${type} caps: ${caps.to_string()}`);
|
||||
}
|
||||
if(type === 'video') {
|
||||
const isShowVis = (
|
||||
@@ -318,11 +319,24 @@ class ClapperWidget extends Gtk.Grid
|
||||
title = item.filename;
|
||||
}
|
||||
|
||||
this.root.title = title;
|
||||
this.refreshWindowTitle(title);
|
||||
this.revealerTop.title = title;
|
||||
this.revealerTop.showTitle = true;
|
||||
}
|
||||
|
||||
refreshWindowTitle(title)
|
||||
{
|
||||
const isFloating = !this.controlsRevealer.reveal_child;
|
||||
const pipSuffix = ' - PiP';
|
||||
const hasPipSuffix = title.endsWith(pipSuffix);
|
||||
|
||||
this.root.title = (isFloating && !hasPipSuffix)
|
||||
? title + pipSuffix
|
||||
: (!isFloating && hasPipSuffix)
|
||||
? title.substring(0, title.length - pipSuffix.length)
|
||||
: title;
|
||||
}
|
||||
|
||||
updateTime()
|
||||
{
|
||||
if(
|
||||
|
@@ -969,6 +969,17 @@ function checkYouTubeUri(uri)
|
||||
const originalHost = gstUri.get_host();
|
||||
gstUri.normalize();
|
||||
|
||||
/* TODO: Remove all this YT code */
|
||||
const scheme = gstUri.get_scheme();
|
||||
if (scheme && scheme === 'gtuber')
|
||||
return [false, null];
|
||||
|
||||
const gstRegistry = Gst.Registry.get();
|
||||
const feature = gstRegistry.lookup_feature('gtubersrc');
|
||||
|
||||
if (feature && feature.get_rank() >= Gst.Rank.PRIMARY)
|
||||
return [false, null];
|
||||
|
||||
const host = gstUri.get_host();
|
||||
let videoId = null;
|
||||
|
||||
@@ -988,7 +999,6 @@ function checkYouTubeUri(uri)
|
||||
videoId = gstUri.get_path_segments()[1];
|
||||
break;
|
||||
default:
|
||||
const scheme = gstUri.get_scheme();
|
||||
if(scheme === 'yt' || scheme === 'youtube') {
|
||||
/* ID is case sensitive */
|
||||
videoId = originalHost;
|
||||
|
@@ -5,7 +5,6 @@
|
||||
<property name="resizable">True</property>
|
||||
<property name="search-enabled">True</property>
|
||||
<property name="destroy-with-parent">True</property>
|
||||
<property name="can-swipe-back">True</property>
|
||||
<property name="modal">True</property>
|
||||
<child>
|
||||
<object class="AdwPreferencesPage">
|
||||
|
Reference in New Issue
Block a user