static void media_eos_cb (ClutterMedia *media, MexPlayer *player) { MexPlayerPrivate *priv = player->priv; priv->position = 0.0; if (priv->idle_mode) { /* loop the video in idle mode */ clutter_media_set_progress (media, priv->position); clutter_media_set_playing (media, TRUE); } else { /* Check to see if we have enqueued content and if so play it next */ MexContent *enqueued_content; enqueued_content = mex_media_controls_get_enqueued (MEX_MEDIA_CONTROLS (priv->controls), priv->content); /* set the control visible */ clutter_actor_animate (priv->info_panel, CLUTTER_EASE_IN_SINE, 250, "opacity", 0x00, NULL); mex_player_set_controls_visible (player, TRUE); if (enqueued_content) { priv->playing_from_queue = TRUE; mex_player_set_content (MEX_CONTENT_VIEW (player), enqueued_content); } else { priv->playing_from_queue = TRUE; mex_screensaver_uninhibit (priv->screensaver); clutter_media_set_progress (media, priv->position); clutter_media_set_playing (media, FALSE); priv->current_position = 0.0; priv->at_eos = TRUE; } /* focus the related content */ mex_media_controls_focus_content (MEX_MEDIA_CONTROLS (priv->controls), priv->content); } }
static gboolean key_press_timeout_cb (gpointer data) { MexMediaControlsPrivate *priv = MEX_MEDIA_CONTROLS (data)->priv; gdouble duration; gdouble change; gfloat progress; priv->long_press_activated = TRUE; priv->key_press_count++; duration = clutter_media_get_duration (priv->media); progress = clutter_media_get_progress (priv->media); if (priv->key_press_count >= 10) change = 60; else change = 10; if (priv->increment) progress = MIN (1.0, ((duration * progress) + change) / duration); else progress = MAX (0.0, ((duration * progress) - change) / duration); clutter_media_set_progress (priv->media, progress); return TRUE; }
static void media_eos_cb (ClutterMedia *media, MexPlayer *player) { MexPlayerPrivate *priv = player->priv; priv->position = 0.0; if (priv->idle_mode) { /* loop the video in idle mode */ clutter_media_set_progress (media, priv->position); clutter_media_set_playing (media, TRUE); } else { /* set the control visible */ mex_player_set_controls_visible (player, TRUE); clutter_media_set_progress (media, priv->position); clutter_media_set_playing (media, FALSE); /* focus the related content */ mex_media_controls_focus_content (MEX_MEDIA_CONTROLS (priv->controls), priv->content); /* we're not playing the content or playing the idle video so allow * screensaver if previously inhibited */ mex_screensaver_uninhibit (priv->screensaver); priv->current_position = 0.0; priv->at_eos = TRUE; } }
void mex_player_set_sort_func (MexPlayer *player, GCompareDataFunc func, gpointer userdata) { mex_media_controls_set_sort_func (MEX_MEDIA_CONTROLS (player->priv->controls), func, userdata); }
static MxFocusable * mex_media_controls_accept_focus (MxFocusable *focusable, MxFocusHint hint) { MexMediaControlsPrivate *priv = MEX_MEDIA_CONTROLS (focusable)->priv; return mx_focusable_accept_focus (MX_FOCUSABLE (priv->vbox), MX_FOCUS_HINT_FIRST); }
static void mex_media_controls_map (ClutterActor *actor) { MexMediaControlsPrivate *priv = MEX_MEDIA_CONTROLS (actor)->priv; CLUTTER_ACTOR_CLASS (mex_media_controls_parent_class)->map (actor); clutter_actor_map (priv->vbox); }
static void mex_media_controls_pick (ClutterActor *actor, const ClutterColor *color) { MexMediaControlsPrivate *priv = MEX_MEDIA_CONTROLS (actor)->priv; CLUTTER_ACTOR_CLASS (mex_media_controls_parent_class)->pick (actor, color); clutter_actor_paint (priv->vbox); }
static gboolean button_release_event_cb (ClutterActor *actor, ClutterButtonEvent *event, gpointer user_data) { MexMediaControls *self = MEX_MEDIA_CONTROLS (user_data); MexContent *content = mex_content_view_get_content (MEX_CONTENT_VIEW (actor)); mex_media_controls_replace_content (self, content); return TRUE; }
static void mex_media_controls_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { ClutterActorBox child_box; MexMediaControlsPrivate *priv = MEX_MEDIA_CONTROLS (actor)->priv; CLUTTER_ACTOR_CLASS (mex_media_controls_parent_class)-> allocate (actor, box, flags); mx_widget_get_available_area (MX_WIDGET (actor), box, &child_box); clutter_actor_allocate (priv->vbox, &child_box, flags); }
static void mex_media_controls_dispose (GObject *object) { MexMediaControls *self = MEX_MEDIA_CONTROLS (object); MexMediaControlsPrivate *priv = self->priv; if (priv->media) mex_media_controls_set_media (self, NULL); if (priv->content) { g_object_unref (priv->content); priv->content = NULL; } if (priv->model) { g_object_unref (priv->model); priv->model = NULL; } if (priv->proxy) { g_object_unref (priv->proxy); priv->proxy = NULL; } if (priv->proxy_model) { g_object_unref (priv->proxy_model); priv->proxy_model = NULL; } if (priv->script) { g_object_unref (priv->script); priv->script = NULL; } if (priv->vbox) { clutter_actor_destroy (priv->vbox); priv->vbox = NULL; } G_OBJECT_CLASS (mex_media_controls_parent_class)->dispose (object); }
static gboolean key_press_event_cb (ClutterActor *actor, ClutterKeyEvent *event, gpointer user_data) { MexMediaControls *self = MEX_MEDIA_CONTROLS (user_data); if (MEX_KEY_OK (event->keyval)) { MexContent *content = mex_content_view_get_content (MEX_CONTENT_VIEW (actor)); mex_media_controls_replace_content (self, content); return TRUE; } return FALSE; }
static void mex_media_controls_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { MexMediaControls *self = MEX_MEDIA_CONTROLS (object); switch (property_id) { case PROP_MEDIA: mex_media_controls_set_media (self, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } }
static void mex_media_controls_unmap (ClutterActor *actor) { MexMediaControlsPrivate *priv = MEX_MEDIA_CONTROLS (actor)->priv; CLUTTER_ACTOR_CLASS (mex_media_controls_parent_class)->unmap (actor); clutter_actor_unmap (priv->vbox); g_object_set (G_OBJECT (priv->proxy_model), "model", NULL, NULL); if (priv->content) { g_object_unref (priv->content); priv->content = NULL; } if (priv->model) { g_object_unref (priv->model); priv->model = NULL; } }
static void mex_media_controls_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { MexMediaControls *self = MEX_MEDIA_CONTROLS (object); switch (property_id) { case PROP_MEDIA: g_value_set_object (value, mex_media_controls_get_media (self)); break; case PROP_PLAYING_QUEUE: g_value_set_boolean (value, mex_media_controls_get_playing_queue (self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } }
static void mex_media_controls_get_preferred_height (ClutterActor *actor, gfloat for_width, gfloat *min_height_p, gfloat *nat_height_p) { MxPadding padding; MexMediaControlsPrivate *priv = MEX_MEDIA_CONTROLS (actor)->priv; mx_widget_get_padding (MX_WIDGET (actor), &padding); if (for_width >= 0) for_width = MAX (0, for_width - padding.left - padding.right); clutter_actor_get_preferred_height (priv->vbox, for_width, min_height_p, nat_height_p); if (min_height_p) *min_height_p += padding.top + padding.bottom; if (nat_height_p) *nat_height_p += padding.top + padding.bottom; }
static void mex_player_init (MexPlayer *self) { MexPlayerPrivate *priv; self->priv = priv = PLAYER_PRIVATE (self); #ifdef USE_PLAYER_CLUTTER_GST priv->media = (ClutterMedia *) clutter_gst_video_texture_new (); /* We want to keep a reference to the media here to ensure consistency with * the D-BUS client interface behaviour */ g_object_ref_sink (priv->media); clutter_container_add_actor (CLUTTER_CONTAINER (self), CLUTTER_ACTOR (priv->media)); clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (priv->media), TRUE); clutter_container_child_set (CLUTTER_CONTAINER (self), CLUTTER_ACTOR (priv->media), "fit", TRUE, NULL); /* Use progressive download when possible. Don't enable that yet, the * behaviour of seeking in the non already downloaded part of the stream * is not great. Either disable seeking in that case or find out why.*/ #if 0 video_texture = CLUTTER_GST_VIDEO_TEXTURE (priv->media); clutter_gst_video_texture_set_buffering_mode (video_texture, CLUTTER_GST_BUFFERING_MODE_DOWNLOAD); #endif #else #ifdef USE_PLAYER_DBUS priv->media = (ClutterMedia *) mex_player_client_new (); #else #ifdef USE_PLAYER_SURFACE priv->media = (ClutterMedia *) mex_surface_player_new (); #else #error Unexpected player setup #endif #endif #endif g_signal_connect (priv->media, "eos", G_CALLBACK (media_eos_cb), self); g_signal_connect (priv->media, "notify::playing", G_CALLBACK (media_playing_cb), self); g_signal_connect (priv->media, "notify::progress", G_CALLBACK (media_update_progress), self); #if defined(USE_PLAYER_SURFACE) || defined (USE_PLAYER_CLUTTER_GST) { GError *error = NULL; priv->bridge = mex_media_dbus_bridge_new (priv->media); if (!mex_media_dbus_bridge_register (priv->bridge, &error)) { g_warning (G_STRLOC ": Error registering player on D-BUS"); g_clear_error (&error); } } #endif /* add info panel */ priv->info_panel = mex_info_panel_new (MEX_INFO_PANEL_MODE_FULL); mx_widget_set_disabled (MX_WIDGET (priv->info_panel), TRUE); clutter_container_add_actor (CLUTTER_CONTAINER (self), priv->info_panel); clutter_container_child_set (CLUTTER_CONTAINER (self), priv->info_panel, "y-fill", FALSE, "y-align", MX_ALIGN_END, NULL); clutter_actor_set_opacity (priv->info_panel, 0); /* add media controls */ priv->controls = mex_media_controls_new (); g_signal_connect (priv->controls, "stopped", G_CALLBACK (controls_stopped_cb), self); mex_media_controls_set_media (MEX_MEDIA_CONTROLS (priv->controls), priv->media); clutter_container_add_actor (CLUTTER_CONTAINER (self), priv->controls); clutter_container_child_set (CLUTTER_CONTAINER (self), priv->controls, "y-fill", FALSE, "y-align", MX_ALIGN_END, NULL); priv->screensaver = mex_screensaver_new (); /* start in idle mode */ mex_player_set_idle_mode (MEX_PLAYER (self), TRUE); }
/* MexContentView implementation */ static void mex_player_set_content (MexContentView *view, MexContent *content) { MexPlayerPrivate *priv = MEX_PLAYER (view)->priv; if (priv->model) mex_media_controls_set_content (MEX_MEDIA_CONTROLS (priv->controls), content, priv->model); if (priv->related_tile) { g_object_unref (priv->related_tile); priv->related_tile = NULL; } if (content) { const gchar *sposition, *sduration; if (priv->content) { save_old_content (MEX_PLAYER (view)); g_object_unref (priv->content); priv->content = NULL; } priv->content = g_object_ref_sink (content); sposition = mex_content_get_metadata (content, MEX_CONTENT_METADATA_LAST_POSITION); sduration = mex_content_get_metadata (content, MEX_CONTENT_METADATA_DURATION); if (sduration && !mex_media_controls_get_playing_queue (MEX_MEDIA_CONTROLS (priv->controls))) priv->duration = atoi (sduration); else priv->duration = 0; if (priv->duration > 0) { if (sposition) { int position = atoi (sposition); priv->position = (gdouble) position / (gdouble) priv->duration; } else { priv->position = 0.0; } } if (MEX_IS_PROGRAM (content)) { mex_program_get_stream (MEX_PROGRAM (content), mex_get_stream_cb, view); } else { const gchar *uri; uri = mex_content_get_metadata (content, MEX_CONTENT_METADATA_STREAM); mex_get_stream_cb (NULL, uri, NULL, view); } if (priv->info_visible) { clutter_actor_animate (priv->info_panel, CLUTTER_EASE_IN_SINE, 250, "opacity", 0x00, NULL); mx_widget_set_disabled (MX_WIDGET (priv->info_panel), TRUE); priv->info_visible = FALSE; } mex_player_set_controls_visible (MEX_PLAYER (view), TRUE); } else { if (priv->content) { g_object_unref (priv->content); priv->content = NULL; } } }