void mex_player_set_idle_mode (MexPlayer *player, gboolean idle) { MexPlayerPrivate *priv = player->priv; if (priv->idle_mode == idle) return; priv->idle_mode = idle; mex_player_set_controls_visible (player, !idle); if (idle) { gchar *tmp; clutter_actor_hide (priv->controls); clutter_actor_hide (priv->info_panel); mx_widget_set_disabled (MX_WIDGET (player), TRUE); clutter_actor_set_reactive (CLUTTER_ACTOR (player), FALSE); if (priv->content) { save_old_content (player); g_object_unref (priv->content); priv->content = NULL; } tmp = g_strconcat ("file://", mex_get_data_dir (), "/common/style/background-loop.mkv", NULL); clutter_media_set_uri (priv->media, tmp); g_free (tmp); clutter_media_set_playing (priv->media, TRUE); /* we're idle so we don't mind the screensaver coming on */ mex_screensaver_uninhibit (priv->screensaver); } else { clutter_actor_show (priv->controls); clutter_actor_show (priv->info_panel); mx_widget_set_disabled (MX_WIDGET (player), FALSE); clutter_actor_set_reactive (CLUTTER_ACTOR (player), TRUE); clutter_media_set_playing (priv->media, FALSE); clutter_media_set_uri (priv->media, NULL); /* we're playing real content so don't allow the screensaver */ mex_screensaver_inhibit (priv->screensaver); } }
/** * clutter_media_set_filename: * @media: a #ClutterMedia * @filename: A filename * * Sets the source of @media using a file path. * * Since: 0.2 * * Deprecated: 1.12 */ void clutter_media_set_filename (ClutterMedia *media, const gchar *filename) { gchar *uri; GError *uri_error = NULL; if (!g_path_is_absolute (filename)) { gchar *abs_path; abs_path = g_build_filename (g_get_current_dir (), filename, NULL); uri = g_filename_to_uri (abs_path, NULL, &uri_error); g_free (abs_path); } else uri = g_filename_to_uri (filename, NULL, &uri_error); if (uri_error) { g_signal_emit (media, media_signals[ERROR_SIGNAL], 0, uri_error); g_error_free (uri_error); return; } clutter_media_set_uri (media, uri); g_free (uri); }
static int mp_load(TPMediaPlayer * mp,const char * uri,const char * extra) { USERDATA(mp); CM(ud); clutter_media_set_uri(cm,uri); #if (CLUTTER_GST_MAJOR_VERSION<1) GstElement * pipeline=clutter_gst_video_texture_get_playbin(CLUTTER_GST_VIDEO_TEXTURE(cm)); #else GstElement * pipeline=clutter_gst_video_texture_get_pipeline(CLUTTER_GST_VIDEO_TEXTURE(cm)); #endif if (!pipeline) return 1; GstStateChangeReturn r=gst_element_set_state(pipeline,GST_STATE_PAUSED); g_debug("STATE CHANGE RETURN IS %d",r); switch(r) { case GST_STATE_CHANGE_FAILURE: { return 2; } case GST_STATE_CHANGE_SUCCESS: case GST_STATE_CHANGE_NO_PREROLL: { get_stream_information(mp); tp_media_player_loaded(mp); break; } case GST_STATE_CHANGE_ASYNC: { // The state change happens asynchronously, so we connect a signal // handler to see when it is done GstBus * bus=gst_pipeline_get_bus(GST_PIPELINE(pipeline)); if (!bus) return 3; ud->load_signal=g_signal_connect(bus,"message",G_CALLBACK(loading_messages),mp); gst_object_unref(GST_OBJECT(bus)); break; } } return 0; }
void mex_player_set_idle_mode (MexPlayer *player, gboolean idle) { MexPlayerPrivate *priv = player->priv; if (priv->idle_mode == idle) return; priv->idle_mode = idle; if (idle) { clutter_actor_hide (priv->controls); clutter_actor_hide (priv->info_panel); mx_widget_set_disabled (MX_WIDGET (player), TRUE); if (priv->content) { save_old_content (player); g_object_unref (priv->content); priv->content = NULL; } clutter_media_set_uri (priv->media, "file://" PKGDATADIR "/style/background-loop.mkv"); clutter_media_set_playing (priv->media, TRUE); /* we're idle so we don't mind the screensaver coming on */ mex_screensaver_uninhibit (priv->screensaver); } else { clutter_actor_show (priv->controls); clutter_actor_show (priv->info_panel); mx_widget_set_disabled (MX_WIDGET (player), FALSE); clutter_media_set_playing (priv->media, FALSE); clutter_media_set_uri (priv->media, NULL); /* we're playing real content so don't allow the screensaver */ mex_screensaver_inhibit (priv->screensaver); } }
void mex_player_stop (MexPlayer *player) { MexPlayerPrivate *priv = player->priv; if (priv->idle_mode) return; clutter_media_set_uri (CLUTTER_MEDIA (priv->media), NULL); clutter_media_set_playing (priv->media, FALSE); g_signal_emit (player, signals[CLOSE_REQUEST], 0); }
/* content view */ static void mex_music_player_set_content (MexContentView *player, MexContent *content) { MexMusicPlayerPrivate *priv = MEX_MUSIC_PLAYER (player)->priv; gchar *album_artist; const gchar *uri, *album, *artist, *title; ClutterActorIter iter; ClutterActor *child, *container; if (priv->content) g_object_unref (priv->content); priv->content = content; if (!content) return; g_object_ref (content); /* title */ title = mex_content_get_metadata (content, MEX_CONTENT_METADATA_TITLE); mx_label_set_text (MX_LABEL (priv->title_label), title); /* subtitle (album, artist) */ album = mex_content_get_metadata (content, MEX_CONTENT_METADATA_ALBUM); artist = mex_content_get_metadata (content, MEX_CONTENT_METADATA_ARTIST); album_artist = g_strconcat (album, ", ", artist , NULL); mx_label_set_text (MX_LABEL (priv->subtitle_label), album_artist); g_free (album_artist); /* uri */ uri = mex_content_get_metadata (content, MEX_CONTENT_METADATA_STREAM); clutter_media_set_uri (priv->player, uri); /* find the item in the list */ container = mex_script_get_actor (priv->script, "tracks"); clutter_actor_iter_init (&iter, container); while (clutter_actor_iter_next (&iter, &child)) { MexContent *button_content; button_content = g_object_get_data (G_OBJECT (child), "content"); mx_button_set_toggled (MX_BUTTON (child), (button_content == content)); } }
static void mex_get_stream_cb (MexProgram *program, const gchar *url, const GError *error, gpointer user_data) { MexPlayer *player = user_data; MexPlayerPrivate *priv = player->priv; MexGenericContent *generic_content; #ifdef USE_PLAYER_CLUTTER_GST ClutterGstVideoTexture *video_texture; #endif /* if idle mode has been set before the program stream was found */ if (priv->idle_mode) return; if (G_UNLIKELY (error)) { g_warning ("Could not play content: %s (%s)", error->message, url); return; } #ifdef USE_PLAYER_CLUTTER_GST /* We seek at the precise time when the file is local, but we * seek to key frame when streaming */ video_texture = CLUTTER_GST_VIDEO_TEXTURE (priv->media); if (g_str_has_prefix (url, "file://")) { clutter_gst_video_texture_set_seek_flags (video_texture, CLUTTER_GST_SEEK_FLAG_ACCURATE); } else { clutter_gst_video_texture_set_seek_flags (video_texture, CLUTTER_GST_SEEK_FLAG_NONE); } #endif clutter_media_set_uri (CLUTTER_MEDIA (priv->media), url); generic_content = MEX_GENERIC_CONTENT (priv->content); if (mex_generic_content_get_last_position_start (generic_content)) clutter_media_set_progress (CLUTTER_MEDIA (priv->media), priv->position); clutter_media_set_playing (CLUTTER_MEDIA (priv->media), TRUE); }
void mex_music_player_set_uri (MexMusicPlayer *player, const gchar *uri) { MexMusicPlayerPrivate *priv; char *old_uri; gboolean playing; gboolean uri_set = FALSE; g_return_if_fail (MEX_IS_MUSIC_PLAYER (player)); priv = player->priv; old_uri = clutter_media_get_uri (priv->player); if (!old_uri && !uri) return; playing = mex_music_player_is_playing (player); if (!old_uri || (uri && strcmp (uri, old_uri))) { uri_set = TRUE; clutter_media_set_uri (priv->player, uri); } if (playing && !uri) { /* we are no longer playing, I guess */ g_signal_emit (player, signals[CLOSE_REQUEST], 0); } else if (!playing && uri && uri_set) { g_signal_emit (player, signals[OPEN_REQUEST], 0); } g_free (old_uri); }
static void mex_get_stream_cb (MexProgram *program, const gchar *url, const GError *error, gpointer user_data) { MexPlayer *player = user_data; MexPlayerPrivate *priv = player->priv; MexGenericContent *generic_content; #ifdef USE_PLAYER_CLUTTER_GST ClutterGstVideoTexture *video_texture; #endif /* if idle mode has been set before the program stream was found */ if (priv->idle_mode) return; if (G_UNLIKELY (error)) { g_warning ("Could not play content: %s (%s)", error->message, url); return; } #ifdef USE_PLAYER_CLUTTER_GST /* We seek at the precise time when the file is local, but we * seek to key frame when streaming */ video_texture = CLUTTER_GST_VIDEO_TEXTURE (priv->media); if (g_str_has_prefix (url, "file://")) { clutter_gst_video_texture_set_seek_flags (video_texture, CLUTTER_GST_SEEK_FLAG_ACCURATE); } else { clutter_gst_video_texture_set_seek_flags (video_texture, CLUTTER_GST_SEEK_FLAG_NONE); } /* TODO when we have settings we can configure this feature */ if (g_str_has_prefix (mex_content_get_metadata (priv->content, MEX_CONTENT_METADATA_MIMETYPE), "audio/")) { GstElement *gst_element, *visual; gint gst_flags; gst_element = clutter_gst_video_texture_get_pipeline (video_texture); g_object_get (G_OBJECT (gst_element), "flags", &gst_flags, NULL); gst_flags = (GST_PLAY_FLAG_VIS | gst_flags); g_object_set (G_OBJECT (gst_element), "flags", gst_flags, NULL); visual = gst_element_factory_make ("libvisual_infinite", NULL); if (visual) g_object_set (G_OBJECT (gst_element), "vis-plugin", visual, NULL); } #endif clutter_media_set_uri (CLUTTER_MEDIA (priv->media), url); generic_content = MEX_GENERIC_CONTENT (priv->content); if (mex_generic_content_get_last_position_start (generic_content)) clutter_media_set_progress (CLUTTER_MEDIA (priv->media), priv->position); clutter_media_set_playing (CLUTTER_MEDIA (priv->media), TRUE); }
static gboolean _start_video_preview (MexContentTile *self) { MexContentTilePrivate *priv = self->priv; GstElement *pipeline; gint gst_flags; const gchar *mimetype, *uri; /* Check we're still focused */ if (!mex_actor_has_focus (CLUTTER_ACTOR (self))) return FALSE; /* Don't play if the main player is still playing.. * too many videos spoil the broth. */ if (clutter_media_get_playing (mex_player_get_clutter_media (mex_player_get_default ()))) return FALSE; mimetype = mex_content_get_metadata (priv->content, MEX_CONTENT_METADATA_MIMETYPE); if ((mimetype) && strncmp (mimetype, "video/", 6) != 0) return FALSE; if (!(uri = mex_content_get_metadata (priv->content, MEX_CONTENT_METADATA_STREAM))) return FALSE; priv->video_preview = clutter_gst_video_texture_new (); pipeline = clutter_gst_video_texture_get_pipeline (CLUTTER_GST_VIDEO_TEXTURE (priv->video_preview)); g_object_get (G_OBJECT (pipeline), "flags", &gst_flags, NULL); gst_flags = 1;//GST_PLAY_FLAG_VIDEO; g_object_set (G_OBJECT (pipeline), "flags", gst_flags, NULL); clutter_gst_video_texture_set_idle_material (CLUTTER_GST_VIDEO_TEXTURE (priv->video_preview), NULL); g_signal_connect (priv->video_preview, "eos", G_CALLBACK (_stop_video_eos), self); clutter_actor_set_opacity (priv->video_preview, 0); g_object_ref (priv->image); clutter_actor_remove_child (CLUTTER_ACTOR (self), priv->image); clutter_actor_add_child (CLUTTER_ACTOR (self), priv->video_preview); clutter_actor_animate (priv->video_preview, CLUTTER_LINEAR, 500, "opacity", 0xff, NULL); clutter_actor_set_size (priv->video_preview, (gfloat)priv->thumb_width, (gfloat)priv->thumb_height); clutter_media_set_uri (CLUTTER_MEDIA (priv->video_preview), uri); clutter_media_set_playing (CLUTTER_MEDIA (priv->video_preview), TRUE); if (priv->stop_video_preview <= 0) priv->stop_video_preview = g_timeout_add_seconds (180, (GSourceFunc)_stop_video_preview, self); return FALSE; }
int main (int argc, char *argv[]) { ClutterActor *video; GdkPixbuf *shot = NULL; gint duration; CoglHandle tex_id; CoglPixelFormat format; gint size; gint width; gint height; gint rowstride; guchar *data = NULL; #ifdef USE_HELIX clutter_helix_init (&argc, &argv); #else gst_init (&argc, &argv); #endif clutter_init (&argc, &argv); if (argc < 3) { g_print ("Usage: %s <path to movie file> <output png>\n", argv[0]); exit(-1); } totem_resources_monitor_start (argv[1], 60 * G_USEC_PER_SEC); #ifdef USE_HELIX video = clutter_helix_video_texture_new (); #else video = clutter_gst_video_texture_new (); #endif if (argv[1][0] == '/') clutter_media_set_filename(CLUTTER_MEDIA(video), argv[1]); else clutter_media_set_uri(CLUTTER_MEDIA(video), argv[1]); clutter_media_set_volume (CLUTTER_MEDIA(video), 0); clutter_media_set_playing (CLUTTER_MEDIA(video), TRUE); do { while (g_main_context_pending (NULL)) g_main_context_iteration (NULL, FALSE); duration = clutter_media_get_duration (CLUTTER_MEDIA(video)); } while (duration == 0); clutter_actor_realize (video); clutter_media_set_position (CLUTTER_MEDIA(video), duration/3); do { while (g_main_context_pending (NULL)) g_main_context_iteration (NULL, FALSE); } while (clutter_media_get_position (CLUTTER_MEDIA(video)) <= duration/3); tex_id = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (video)); if (tex_id) { format = cogl_texture_get_format (tex_id); size = cogl_texture_get_data (tex_id, format, 0, NULL); width = cogl_texture_get_width (tex_id); height = cogl_texture_get_height (tex_id); rowstride = cogl_texture_get_rowstride (tex_id); data = (guchar*) g_malloc (sizeof(guchar) * size); if (!data) g_error ("malloc");; cogl_texture_get_data (tex_id, format, rowstride, data); shot = gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB, FALSE, 8, width, height, rowstride, NULL, NULL); } totem_resources_monitor_stop (); if (shot) { GdkPixbuf *thumb, *pic; gint x, y, nw, nh, w, h, size; size = 128; /* FIXME swap RGB pixels */ w = clutter_actor_get_width (video); h = clutter_actor_get_height (video); nh = ( h * size) / w; if (nh <= size) { nw = size; x = 0; y = (size - nh) / 2; } else { nw = ( w * size ) / h; nh = size; x = (size - nw) / 2; y = 0; } thumb = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, size, size); gdk_pixbuf_fill (thumb, 0x000000FF); pic = gdk_pixbuf_scale_simple (shot, nw, nh, GDK_INTERP_BILINEAR); gdk_pixbuf_copy_area (pic, 0, 0, nw, nh, thumb, x, y); if (!gdk_pixbuf_save (thumb, argv[2], "png", NULL, NULL)) { g_error ("%s: Pixbuf save failed\n", argv[0]); exit(-1); } g_object_unref (shot); g_object_unref (thumb); g_object_unref (pic); exit(0); } exit (-1); }