diff --git a/data/com.github.rafostar.Clapper.gschema.xml b/data/com.github.rafostar.Clapper.gschema.xml index f43b58f4..26db03ad 100644 --- a/data/com.github.rafostar.Clapper.gschema.xml +++ b/data/com.github.rafostar.Clapper.gschema.xml @@ -94,6 +94,14 @@ '{}' Custom values for GStreamer plugin ranking + + false + Use playbin3 element instead of playbin2 + + + false + Use PipeWire for audio output + 1687 Set PlayFlags for playbin diff --git a/lib/gst/clapper/gstclapper.c b/lib/gst/clapper/gstclapper.c index d20f0a5b..6efd2491 100644 --- a/lib/gst/clapper/gstclapper.c +++ b/lib/gst/clapper/gstclapper.c @@ -51,6 +51,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_clapper_debug); #define GST_CAT_DEFAULT gst_clapper_debug +#define DEFAULT_USE_PLAYBIN3 FALSE +#define DEFAULT_USE_PIPEWIRE FALSE #define DEFAULT_STATE GST_CLAPPER_STATE_STOPPED #define DEFAULT_URI NULL #define DEFAULT_POSITION GST_CLOCK_TIME_NONE @@ -80,6 +82,8 @@ enum PROP_VIDEO_RENDERER, PROP_SIGNAL_DISPATCHER, PROP_MPRIS, + PROP_USE_PLAYBIN3, + PROP_USE_PIPEWIRE, PROP_STATE, PROP_URI, PROP_SUBURI, @@ -196,6 +200,8 @@ struct _GstClapper gchar *audio_sid; gchar *subtitle_sid; gulong stream_notify_id; + + gboolean use_pipewire; }; struct _GstClapperClass @@ -324,6 +330,16 @@ gst_clapper_class_init (GstClapperClass * klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + param_specs[PROP_USE_PLAYBIN3] = + g_param_spec_boolean ("use-playbin3", "Use playbin3", "Use playbin3", + DEFAULT_USE_PLAYBIN3, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + param_specs[PROP_USE_PIPEWIRE] = + g_param_spec_boolean ("use-pipewire", "Use PipeWire", "PipeWire audio output", + DEFAULT_USE_PIPEWIRE, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + param_specs[PROP_STATE] = g_param_spec_enum ("state", "Clapper State", "Current player state", GST_TYPE_CLAPPER_STATE, DEFAULT_STATE, G_PARAM_READABLE | @@ -685,6 +701,12 @@ gst_clapper_set_property (GObject * object, guint prop_id, case PROP_MPRIS: self->mpris = g_value_dup_object (value); break; + case PROP_USE_PLAYBIN3: + self->use_playbin3 = g_value_get_boolean (value); + break; + case PROP_USE_PIPEWIRE: + self->use_pipewire = g_value_get_boolean (value); + break; case PROP_URI:{ g_mutex_lock (&self->lock); g_free (self->uri); @@ -3057,6 +3079,19 @@ element_setup_cb (GstElement * playbin, GstElement * element, GstClapper * self) } } +static void +_update_from_env (gboolean * enabled, const gchar * env_name) +{ + const gchar *env = g_getenv (env_name); + + if (env) { + if (g_str_has_prefix (env, "1")) + *enabled = TRUE; + else if (g_str_has_prefix (env, "0")) + *enabled = FALSE; + } +} + static gpointer gst_clapper_main (gpointer data) { @@ -3064,7 +3099,6 @@ gst_clapper_main (gpointer data) GstBus *bus; GSource *source; GstElement *scaletempo, *pipewiresink; - const gchar *pb_env, *pw_env; GST_TRACE_OBJECT (self, "Starting main thread"); @@ -3076,9 +3110,7 @@ gst_clapper_main (gpointer data) g_source_attach (source, self->context); g_source_unref (source); - pb_env = g_getenv ("GST_CLAPPER_USE_PLAYBIN3"); - if (pb_env && g_str_has_prefix (pb_env, "1")) - self->use_playbin3 = TRUE; + _update_from_env (&self->use_playbin3, "GST_CLAPPER_USE_PLAYBIN3"); if (self->use_playbin3) { GST_DEBUG_OBJECT (self, "playbin3 enabled"); @@ -3119,14 +3151,21 @@ gst_clapper_main (gpointer data) } } - pw_env = g_getenv ("GST_CLAPPER_USE_PIPEWIRE"); - if (pw_env && g_str_has_prefix (pw_env, "1")) { + _update_from_env (&self->use_pipewire, "GST_CLAPPER_USE_PIPEWIRE"); + + if (self->use_pipewire) { pipewiresink = gst_element_factory_make ("pipewiresink", NULL); if (pipewiresink) { g_object_set (self->playbin, "audio-sink", pipewiresink, NULL); } else { - g_warning ("GstClapper: pipewiresink element not available. " - "Default audio sink will be used instead."); + GstElement *fakesink; + + g_warning ("GstClapper: pipewiresink element not available"); + fakesink = gst_element_factory_make ("fakesink", "fakeaudiosink"); + if (fakesink) + g_object_set (self->playbin, "audio-sink", fakesink, NULL); + else + g_warning ("GstClapper: default audio sink will be used instead"); } } diff --git a/src/player.js b/src/player.js index 5fb877f7..a981b43d 100644 --- a/src/player.js +++ b/src/player.js @@ -34,6 +34,8 @@ class ClapperPlayer extends GstClapper.Clapper desktop_entry: Misc.appId, default_art_url: Misc.getClapperThemeIconUri(), }), + use_playbin3: settings.get_boolean('use-playbin3'), + use_pipewire: settings.get_boolean('use-pipewire'), }); this.widget = gtk4plugin.video_sink.widget; diff --git a/ui/preferences-window.ui b/ui/preferences-window.ui index 749c3116..85e9f0a7 100644 --- a/ui/preferences-window.ui +++ b/ui/preferences-window.ui @@ -254,6 +254,20 @@ Alter default ranks of GStreamer plugins + + + Use playbin3 + Use experimental playbin3 element (requires player restart) + use-playbin3 + + + + + Use PipeWire + Use PipeWire for audio output (requires player restart) + use-pipewire + +