GtkMediaStream with gstreamer backend isn't 'prepared' until media is played

This seems to be a problem since:
https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3565

To demo the problem, the video demo in gtk4-demo is currently set to
autoplay, but it doesn't autoplay on load as expected because the
"prepared" notification doesn't fire until the user explicitly presses
play.

Similarly if the demo is tweaked to disable autoplay then on loading a
video (or an audio-only ogg) the duration is not known or shown until
the user presses play.

In LibreOffice we want to know what the size of the video is to position
it before the user can interact with it to set it to play. We can
workaround this to some degree by listening to "invalidate-size" on the
GtkMediaStream object which updates for videos, but that doesn't wor
for audio-only streams.

So restore listening to media-info-updated but ignore -1 (which I see
for audio-only where I get -1 and then a useful value) and 0 of the
original report.

see also:
https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3550

GNOME/gtk!4513
This commit is contained in:
Caolán McNamara 2022-02-24 19:44:08 +00:00
parent ead210c170
commit 82f57c6a93

View File

@ -172,6 +172,23 @@ gtk_gst_media_file_position_updated_cb (GstPlayer *player,
gtk_media_stream_update (GTK_MEDIA_STREAM (self), FROM_GST_TIME (time)); gtk_media_stream_update (GTK_MEDIA_STREAM (self), FROM_GST_TIME (time));
} }
static void
gtk_gst_media_file_media_info_updated_cb (GstPlayer *player,
GstPlayerMediaInfo *media_info,
GtkGstMediaFile *self)
{
/* clock_time == 0: https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/issues/1588
* GstPlayer's first media-info-updated comes with 0 duration
*
* click_time == -1: Seen on loading an audio-only ogg
*/
GstClockTime clock_time = gst_player_media_info_get_duration (media_info);
if (clock_time == 0 || clock_time == -1)
return;
gtk_gst_media_file_ensure_prepared (self);
}
static void static void
gtk_gst_media_file_seek_done_cb (GstPlayer *player, gtk_gst_media_file_seek_done_cb (GstPlayer *player,
GstClockTime time, GstClockTime time,
@ -219,6 +236,7 @@ gtk_gst_media_file_destroy_player (GtkGstMediaFile *self)
if (self->player == NULL) if (self->player == NULL)
return; return;
g_signal_handlers_disconnect_by_func (self->player, gtk_gst_media_file_media_info_updated_cb, self);
g_signal_handlers_disconnect_by_func (self->player, gtk_gst_media_file_position_updated_cb, self); g_signal_handlers_disconnect_by_func (self->player, gtk_gst_media_file_position_updated_cb, self);
g_signal_handlers_disconnect_by_func (self->player, gtk_gst_media_file_end_of_stream_cb, self); g_signal_handlers_disconnect_by_func (self->player, gtk_gst_media_file_end_of_stream_cb, self);
g_signal_handlers_disconnect_by_func (self->player, gtk_gst_media_file_seek_done_cb, self); g_signal_handlers_disconnect_by_func (self->player, gtk_gst_media_file_seek_done_cb, self);
@ -237,6 +255,7 @@ gtk_gst_media_file_create_player (GtkGstMediaFile *file)
self->player = gst_player_new (GST_PLAYER_VIDEO_RENDERER (g_object_ref (self->paintable)), self->player = gst_player_new (GST_PLAYER_VIDEO_RENDERER (g_object_ref (self->paintable)),
gst_player_g_main_context_signal_dispatcher_new (NULL)); gst_player_g_main_context_signal_dispatcher_new (NULL));
g_signal_connect (self->player, "media-info-updated", G_CALLBACK (gtk_gst_media_file_media_info_updated_cb), self);
g_signal_connect (self->player, "position-updated", G_CALLBACK (gtk_gst_media_file_position_updated_cb), self); g_signal_connect (self->player, "position-updated", G_CALLBACK (gtk_gst_media_file_position_updated_cb), self);
g_signal_connect (self->player, "end-of-stream", G_CALLBACK (gtk_gst_media_file_end_of_stream_cb), self); g_signal_connect (self->player, "end-of-stream", G_CALLBACK (gtk_gst_media_file_end_of_stream_cb), self);
g_signal_connect (self->player, "seek-done", G_CALLBACK (gtk_gst_media_file_seek_done_cb), self); g_signal_connect (self->player, "seek-done", G_CALLBACK (gtk_gst_media_file_seek_done_cb), self);