25 #include <gst/video/videooverlay.h>
27 #if defined (GDK_WINDOWING_X11)
29 #elif defined (GDK_WINDOWING_WIN32)
30 #include <gdk/gdkwin32.h>
71 gtk_range_set_value (GTK_RANGE (player->slider), player->position);
79 gst_element_query_position (player->
pipeline, GST_FORMAT_TIME, &position);
80 player->
position = (gdouble)position / GST_SECOND;
83 return G_SOURCE_CONTINUE;
131 gtk_image_set_from_icon_name (GTK_IMAGE (gtk_button_get_image (GTK_BUTTON (player->
play_button))),
132 player->
is_playing ?
"media-playback-pause-symbolic" :
"media-playback-start-symbolic",
140 GstState state, pending;
143 gst_element_get_state (player->
pipeline, &state, &pending, 250 * GST_NSECOND);
145 is_playing = state == GST_STATE_PLAYING;
159 GstState current, pending, new_state;
164 gst_element_get_state (player->
pipeline, ¤t, &pending, 0);
165 new_state = current == GST_STATE_PLAYING ? GST_STATE_PAUSED : GST_STATE_PLAYING;
166 if (pending != new_state)
167 gst_element_set_state (player->
pipeline, new_state);
172 GtkScrollType scroll,
178 position = CLAMP (position, 0, player->
duration);
179 if (gst_element_seek_simple (player->
pipeline,
182 (gint64)(position * GST_SECOND))) {
196 gtk_widget_destroy (GTK_WIDGET (player));
204 gst_element_set_state (player->
pipeline, GST_STATE_READY);
207 static GstBusSyncReply
212 GstVideoOverlay *overlay;
214 if (!gst_is_video_overlay_prepare_window_handle_message (message))
217 overlay = GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message));
218 gst_video_overlay_set_window_handle (overlay, (guintptr)player->
window_handle);
219 gst_video_overlay_expose (overlay);
223 gst_message_unref (message);
233 switch (GST_MESSAGE_TYPE (message)) {
234 case GST_MESSAGE_ERROR: {
235 GError *error = NULL;
238 gst_message_parse_error (message, &error, &dbg);
239 g_warning (
"Error: %s (%s)\n", error->message, dbg);
240 g_error_free (error);
244 case GST_MESSAGE_STATE_CHANGED:
245 if (GST_MESSAGE_SRC (message) != (GstObject *)player->
pipeline)
252 case GST_MESSAGE_ASYNC_DONE: {
255 if (GST_MESSAGE_SRC (message) != (GstObject *)player->
pipeline)
268 if (player->
duration == 0 && (state == GST_STATE_PAUSED || state == GST_STATE_PLAYING)) {
271 gst_element_query_duration (player->
pipeline, GST_FORMAT_TIME, &duration);
272 player->
duration = (gdouble)duration / GST_SECOND;
273 gtk_range_set_range (GTK_RANGE (player->
slider), 0, player->
duration);
279 case GST_MESSAGE_EOS:
293 #if defined (GDK_WINDOWING_X11)
294 player->
window_handle = (guint64)GDK_WINDOW_XID (gtk_widget_get_window (widget));
295 #elif defined (GDK_WINDOWING_WIN32)
296 player->
window_handle = (guint64)GDK_WINDOW_HWND (gtk_widget_get_window (widget));
298 g_assert_not_reached ();
304 GtkAllocation *allocation)
307 GdkRectangle controls_allocation;
309 GTK_WIDGET_CLASS (ev_media_player_parent_class)->size_allocate (widget, allocation);
315 gtk_widget_size_allocate (player->
drawing_area, allocation);
318 controls_allocation.x = allocation->x;
319 controls_allocation.y = allocation->y + allocation->height;
320 controls_allocation.width = allocation->width;
321 controls_allocation.height = gtk_widget_get_allocated_height (player->
controls);
322 gtk_widget_size_allocate (player->
controls, &controls_allocation);
324 allocation->height += controls_allocation.height;
326 gtk_widget_set_allocation (widget, allocation);
337 gst_bus_remove_signal_watch (player->
bus);
338 gst_object_unref (player->
bus);
343 gst_element_set_state (player->
pipeline, GST_STATE_NULL);
344 gst_object_unref (player->
pipeline);
348 g_clear_object (&player->
media);
350 G_OBJECT_CLASS (ev_media_player_parent_class)->dispose (
object);
366 G_OBJECT_WARN_INVALID_PROPERTY_ID (
object, prop_id, pspec);
373 gtk_orientable_set_orientation (GTK_ORIENTABLE (player), GTK_ORIENTATION_VERTICAL);
375 player->
pipeline = gst_element_factory_make (
"playbin", NULL);
377 g_warning (
"Failed to create playbin\n");
388 player->
bus = gst_pipeline_get_bus (GST_PIPELINE (player->
pipeline));
389 gst_bus_set_sync_handler (player->
bus, (GstBusSyncHandler)
bus_sync_handle, player, NULL);
390 gst_bus_add_signal_watch (player->
bus);
391 g_signal_connect_object (player->
bus,
"message",
399 GtkAdjustment *adjustment;
400 GtkCssProvider *provider;
402 player->
controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
404 gtk_style_context_add_class (gtk_widget_get_style_context (player->
controls), GTK_STYLE_CLASS_OSD);
407 g_signal_connect_swapped (player->
play_button,
"clicked",
410 gtk_widget_set_name (player->
play_button,
"ev-media-player-play-button");
411 gtk_widget_set_valign (player->
play_button, GTK_ALIGN_CENTER);
412 gtk_button_set_relief (GTK_BUTTON (player->
play_button), GTK_RELIEF_NONE);
413 gtk_button_set_image (GTK_BUTTON (player->
play_button),
414 gtk_image_new_from_icon_name (
"media-playback-start-symbolic",
415 GTK_ICON_SIZE_MENU));
416 gtk_button_set_label(GTK_BUTTON (player->
play_button), NULL);
419 provider = gtk_css_provider_new ();
420 gtk_css_provider_load_from_data (provider,
"#ev-media-player-play-button { padding: 0px 8px 0px 8px; }", -1, NULL);
421 gtk_style_context_add_provider (gtk_widget_get_style_context (player->
play_button),
422 GTK_STYLE_PROVIDER (provider),
423 GTK_STYLE_PROVIDER_PRIORITY_USER);
424 g_object_unref (provider);
429 adjustment = gtk_adjustment_new (0, 0, 1, 0.1, 0.10, 0);
430 player->
slider = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
431 g_signal_connect_swapped (player->
slider,
"change-value",
434 gtk_widget_set_hexpand (player->
slider,
TRUE);
435 gtk_scale_set_draw_value (GTK_SCALE (player->
slider),
FALSE);
437 gtk_widget_show (player->
slider);
448 G_OBJECT_CLASS (ev_media_player_parent_class)->constructed (
object);
457 gst_element_set_state (player->
pipeline, GST_STATE_PLAYING);
463 GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
464 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
466 if (!gst_is_initialized ()) {
467 GError *error = NULL;
469 if (!gst_init_check (NULL, NULL, &error)) {
470 g_warning (
"Failed to initialize GStreamer: %s\n", error->message);
471 g_error_free (error);
480 g_object_class_install_property (g_object_class,
482 g_param_spec_object (
"media",
484 "The media played by the player",
487 G_PARAM_CONSTRUCT_ONLY |
488 G_PARAM_STATIC_STRINGS));
504 return player->
media;