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 */
|
/* Adwaita is missing osd ListBox */
|
||||||
|
.clapperplaylist {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
.clapperplaylist row {
|
.clapperplaylist row {
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
@@ -28,9 +31,6 @@ scrolledwindow scrollbar.vertical slider {
|
|||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
}
|
}
|
||||||
.osd .clapperplaylist {
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
.osd .clapperplaylist row image {
|
.osd .clapperplaylist row image {
|
||||||
-gtk-icon-shadow: none;
|
-gtk-icon-shadow: none;
|
||||||
}
|
}
|
||||||
@@ -223,6 +223,9 @@ scale trough slider {
|
|||||||
.fullscreen.tvmode .positionscale marks.bottom {
|
.fullscreen.tvmode .positionscale marks.bottom {
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
}
|
}
|
||||||
|
.fullscreen.tvmode .positionscale trough {
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
.fullscreen.tvmode .positionscale trough highlight {
|
.fullscreen.tvmode .positionscale trough highlight {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
|
@@ -48,6 +48,34 @@
|
|||||||
</screenshot>
|
</screenshot>
|
||||||
</screenshots>
|
</screenshots>
|
||||||
<releases>
|
<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">
|
<release version="0.4.0" date="2021-09-12">
|
||||||
<description>
|
<description>
|
||||||
<p>Changes:</p>
|
<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,
|
static void gst_clapper_subtitle_info_update (GstClapper * self,
|
||||||
GstClapperStreamInfo * stream_info);
|
GstClapperStreamInfo * stream_info);
|
||||||
|
|
||||||
|
static gboolean find_active_decoder_with_stream_id (GstClapper * self,
|
||||||
|
GstElementFactoryListType type, const gchar * stream_id);
|
||||||
|
|
||||||
/* For playbin3 */
|
/* For playbin3 */
|
||||||
static void gst_clapper_streams_info_create_from_collection (GstClapper * self,
|
static void gst_clapper_streams_info_create_from_collection (GstClapper * self,
|
||||||
GstClapperMediaInfo * media_info, GstStreamCollection * collection);
|
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);
|
"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
|
static void
|
||||||
tags_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg, gpointer user_data)
|
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) {
|
if (gst_tag_list_get_scope (tags) == GST_TAG_SCOPE_GLOBAL) {
|
||||||
g_mutex_lock (&self->lock);
|
g_mutex_lock (&self->lock);
|
||||||
if (self->media_info) {
|
if (self->media_info) {
|
||||||
if (self->media_info->tags)
|
merge_tags (&self->media_info->tags, tags);
|
||||||
gst_tag_list_unref (self->media_info->tags);
|
|
||||||
self->media_info->tags = gst_tag_list_ref (tags);
|
|
||||||
media_info_update (self, self->media_info);
|
media_info_update (self, self->media_info);
|
||||||
g_mutex_unlock (&self->lock);
|
|
||||||
} else {
|
} else {
|
||||||
if (self->global_tags)
|
merge_tags (&self->global_tags, tags);
|
||||||
gst_tag_list_unref (self->global_tags);
|
|
||||||
self->global_tags = gst_tag_list_ref (tags);
|
|
||||||
g_mutex_unlock (&self->lock);
|
|
||||||
}
|
}
|
||||||
|
g_mutex_unlock (&self->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_tag_list_unref (tags);
|
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);
|
GstClapper *self = GST_CLAPPER (user_data);
|
||||||
GstStreamCollection *collection = NULL;
|
GstStreamCollection *collection = NULL;
|
||||||
|
gchar *video_sid, *audio_sid;
|
||||||
guint i, len;
|
guint i, len;
|
||||||
|
|
||||||
gst_message_parse_streams_selected (msg, &collection);
|
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);
|
*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);
|
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
|
static gboolean
|
||||||
@@ -3009,11 +3032,12 @@ decoder_changed_signal_data_free (DecoderChangedSignalData * data)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
emit_decoder_changed (GstClapper * self, gchar * decoder_name,
|
emit_decoder_changed (GstClapper * self, gchar * decoder_name,
|
||||||
gboolean is_video)
|
GstElementFactoryListType type)
|
||||||
{
|
{
|
||||||
GstClapperSignalDispatcherFunc func = NULL;
|
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,
|
if (g_signal_handler_find (self, G_SIGNAL_MATCH_ID,
|
||||||
signals[SIGNAL_VIDEO_DECODER_CHANGED], 0, NULL, NULL, NULL) != 0 &&
|
signals[SIGNAL_VIDEO_DECODER_CHANGED], 0, NULL, NULL, NULL) != 0 &&
|
||||||
g_strcmp0 (self->last_vdecoder, decoder_name) != 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);
|
g_free (self->last_vdecoder);
|
||||||
self->last_vdecoder = g_strdup (decoder_name);
|
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,
|
if (g_signal_handler_find (self, G_SIGNAL_MATCH_ID,
|
||||||
signals[SIGNAL_AUDIO_DECODER_CHANGED], 0, NULL, NULL, NULL) != 0 &&
|
signals[SIGNAL_AUDIO_DECODER_CHANGED], 0, NULL, NULL, NULL) != 0 &&
|
||||||
g_strcmp0 (self->last_adecoder, decoder_name) != 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
|
static void
|
||||||
element_setup_cb (GstElement * playbin, GstElement * element, GstClapper * self)
|
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) {
|
if (plugin_name) {
|
||||||
GST_INFO_OBJECT (self, "Plugin setup: %s", 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 */
|
/* TODO: Set plugin props */
|
||||||
}
|
}
|
||||||
g_free (plugin_name);
|
g_free (plugin_name);
|
||||||
@@ -3229,6 +3379,11 @@ gst_clapper_main (gpointer data)
|
|||||||
G_CALLBACK (audio_tags_changed_cb), self);
|
G_CALLBACK (audio_tags_changed_cb), self);
|
||||||
g_signal_connect (self->playbin, "text-tags-changed",
|
g_signal_connect (self->playbin, "text-tags-changed",
|
||||||
G_CALLBACK (subtitle_tags_changed_cb), self);
|
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",
|
g_signal_connect (self->playbin, "notify::volume",
|
||||||
@@ -3324,6 +3479,103 @@ gst_clapper_has_plugin_with_features (const gchar * name)
|
|||||||
return ret;
|
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
|
static void
|
||||||
gst_clapper_prepare_gstreamer (void)
|
gst_clapper_prepare_gstreamer (void)
|
||||||
{
|
{
|
||||||
@@ -3346,6 +3598,9 @@ gst_clapper_prepare_gstreamer (void)
|
|||||||
gst_clapper_set_feature_rank ("v4l2slvp8dec", GST_RANK_NONE);
|
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_clapper_gstreamer_prepared = TRUE;
|
||||||
GST_DEBUG ("GStreamer plugins prepared");
|
GST_DEBUG ("GStreamer plugins prepared");
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
project('com.github.rafostar.Clapper', 'c', 'cpp',
|
project('com.github.rafostar.Clapper', 'c', 'cpp',
|
||||||
version: '0.4.0',
|
version: '0.4.1',
|
||||||
meson_version: '>= 0.50.0',
|
meson_version: '>= 0.50.0',
|
||||||
license: 'GPL-3.0-or-later',
|
license: 'GPL-3.0-or-later',
|
||||||
default_options: [
|
default_options: [
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
"flathub/lib/libass.json",
|
"flathub/lib/libass.json",
|
||||||
"flathub/lib/ffmpeg.json",
|
"flathub/lib/ffmpeg.json",
|
||||||
"testing/gstreamer.json",
|
"testing/gstreamer.json",
|
||||||
|
"testing/gtuber.json",
|
||||||
{
|
{
|
||||||
"name": "clapper",
|
"name": "clapper",
|
||||||
"buildsystem": "meson",
|
"buildsystem": "meson",
|
||||||
|
@@ -42,6 +42,7 @@
|
|||||||
"flathub/gstreamer-1.0/gstreamer-vaapi.json",
|
"flathub/gstreamer-1.0/gstreamer-vaapi.json",
|
||||||
"flathub/lib/gtk4.json",
|
"flathub/lib/gtk4.json",
|
||||||
"flathub/lib/libadwaita.json",
|
"flathub/lib/libadwaita.json",
|
||||||
|
"testing/gtuber.json",
|
||||||
{
|
{
|
||||||
"name": "clapper",
|
"name": "clapper",
|
||||||
"buildsystem": "meson",
|
"buildsystem": "meson",
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
"-Dintrospection=enabled",
|
"-Dintrospection=enabled",
|
||||||
"-Ddoc=disabled",
|
"-Ddoc=disabled",
|
||||||
"-Dgtk_doc=disabled",
|
"-Dgtk_doc=disabled",
|
||||||
|
"-Dgpl=enabled",
|
||||||
|
|
||||||
"-Dgstreamer:benchmarks=disabled",
|
"-Dgstreamer:benchmarks=disabled",
|
||||||
"-Dgstreamer:gobject-cast-checks=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
|
%global glib2_version 2.56.0
|
||||||
|
|
||||||
Name: clapper
|
Name: clapper
|
||||||
Version: 0.4.0
|
Version: 0.4.1
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: Simple and modern GNOME media player
|
Summary: Simple and modern GNOME media player
|
||||||
|
|
||||||
@@ -129,6 +129,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
|
|||||||
%{_libdir}/%{appname}/
|
%{_libdir}/%{appname}/
|
||||||
|
|
||||||
%changelog
|
%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
|
* Sun Sep 12 2021 Rafostar <rafostar.github@gmail.com> - 0.4.0-1
|
||||||
- New version
|
- 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"
|
"Project-Id-Version: clapper\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-09-14 16:35+0200\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"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Portuguese\n"
|
"Language-Team: Portuguese\n"
|
||||||
"Language: pt_PT\n"
|
"Language: pt_PT\n"
|
||||||
@@ -19,88 +19,88 @@ msgstr ""
|
|||||||
|
|
||||||
#: ui/clapper.ui:6
|
#: ui/clapper.ui:6
|
||||||
msgid "Open Files..."
|
msgid "Open Files..."
|
||||||
msgstr ""
|
msgstr "Abrir Arquivos..."
|
||||||
|
|
||||||
#: ui/clapper.ui:10
|
#: ui/clapper.ui:10
|
||||||
msgid "Open URI..."
|
msgid "Open URI..."
|
||||||
msgstr ""
|
msgstr "Abrir URI..."
|
||||||
|
|
||||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||||
msgid "Preferences"
|
msgid "Preferences"
|
||||||
msgstr ""
|
msgstr "Preferências"
|
||||||
|
|
||||||
#: ui/clapper.ui:20
|
#: ui/clapper.ui:20
|
||||||
msgid "Shortcuts"
|
msgid "Shortcuts"
|
||||||
msgstr ""
|
msgstr "Atalhos"
|
||||||
|
|
||||||
#: ui/clapper.ui:26
|
#: ui/clapper.ui:26
|
||||||
msgid "About Clapper"
|
msgid "About Clapper"
|
||||||
msgstr ""
|
msgstr "Sobre o Clapper"
|
||||||
|
|
||||||
#: ui/elapsed-time-button.ui:27
|
#: ui/elapsed-time-button.ui:27
|
||||||
msgid "Speed"
|
msgid "Speed"
|
||||||
msgstr ""
|
msgstr "Velocidade"
|
||||||
|
|
||||||
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:83
|
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:83
|
||||||
#: ui/preferences-window.ui:215
|
#: ui/preferences-window.ui:215
|
||||||
msgid "Normal"
|
msgid "Normal"
|
||||||
msgstr ""
|
msgstr "Predefinido"
|
||||||
|
|
||||||
#: ui/help-overlay.ui:10 ui/preferences-window.ui:12
|
#: ui/help-overlay.ui:10 ui/preferences-window.ui:12
|
||||||
msgid "General"
|
msgid "General"
|
||||||
msgstr ""
|
msgstr "Geral"
|
||||||
|
|
||||||
#: ui/help-overlay.ui:13
|
#: ui/help-overlay.ui:13
|
||||||
msgid "Show shortcuts"
|
msgid "Show shortcuts"
|
||||||
msgstr ""
|
msgstr "Mostrar atalhos"
|
||||||
|
|
||||||
#: ui/help-overlay.ui:19
|
#: ui/help-overlay.ui:19
|
||||||
msgid "Toggle fullscreen"
|
msgid "Toggle fullscreen"
|
||||||
msgstr ""
|
msgstr "Mudar modo de ecrã"
|
||||||
|
|
||||||
#: ui/help-overlay.ui:20
|
#: ui/help-overlay.ui:20
|
||||||
msgid "Double tap | Double click"
|
msgid "Double tap | Double click"
|
||||||
msgstr ""
|
msgstr "Toque duplo duplo Clique duplo"
|
||||||
|
|
||||||
#: ui/help-overlay.ui:26
|
#: ui/help-overlay.ui:26
|
||||||
msgid "Leave fullscreen"
|
msgid "Leave fullscreen"
|
||||||
msgstr ""
|
msgstr "Sair do modo de ecrã completo"
|
||||||
|
|
||||||
#: ui/help-overlay.ui:32
|
#: ui/help-overlay.ui:32
|
||||||
msgid "Reveal OSD (fullscreen only)"
|
msgid "Reveal OSD (fullscreen only)"
|
||||||
msgstr ""
|
msgstr "Revelar OSD (apenas em tela cheia)"
|
||||||
|
|
||||||
#: ui/help-overlay.ui:33
|
#: ui/help-overlay.ui:33
|
||||||
msgid "Tap"
|
msgid "Tap"
|
||||||
msgstr ""
|
msgstr "Tocar"
|
||||||
|
|
||||||
#: ui/help-overlay.ui:39
|
#: ui/help-overlay.ui:39
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr ""
|
msgstr "Sair"
|
||||||
|
|
||||||
#: ui/help-overlay.ui:47
|
#: ui/help-overlay.ui:47
|
||||||
msgid "Media"
|
msgid "Media"
|
||||||
msgstr ""
|
msgstr "Multimédia"
|
||||||
|
|
||||||
#: ui/help-overlay.ui:50
|
#: ui/help-overlay.ui:50
|
||||||
msgid "Open files"
|
msgid "Open files"
|
||||||
msgstr ""
|
msgstr "Abrir ficheiro"
|
||||||
|
|
||||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||||
msgid "Open URI"
|
msgid "Open URI"
|
||||||
msgstr ""
|
msgstr "Abrir URI"
|
||||||
|
|
||||||
#: ui/help-overlay.ui:64
|
#: ui/help-overlay.ui:64
|
||||||
msgid "Playlist"
|
msgid "Playlist"
|
||||||
msgstr ""
|
msgstr "Lista de reprodução"
|
||||||
|
|
||||||
#: ui/help-overlay.ui:67
|
#: ui/help-overlay.ui:67
|
||||||
msgid "Next item"
|
msgid "Next item"
|
||||||
msgstr ""
|
msgstr "Próximo item"
|
||||||
|
|
||||||
#: ui/help-overlay.ui:68
|
#: ui/help-overlay.ui:68
|
||||||
msgid "Double tap (right side)"
|
msgid "Double tap (right side)"
|
||||||
msgstr ""
|
msgstr "Toque duplo (lado direito)"
|
||||||
|
|
||||||
#: ui/help-overlay.ui:74
|
#: ui/help-overlay.ui:74
|
||||||
msgid "Previous item"
|
msgid "Previous item"
|
||||||
|
@@ -96,13 +96,6 @@ class ClapperAppBase extends Gtk.Application
|
|||||||
if(accels)
|
if(accels)
|
||||||
this.set_accels_for_action(`app.${name}`, 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;
|
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 ByteArray = imports.byteArray;
|
||||||
const Debug = imports.src.debug;
|
const Debug = imports.src.debug;
|
||||||
const Misc = imports.src.misc;
|
const Misc = imports.src.misc;
|
||||||
@@ -74,6 +74,7 @@ class ClapperPlayer extends GstClapper.Clapper
|
|||||||
set_and_bind_settings()
|
set_and_bind_settings()
|
||||||
{
|
{
|
||||||
const settingsToSet = [
|
const settingsToSet = [
|
||||||
|
'dark-theme',
|
||||||
'after-playback',
|
'after-playback',
|
||||||
'seeking-mode',
|
'seeking-mode',
|
||||||
'audio-offset',
|
'audio-offset',
|
||||||
@@ -657,6 +658,19 @@ class ClapperPlayer extends GstClapper.Clapper
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
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':
|
case 'render-shadows':
|
||||||
root = this.widget.get_root();
|
root = this.widget.get_root();
|
||||||
if(!root) break;
|
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]);
|
const featuresNames = Object.keys(pluginsData[this.title]);
|
||||||
debug(`Adding ${featuresNames.length} features to the list of plugin: ${this.title}`);
|
debug(`Adding ${featuresNames.length} features to the list of plugin: ${this.title}`);
|
||||||
|
|
||||||
for(let featureObj of pluginsData[this.title])
|
for(let featureObj of pluginsData[this.title]) {
|
||||||
this.add(new PrefsPluginFeature(featureObj));
|
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,
|
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();
|
this.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -321,6 +321,8 @@ class ClapperControlsRevealer extends Gtk.Revealer
|
|||||||
|
|
||||||
const isStick = (isFloating && settings.get_boolean('floating-stick'));
|
const isStick = (isFloating && settings.get_boolean('floating-stick'));
|
||||||
DBus.shellWindowEval('stick', isStick);
|
DBus.shellWindowEval('stick', isStick);
|
||||||
|
|
||||||
|
this.root.child.refreshWindowTitle(this.root.title);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onControlsRevealed()
|
_onControlsRevealed()
|
||||||
|
@@ -278,7 +278,8 @@ class ClapperWidget extends Gtk.Grid
|
|||||||
|
|
||||||
if(currStream && type !== 'subtitle') {
|
if(currStream && type !== 'subtitle') {
|
||||||
const caps = currStream.get_caps();
|
const caps = currStream.get_caps();
|
||||||
debug(`${type} caps: ${caps.to_string()}`);
|
if (caps)
|
||||||
|
debug(`${type} caps: ${caps.to_string()}`);
|
||||||
}
|
}
|
||||||
if(type === 'video') {
|
if(type === 'video') {
|
||||||
const isShowVis = (
|
const isShowVis = (
|
||||||
@@ -318,11 +319,24 @@ class ClapperWidget extends Gtk.Grid
|
|||||||
title = item.filename;
|
title = item.filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.root.title = title;
|
this.refreshWindowTitle(title);
|
||||||
this.revealerTop.title = title;
|
this.revealerTop.title = title;
|
||||||
this.revealerTop.showTitle = true;
|
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()
|
updateTime()
|
||||||
{
|
{
|
||||||
if(
|
if(
|
||||||
|
@@ -969,6 +969,17 @@ function checkYouTubeUri(uri)
|
|||||||
const originalHost = gstUri.get_host();
|
const originalHost = gstUri.get_host();
|
||||||
gstUri.normalize();
|
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();
|
const host = gstUri.get_host();
|
||||||
let videoId = null;
|
let videoId = null;
|
||||||
|
|
||||||
@@ -988,7 +999,6 @@ function checkYouTubeUri(uri)
|
|||||||
videoId = gstUri.get_path_segments()[1];
|
videoId = gstUri.get_path_segments()[1];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
const scheme = gstUri.get_scheme();
|
|
||||||
if(scheme === 'yt' || scheme === 'youtube') {
|
if(scheme === 'yt' || scheme === 'youtube') {
|
||||||
/* ID is case sensitive */
|
/* ID is case sensitive */
|
||||||
videoId = originalHost;
|
videoId = originalHost;
|
||||||
|
@@ -5,7 +5,6 @@
|
|||||||
<property name="resizable">True</property>
|
<property name="resizable">True</property>
|
||||||
<property name="search-enabled">True</property>
|
<property name="search-enabled">True</property>
|
||||||
<property name="destroy-with-parent">True</property>
|
<property name="destroy-with-parent">True</property>
|
||||||
<property name="can-swipe-back">True</property>
|
|
||||||
<property name="modal">True</property>
|
<property name="modal">True</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="AdwPreferencesPage">
|
<object class="AdwPreferencesPage">
|
||||||
|
Reference in New Issue
Block a user