libvlc и gtk (для графического интерфейса) не работают вместе?

Я безуспешно пытаюсь использовать libvlc и gtk+ вместе. Я думаю, что есть проблема с функцией libvlc_media_player_set_xwindow(), которую я использую для графического интерфейса. Мой код выглядит следующим образом:

#include <stdio.h>  
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <time.h>
#include <inttypes.h>
#include <vlc/vlc.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>

libvlc_media_t *media_played;
libvlc_media_player_t *is_play;
void Play(gpointer frame, GtkButton * button);
int main(int argc, char **argv)
{
  libvlc_instance_t * instance = libvlc_new(0,NULL);
  libvlc_media_player_t *player = libvlc_media_player_new(instance);
  is_play = player;
  gtk_init(&argc, &argv);
  char Files[256];
  int i =0;
  printf("enter file name plus path, replace scape by '=' character\n");
  scanf("%s", Files);
  for(i = 0; i < 256; i++)
  {
      if(Files[i] == '=') Files[i] = ' ';
  }
  libvlc_media_t *media = libvlc_media_new_path(instance, Files);
  media_played = media;
  libvlc_media_player_set_media(player, media);
  GtkWidget * window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  GtkWidget * table = gtk_table_new(1,2,FALSE);
  GtkWidget * table1 = gtk_table_new(1,1,TRUE);
  GtkWidget *frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
  GtkWidget *button = gtk_button_new_with_mnemonic("_Play");
  g_signal_connect_swapped(GTK_BUTTON(button),"clicked",G_CALLBACK(Play),(gpointer)frame);  
  libvlc_media_player_set_xwindow(player, GDK_WINDOW_XID(frame->window));
  gtk_table_attach(GTK_TABLE(table1),button,0,1,0,1,GTK_FILL,GTK_FILL,0,0);
  gtk_table_attach(GTK_TABLE(table),table1,0,1,0,1,GTK_FILL,GTK_FILL,0,0);
  gtk_table_attach(GTK_TABLE(table),frame,1,2,0,1,GTK_FILL,GTK_FILL,0,0);
  gtk_container_add(GTK_CONTAINER(window),table);
  gtk_widget_show_all(window);
  gtk_main();
  return 0;
}

void Play(gpointer frame, GtkButton * button)
{
   char * title = libvlc_media_get_meta(media_played, libvlc_meta_Title);
   printf("vlc will play: %s\n", title);
   int64_t Time = libvlc_media_get_duration(media_played);
   libvlc_media_player_play(is_play);
   Time = Time/1000;
   clock_t c = clock();
   clock_t t = c;
   while((c/CLOCKS_PER_SEC)<( Time + t))
   {
        c = c + clock();
   }
   gtk_widget_destroy(((GTK_WIDGET(frame)->parent)->parent));
   gtk_main_quit();
}  

При запуске выдает такую ​​ошибку:

(vlc1:7774): Gdk-WARNING **: /build/buildd/gtk+2.0-2.24.10/gdk/x11/gdkdrawable-x11.c:952 drawable is not a pixmap or window 

У кого-то есть решение??


person Narcisse Doudieu Siewe    schedule 03.08.2012    source источник
comment
Я хочу встроить vlc в свой графический интерфейс gtk, но хорошо.   -  person Narcisse Doudieu Siewe    schedule 03.08.2012


Ответы (1)


Проблема, скорее всего, в том, что когда вы делаете вызов libvlc_media_player_set_xwindow в своем коде, frame (или, точнее, окно верхнего уровня) еще не реализовано, а связанное с ним GdkWindow, т.е. frame->window, не создано. Переместите вызов libvlc_media_player_set_xwindow после gtk_widget_show_all(window); в код и проверьте свое приложение.
Рекомендуется использовать gtk_widget_get_window вместо разыменования указателя GtkWidget для получения связанного GdkWindow т.е. gtk_widget_get_window(frame) вместо frame->window
Надеюсь, это поможет!

person another.anon.coward    schedule 03.08.2012
comment
Я пробовал это, эффективно вызывая libvlc_media_player_set_xwindow после того, как работает gtk_widget_show(), но даже с gtk_widget_get_window() libvlc занимает все предоставленное пространство. Кажется, что невозможно рисовать на виджете GtkFrame, потому что он отлично работает с GtkdrawingArea, а фильм занимает именно пространство GtkdrawingArea. - person Narcisse Doudieu Siewe; 03.08.2012
comment
@NarcisseDoudieuSiewe: На самом деле я не использовал libvlc как таковой, но похоже, что вы предоставляете полное окно для рендеринга видео. Когда вы указываете xid окна, видео будет отображаться в окне. Хм, что именно вы ищете? Ограничить область рендеринга видео? - person another.anon.coward; 03.08.2012
comment
@NarcisseDoudieuSiewe: Верно. Фрейм не имеет собственного окна, т. е. с ним не связано окно X11, а вместо этого используется окно верхнего уровня. Но в случае области рисования с ней связано отдельное окно x11, которое не совпадает с окном верхнего уровня. Вот почему используйте наблюдение за поведением - person another.anon.coward; 03.08.2012
comment
У меня есть вопрос, вы сказали, что: похоже, вы предоставляете полное окно для рендеринга видео, но в структуре GtkWidget есть окно вызова члена GdkWindow, которое является объектом GdkDrawable, и я понял, что мы можем рисовать на нем, устанавливать много пикселей на нем и т.д... вот почему я использую frame-›window, но вы сказали, что виджет gtkframe не имеет связанного окна X11 и что он использует окно X11 своего окна верхнего уровня, так что я понял, что frame-› window и window-›window указывают на один и тот же gdkwindow. - person Narcisse Doudieu Siewe; 04.08.2012
comment
Когда я бегло просматриваю сайт gtk+ в справочном руководстве по gtk+, ничто не говорит мне, что этот виджет или этот виджет не имеет окна X11. Не могли бы вы дать мне учебник, который дает мне все эти детали ?? это имеет решающее значение для создания хороших вещей. Большое спасибо за вашу помощь, теперь я точно знаю проблему со многих дней. - person Narcisse Doudieu Siewe; 04.08.2012
comment
@NarcisseDoudieuSiewe: Пара уточнений (возможно, я ввел вас в заблуждение из-за плохой формулировки): GdkWindow, связанный с GtkWidget, не окно X11. GdkWindow происходит абстрагирование окна, а для оконной системы X11 GdkWindow сопоставляется с окном X11. Не обязательно, чтобы для каждого GdkWindow было связано уникальное окно X11. С этим уточнением, когда вы используете GDK_WINDOW_XID, вы пытаетесь получить идентификатор окна X11, связанного с GdkWindow. Таким образом, вы делаете свое приложение непереносимым в других оконных системах, т.е. оно гарантированно будет работать... - person another.anon.coward; 04.08.2012
comment
... только для оконной системы X11. Чтобы определить, имеет ли виджет собственное GdkWindow, вы можете использовать gtk_widget_get_has_window начиная с версии 2.18. Может быть, вы можете работать с этим. Использование области рисования, как вы экспериментировали, может быть хорошим вариантом. GtkDrawingArea имеет свой GdkWindow - person another.anon.coward; 04.08.2012
comment
спасибо, я понял. GdkWindow просто соответствует реальному окну в оконной системе x11, это оболочка, она просто хранит некоторую информацию о соответствующем ресурсе x11. GDK_WINDOW_XID дает нам идентификатор реального окна на X-сервере. Но с gtk+ есть ли другая оконная система, чтобы использовать реальное окно для рисования и т. д.? - person Narcisse Doudieu Siewe; 05.08.2012
comment
@NarcisseDoudieuSiewe: Вы правы. GdkWindow — это абстракция окна. Оно может не совпадать один к одному с окном X11 в новой версии. Существуют и другие оконные системы, например, в Linux есть wayland, для Windows есть win32, Quartz для Mac OS. Вы можете увидеть эти бэкенды в исходниках Gtk. Они предоставляют окна для рендеринга. Для фактического рисования также используется cairo. Структура исходного кода даст много информации обо всех этих - person another.anon.coward; 07.08.2012