static void on_got_metadata_event (BaconVideoWidget *bvw, callback_data *data) { GValue value = { 0, }; GdkPixbuf *pixbuf; PROGRESS_DEBUG("Got metadata, checking if we have a cover"); bacon_video_widget_get_metadata (bvw, BVW_INFO_COVER, &value); pixbuf = g_value_dup_object (&value); g_value_unset (&value); if (pixbuf) { PROGRESS_DEBUG("Saving cover image"); bacon_video_widget_close (bvw); totem_resources_monitor_stop (); gtk_widget_destroy (GTK_WIDGET (bvw)); save_pixbuf (pixbuf, data->output, data->input, output_size, TRUE); g_object_unref (pixbuf); exit (0); } else if (has_video (bvw) == FALSE) { PROGRESS_DEBUG("No covers, and no video, exiting"); exit (0); } }
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); }
int main (int argc, char *argv[]) { GOptionGroup *options; GOptionContext *context; GError *err = NULL; BaconVideoWidget *bvw; GdkPixbuf *pixbuf; const char *input, *output; callback_data data; g_thread_init (NULL); context = g_option_context_new ("Thumbnail movies"); options = bacon_video_widget_get_option_group (); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); g_option_context_add_group (context, options); #ifndef THUMB_DEBUG g_type_init (); #else g_option_context_add_group (context, gtk_get_option_group (TRUE)); #endif if (g_option_context_parse (context, &argc, &argv, &err) == FALSE) { g_print ("couldn't parse command-line options: %s\n", err->message); g_error_free (err); return 1; } #ifdef G_OS_UNIX if (time_limit != FALSE) { errno = 0; if (nice (20) != 20 && errno != 0) g_warning ("Couldn't change nice value of process."); } #endif if (print_progress) { fcntl (fileno (stdout), F_SETFL, O_NONBLOCK); setbuf (stdout, NULL); } if (g_fatal_warnings) { GLogLevelFlags fatal_mask; fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; g_log_set_always_fatal (fatal_mask); } if (raw_output == FALSE && output_size == -1) output_size = DEFAULT_OUTPUT_SIZE; if (filenames == NULL || g_strv_length (filenames) != 2 || (second_index != -1 && gallery != -1) || (print_progress == TRUE && verbose == TRUE)) { char *help; help = g_option_context_get_help (context, FALSE, NULL); g_print ("%s", help); g_free (help); return 1; } input = filenames[0]; output = filenames[1]; PROGRESS_DEBUG("Initialised libraries, about to create video widget"); PRINT_PROGRESS (2.0); bvw = BACON_VIDEO_WIDGET (bacon_video_widget_new (-1, -1, BVW_USE_TYPE_CAPTURE, &err)); if (err != NULL) { g_print ("totem-video-thumbnailer couldn't create the video " "widget.\nReason: %s.\n", err->message); g_error_free (err); exit (1); } data.input = input; data.output = output; g_signal_connect (G_OBJECT (bvw), "got-metadata", G_CALLBACK (on_got_metadata_event), &data); PROGRESS_DEBUG("Video widget created"); PRINT_PROGRESS (6.0); if (time_limit != FALSE) totem_resources_monitor_start (input, 0); PROGRESS_DEBUG("About to open video file"); if (bacon_video_widget_open (bvw, input, NULL, &err) == FALSE) { g_print ("totem-video-thumbnailer couldn't open file '%s'\n" "Reason: %s.\n", input, err->message); g_error_free (err); exit (1); } PROGRESS_DEBUG("Opened video file: '%s'", input); PRINT_PROGRESS (10.0); if (gallery == -1) { /* If the user has told us to use a frame at a specific second * into the video, just use that frame no matter how boring it * is */ if (second_index != -1) pixbuf = capture_frame_at_time (bvw, input, output, second_index); else pixbuf = capture_interesting_frame (bvw, input, output); PRINT_PROGRESS (90.0); } else { /* We're producing a gallery of screenshots from throughout the file */ pixbuf = create_gallery (bvw, input, output); } /* Cleanup */ bacon_video_widget_close (bvw); totem_resources_monitor_stop (); gtk_widget_destroy (GTK_WIDGET (bvw)); PRINT_PROGRESS (92.0); if (pixbuf == NULL) { g_print ("totem-video-thumbnailer couldn't get a picture from " "'%s'\n", input); exit (1); } PROGRESS_DEBUG("Saving captured screenshot"); save_pixbuf (pixbuf, output, input, output_size, FALSE); g_object_unref (pixbuf); PRINT_PROGRESS (100.0); return 0; }
int main (int argc, char **argv) { FT_Error error; FT_Library library; FT_Face face; GFile *file; gint font_size, thumb_size = THUMB_SIZE; gchar *thumbstr_utf8 = NULL, *help, *uri; gchar **arguments = NULL; GOptionContext *context; GError *gerror = NULL; gchar *contents = NULL; gboolean retval, default_thumbstr = TRUE; gint rv = 1; GdkRGBA white = { 1.0, 1.0, 1.0, 1.0 }; GdkRGBA black = { 0.0, 0.0, 0.0, 1.0 }; cairo_surface_t *surface; cairo_t *cr; cairo_text_extents_t text_extents; cairo_font_face_t *font; gchar *str; gdouble scale, scale_x, scale_y; const GOptionEntry options[] = { { "text", 't', 0, G_OPTION_ARG_STRING, &thumbstr_utf8, N_("Text to thumbnail (default: Aa)"), N_("TEXT") }, { "size", 's', 0, G_OPTION_ARG_INT, &thumb_size, N_("Thumbnail size (default: 128)"), N_("SIZE") }, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &arguments, NULL, N_("FONT-FILE OUTPUT-FILE") }, { NULL } }; bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); setlocale (LC_ALL, ""); g_type_init (); context = g_option_context_new (NULL); g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE); retval = g_option_context_parse (context, &argc, &argv, &gerror); if (!retval) { g_printerr ("Error parsing arguments: %s\n", gerror->message); g_option_context_free (context); g_error_free (gerror); return 1; } if (!arguments || g_strv_length (arguments) != 2) { help = g_option_context_get_help (context, TRUE, NULL); g_printerr ("%s", help); g_option_context_free (context); goto out; } g_option_context_free (context); if (thumbstr_utf8 != NULL) default_thumbstr = FALSE; error = FT_Init_FreeType (&library); if (error) { g_printerr("Could not initialise freetype: %s\n", get_ft_error (error)); goto out; } totem_resources_monitor_start (arguments[0], 30 * G_USEC_PER_SEC); file = g_file_new_for_commandline_arg (arguments[0]); uri = g_file_get_uri (file); g_object_unref (file); face = sushi_new_ft_face_from_uri (library, uri, &contents, &gerror); if (gerror) { g_printerr ("Could not load face '%s': %s\n", uri, gerror->message); g_free (uri); g_error_free (gerror); goto out; } g_free (uri); if (default_thumbstr) { if (check_font_contain_text (face, "Aa")) str = g_strdup ("Aa"); else str = build_fallback_thumbstr (face); } else { str = thumbstr_utf8; } surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, thumb_size, thumb_size); cr = cairo_create (surface); gdk_cairo_set_source_rgba (cr, &white); cairo_paint (cr); font = cairo_ft_font_face_create_for_ft_face (face, 0); cairo_set_font_face (cr, font); cairo_font_face_destroy (font); font_size = thumb_size - 2 * PADDING_VERTICAL; cairo_set_font_size (cr, font_size); cairo_text_extents (cr, str, &text_extents); if ((text_extents.width) > (thumb_size - 2 * PADDING_HORIZONTAL)) { scale_x = (gdouble) (thumb_size - 2 * PADDING_HORIZONTAL) / (text_extents.width); } else { scale_x = 1.0; } if ((text_extents.height) > (thumb_size - 2 * PADDING_VERTICAL)) { scale_y = (gdouble) (thumb_size - 2 * PADDING_VERTICAL) / (text_extents.height); } else { scale_y = 1.0; } scale = MIN (scale_x, scale_y); cairo_scale (cr, scale, scale); cairo_translate (cr, PADDING_HORIZONTAL - text_extents.x_bearing + (thumb_size - scale * text_extents.width) / 2.0, PADDING_VERTICAL - text_extents.y_bearing + (thumb_size - scale * text_extents.height) / 2.0); gdk_cairo_set_source_rgba (cr, &black); cairo_show_text (cr, str); cairo_destroy (cr); cairo_surface_write_to_png (surface, arguments[1]); cairo_surface_destroy (surface); totem_resources_monitor_stop (); error = FT_Done_Face (face); if (error) { g_printerr("Could not unload face: %s\n", get_ft_error (error)); goto out; } error = FT_Done_FreeType (library); if (error) { g_printerr ("Could not finalize freetype library: %s\n", get_ft_error (error)); goto out; } rv = 0; /* success */ out: g_strfreev (arguments); g_free (str); g_free (contents); return rv; }