You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:Gstreamer1.0+GTK+3.0无法将视频嵌入指定GtkWidget,视频弹出新窗口

Hey there! Let's figure out why your video keeps opening in a new window instead of embedding into your target GtkWidget. I’ve run into similar quirks on older Ubuntu releases, so here’s what to check and fix:

Possible Causes & Fixes

1. You’re Not Properly Binding the Video Sink to Your GtkWidget’s Window Handle

Both GStreamer and LibVLC require explicit binding to your widget’s X11 window ID to embed video. Skip this step, and the library will default to creating a new window. The key detail here: you can only get a valid XID after the widget has been realized (i.e., drawn to the screen).

For GStreamer:

First, use a sink that supports X11 embedding (avoid autovideosink—it might pick a Wayland-compatible sink that doesn’t support embedding):

sink = gst_element_factory_make("xvimagesink", "video-sink");
// Use "ximagesink" if xvimagesink isn’t available on your system

Then bind the sink to your widget’s window ID, either immediately (if the widget is already realized) or via a signal callback:

// Assume your target container widget is GtkWidget *video_container;

static void on_widget_realized(GtkWidget *widget, GstElement *sink) {
    // Grab the X11 window ID of the widget
    Window xwin = gdk_x11_window_get_xid(gtk_widget_get_window(widget));
    // Attach the sink to the widget’s window
    GstVideoOverlay *overlay = GST_VIDEO_OVERLAY(sink);
    gst_video_overlay_set_window_handle(overlay, xwin);
}

// In your main setup:
if (gtk_widget_get_realized(video_container)) {
    // Widget is already ready—set the handle right away
    on_widget_realized(video_container, sink);
} else {
    // Wait for the widget to be realized before binding
    g_signal_connect(video_container, "realize", G_CALLBACK(on_widget_realized), sink);
}

For LibVLC:

The logic is identical—pass your widget’s XID to the media player once the widget is realized:

// Assume you have a libvlc_media_player_t *player;
// And your target widget is GtkWidget *video_container;

static void on_vlc_widget_realized(GtkWidget *widget, libvlc_media_player_t *player) {
    unsigned long xid = gdk_x11_window_get_xid(gtk_widget_get_window(widget));
    libvlc_media_player_set_xwindow(player, xid);
}

// In your setup:
if (gtk_widget_get_realized(video_container)) {
    on_vlc_widget_realized(video_container, player);
} else {
    g_signal_connect(video_container, "realize", G_CALLBACK(on_vlc_widget_realized), player);
}

2. Wayland Might Be Blocking Embedding (Ubuntu 17.10 Default)

Ubuntu 17.10 uses GNOME on Wayland by default, and Wayland has poor support for X11 window embedding—this is likely the root cause if both GStreamer and LibVLC behave the same way.

Fix: Switch to an Xorg session when logging in:

  • At the Ubuntu login screen, click the gear icon in the bottom-right corner.
  • Select Ubuntu on Xorg from the menu, then log in as usual.

3. Double-Check Your GStreamer Pipeline

If you’re using autovideosink, it might be selecting a non-embeddable sink (like waylandsink). Force it to use an X11-compatible sink as shown earlier. Also, ensure your pipeline is fully linked and set to the PLAYING state after binding the window handle.


内容的提问来源于stack exchange,提问作者Станислав Гичак

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:40:36