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_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); } }
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 _stop_video_preview (MexContentTile *self) { MexContentTilePrivate *priv = MEX_CONTENT_TILE (self)->priv; if (priv->start_video_preview > 0) g_source_remove (priv->start_video_preview); /* video never started */ if (priv->child == priv->image) return FALSE; if (!priv->video_preview) return FALSE; clutter_media_set_playing (CLUTTER_MEDIA (priv->video_preview), FALSE); clutter_actor_remove_child (CLUTTER_ACTOR (self), priv->video_preview); clutter_actor_add_child (CLUTTER_ACTOR (self), priv->image); /* After setting the child the old child is killed off so NULL this to * help with checks */ priv->video_preview = NULL; return FALSE; }
static int mp_pause(TPMediaPlayer * mp) { USERDATA(mp); CM(ud); clutter_media_set_playing(cm,FALSE); return 0; }
static void mex_media_controls_play_cb (MxButton *toggle, MexMediaControls *self) { MexMediaControlsPrivate *priv = self->priv; if (priv->media) clutter_media_set_playing (priv->media, !clutter_media_get_playing (priv->media)); }
void mex_player_play (MexPlayer *player) { MexPlayerPrivate *priv = player->priv; if (priv->idle_mode) return; clutter_media_set_playing (priv->media, TRUE); }
void mex_music_player_stop (MexMusicPlayer *player) { MexMusicPlayerPrivate *priv; g_return_if_fail (MEX_IS_MUSIC_PLAYER (player)); priv = player->priv; clutter_media_set_playing (priv->player, FALSE); }
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); } }
static int mp_play(TPMediaPlayer * mp) { USERDATA(mp); CM(ud); clutter_media_set_playing(cm,TRUE); if (ud->media_type&TP_MEDIA_TYPE_VIDEO) clutter_actor_show(CLUTTER_ACTOR(cm)); return 0; }
static void mex_media_controls_stop_cb (MxButton *toggle, MexMediaControls *self) { MexMediaControlsPrivate *priv = self->priv; if (priv->media) clutter_media_set_playing (priv->media, FALSE); g_signal_emit (self, signals[STOPPED], 0); }
void mex_player_stop (MexPlayer *player) { MexPlayerPrivate *priv = player->priv; if (priv->idle_mode) return; clutter_media_set_playing (priv->media, FALSE); g_signal_emit (player, signals[CLOSE_REQUEST], 0); }
void mex_music_player_quit (MexMusicPlayer *player) { MexMusicPlayerPrivate *priv; g_return_if_fail (MEX_IS_MUSIC_PLAYER (player)); priv = player->priv; clutter_media_set_playing (priv->player, FALSE); g_signal_emit (player, signals[CLOSE_REQUEST], 0); }
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); }
static void mp_reset(TPMediaPlayer * mp) { USERDATA(mp); CM(ud); disconnect_loading_messages(mp); ud->video_width=0; ud->video_height=0; ud->media_type=0; // Reset should do more - it should truly forget all about the resource clutter_media_set_playing(cm,FALSE); clutter_media_set_progress(cm,0); clutter_actor_hide(CLUTTER_ACTOR(cm)); }
static void mp_end_of_stream(ClutterMedia * cm,TPMediaPlayer * mp) { tp_media_player_end_of_stream(mp); clutter_media_set_playing(cm,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); }
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; }
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); }
int main (int argc, char *argv[]) { ClutterActor *video; /* So we can fade out at the end. */ clutter_x11_set_use_argb_visual (TRUE); if (clutter_gst_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return EXIT_FAILURE; if (argc < 2) { g_print ("Usage: %s [OPTIONS] <video file>\n", argv[0]); return EXIT_FAILURE; } if (!clutter_color_from_string (&bg_color, BG_COLOR)) { g_warning ("Invalid BG_COLOR"); exit (1); } stage = clutter_stage_new (); /* Clutter's full-screening code does not allow us to * set both that and _NET_WM_STATE_ABOVE, so do the state * management ourselves for now. */ #if 0 clutter_stage_set_fullscreen (CLUTTER_STAGE (stage), TRUE); #endif /* Clutter will set maximum size restrictions (meaning not * full screen) unless I set this. */ clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); clutter_stage_set_use_alpha (CLUTTER_STAGE (stage), TRUE); clutter_actor_set_background_color (stage, &bg_color); clutter_actor_set_layout_manager (stage, clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_FIXED, CLUTTER_BIN_ALIGNMENT_FIXED)); clutter_actor_realize (stage); set_above_and_fullscreen (); video = clutter_gst_video_texture_new (); clutter_actor_set_x_expand (video, TRUE); clutter_actor_set_y_expand (video, TRUE); clutter_actor_set_x_align (video, CLUTTER_ACTOR_ALIGN_CENTER); clutter_actor_set_y_align (video, CLUTTER_ACTOR_ALIGN_CENTER); set_idle_material (CLUTTER_GST_VIDEO_TEXTURE (video)); g_signal_connect (video, "eos", G_CALLBACK (on_video_texture_eos), NULL); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); clutter_media_set_filename (CLUTTER_MEDIA (video), argv[1]); clutter_stage_hide_cursor (CLUTTER_STAGE (stage)); clutter_actor_add_child (stage, video); g_signal_connect (stage, "key-press-event", G_CALLBACK (key_press_cb), NULL); clutter_media_set_playing (CLUTTER_MEDIA (video), TRUE); clutter_actor_show (stage); clutter_main (); return EXIT_SUCCESS; }