我的英语不好。如果您不明白,请提供更清楚的说明。我在Allwinnwer A13上有一个GUI。为此,我使用Gtk3.0
。另外,我在GUI上播放视频,并使用gstreamer1.0
播放视频。我用林间空地创建了GUI。
GUI在播放视频时,同时在必要的时候播放信息消息。信息消息文件为.wav
。如果我不使用信息消息,则视频会再次重复播放。如果我使用信息消息(可用性20次),视频开始收缩。我尝试清理到gst_element_set_state
,但似乎不起作用。如何解决此问题?我的代码如下。我刚刚写了关于这个主题的文章。如果需要所有代码,请告诉我。
#include <string.h>
#include <stdbool.h>
#include <gtk/gtk.h>
#include <gst/gst.h>
#include <cairo.h>
#include <gst/video/videooverlay.h>
#include "uart.h"
#include "global.h"
#include <gdk/gdk.h>
#if defined (GDK_WINDOWING_X11)
#include <gdk/gdkx.h>
#elif defined (GDK_WINDOWING_WIN32)
#include <gdk/gdkwin32.h>
#elif defined (GDK_WINDOWING_QUARTZ)
#include <gdk/gdkquartz.h>
#endif
/* Structure to contain all our information, so we can pass it around */
typedef struct _CustomData {
GstElement *playbin, *videosink, *announce; /* Our one and only pipeline */
GtkImage *image; // image definition
GtkBuilder *builder; //builder definition
GtkFixed *fixed; // Fixed
GtkWidget *label1, *label2; //label definition
GtkWidget *slider; /* Slider widget to keep track of current position */
GtkWidget *streams_list; /* Text widget to display info about the streams */
gulong slider_update_signal_id; /* Signal ID for the slider update signal */
GstState state; /* Current state of the pipeline */
gint64 duration; /* Duration of the clip, in nanoseconds */
} CustomData;
static void create_ui (CustomData *data) {
GtkWidget *main_window; /* The uppermost window, containing all other windows */
GtkWidget *video_window; /* The drawing area where the video will be shown */
GtkWidget *main_box; /* VBox to hold main_hbox and the controls */
main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT (main_window), "delete-event", G_CALLBACK (delete_event_cb), data);
video_window = gtk_drawing_area_new ();
gtk_widget_set_double_buffered (video_window, FALSE);
g_signal_connect (video_window, "realize", G_CALLBACK (realize_cb), data);
g_signal_connect (video_window, "draw", G_CALLBACK (draw_cb), data);
data->slider = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0, 100, 1);
gtk_scale_set_draw_value (GTK_SCALE (data->slider), 0);
data->slider_update_signal_id = g_signal_connect (G_OBJECT (data->slider), "value-changed", G_CALLBACK (slider_cb), data);
data->streams_list = gtk_text_view_new ();
gtk_text_view_set_editable (GTK_TEXT_VIEW (data->streams_list), FALSE);
data->builder = gtk_builder_new();
gtk_builder_add_from_file(data->builder,"/home/olimex/Desktop/NewGUI/GUI_test/builder.glade",NULL);
main_window=GTK_WINDOW(gtk_builder_get_object(data->builder,"window")); //Definition window of glade
gtk_builder_connect_signals(data->builder,NULL);
data->fixed=GTK_WIDGET(gtk_builder_get_object(data->builder,"fixed2"));
data->image=gtk_image_new_from_file("/home/olimex/Desktop/NewGUI/GUI_test/upArrow2.png");
data->image=GTK_WIDGET(gtk_builder_get_object(data->builder,"image1")); // Definition image of glade
data->label1=GTK_WIDGET(gtk_builder_get_object(data->builder,"label4")); // Definition label4 of glade
data->label2=GTK_WIDGET(gtk_builder_get_object(data->builder,"label5")); // Definition label5 of glade
main_box=GTK_WIDGET(gtk_builder_get_object(data->builder,"box1")); // Definition video box of glade
gtk_box_pack_start(GTK_BOX(main_box), video_window,TRUE,TRUE,0); // video play in GUI window
gtk_window_set_decorated(GTK_WINDOW(main_window),FALSE); //Hide menu bar
gtk_container_add(GTK_CONTAINER(main_window),main_box);
//gtk_widget_reparent(main_window,main_box);
gtk_label_set_markup(GTK_LABEL(data->label1), "<span foreground=\"white\" font=\"Arial\" size='150050'>0</span>"); // if use one number size should be 300100. setting color and size
gtk_label_set_markup(GTK_LABEL(data->label2), "<span foreground=\"white\" font=\"Arial\" size='150050'>0</span>"); // if use one number size should be 300100
GdkRGBA color;
gdk_rgba_parse(&color,"#2080FF");
gtk_widget_override_background_color(main_window, GTK_STATE_FLAG_NORMAL, &color);
g_object_unref(data->builder);
gtk_widget_show_all (main_window);
}
/* This function is called periodically to refresh the GUI */
static gboolean refresh_ui (CustomData *data) {
gint64 current = -1;
char announceBuffer[128];
int a=0;
gint x1; //for place of label1
gint y1;
gint x2; //for place of label2
gint y2;
recv_data ();
sprintf(printBuffer1, "<span foreground=\"white\" font=\"Arial\" size='150050'>%c</span>", floorLevel1);
sprintf(printBuffer2, "<span foreground=\"white\" font=\"Arial\" size='150050'>%c</span>", floorLevel2);
gtk_label_set_markup(GTK_LABEL(data->label1), printBuffer1); // if use one number size should be 300100
gtk_label_set_markup(GTK_LABEL(data->label2), printBuffer2); // if use one number size should be 300100
if(floorLevel1=='-' || (floorLevel1>='1' && floorLevel1<='4'))
{
snprintf(announceBuffer,sizeof(announceBuffer),"playbin uri=file:///home/olimex/Desktop/TR/%c%c.wav",floorLevel1,floorLevel2);
}
else
{
if(floorLevel1=='0')
snprintf(announceBuffer,sizeof(announceBuffer),"playbin uri=file:///home/olimex/Desktop/TR/%c.wav",floorLevel1);
else
snprintf(announceBuffer,sizeof(announceBuffer),"playbin uri=file:///home/olimex/Desktop/TR/%c.wav",floorLevel2);
}
if (travelDownDirectionFlag==1){
x1=250;
y1=0;
x2=350;
y2=0;
if (floorLevel1=='0')
{ printf("floorlevel 0");
gtk_widget_hide(data->label2);
x1=350;
y1=0;
}
else
gtk_widget_show(data->label2);
//gtk_widget_show(data->label2);
gtk_fixed_move(data->fixed, data->label1, x1, y1);
gtk_fixed_move(data->fixed, data->label2, x2, y2);
gtk_image_set_from_file(data->image,"/home/olimex/Desktop/NewGUI/GUI_test/downArrow2.png");
announceFlag=true;
if (announceFlag==false)
{ data->announce=gst_parse_launch(NULL,NULL); //Build floorLevel announce
gst_element_set_state(data->announce, GST_STATE_NULL);
g_object_unref(data->announce);
}
announceFlag=true;
}
else if (travelUpDirectionFlag==1)
{
x1=250;
y1=0;
x2=350;
y2=0;
if (floorLevel1=='0')
{
gtk_widget_hide(data->label2);
x1=350;
y1=0;
}
else
gtk_widget_show(data->label2);
gtk_fixed_move(data->fixed, data->label1, x1, y1); //set place label1
gtk_fixed_move(data->fixed, data->label2, x2, y2); //set place label2
gtk_image_set_from_file(data->image,"/home/olimex/Desktop/NewGUI/GUI_test/upArrow2.png");
announceFlag=true;
if (announceFlag==false)
{
data->announce=gst_parse_launch(NULL,NULL); //Build floorLevel announce
gst_element_set_state(data->announce, GST_STATE_NULL);
g_object_unref(data->announce);
}
announceFlag=true;
}
else
{
x1=120;
y1=0;
x2=220;
y2=0;
if (floorLevel1=='0')
{
gtk_widget_hide(data->label2);
x1=150;
y1=0;
}
else
gtk_widget_show(data->label2);
gtk_image_set_from_file(data->image,NULL);
gtk_fixed_move(data->fixed, data->label1, x1, y1); //set place label1
gtk_fixed_move(data->fixed, data->label2, x2, y2); //set place label2
if (announceFlag==true)
{
data->announce=gst_parse_launch(announceBuffer,NULL);
gst_element_set_state(data->announce, GST_STATE_PLAYING); //Start playing floorLevel
announceFlag=false;
}
}
/* We do not want to update anything unless we are in the PAUSED or PLAYING states */
if (data->state < GST_STATE_PAUSED)
return TRUE;
/* If we didn't know it yet, query the stream duration */
if (!GST_CLOCK_TIME_IS_VALID (data->duration)) {
if (!gst_element_query_duration (data->playbin, GST_FORMAT_TIME, &data->duration)) {
g_printerr ("Could not query current duration.\n");
} else {
/* Set the range of the slider to the clip duration, in SECONDS */
gtk_range_set_range (GTK_RANGE (data->slider), 0, (gdouble)data->duration / GST_SECOND);
}
}
if (gst_element_query_position (data->playbin, GST_FORMAT_TIME, ¤t)) {
}
return TRUE;
}
int main(int argc, char *argv[]) {
CustomData data;
GstStateChangeReturn ret;
GstBus *bus;
GstMessage *msg;
/* Initialize GTK */
gtk_init (&argc, &argv);
/* Initialize GStreamer */
gst_init (&argc, &argv);
/* Initialize our data structure */
memset (&data, 0, sizeof (data));
data.duration = GST_CLOCK_TIME_NONE;
/* Create the elements */
data.playbin = gst_element_factory_make ("playbin","playbin");
if (!data.playbin) {
g_printerr ("Not all elements could be created.\n");
return -1;
}
/* Set the URI to play */
//g_object_set (data.playbin, "uri", "https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm", NULL);
//g_object_set(data.playbin,"video-sink",NULL); Warning veriyor
g_object_set(data.playbin,"uri","file:///home/olimex/Desktop/sample.mp4",NULL);
data.announce=gst_parse_launch("playbin uri=file:///home/olimex/Desktop/TR/1.wav",NULL); //Build annonce. Firt play is empty.
gst_element_set_state(data.announce, GST_STATE_PLAYING); //Start playing
bus=gst_element_get_bus(data.announce); //Wait until error
msg=gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS); //Wait until EOS
//free resource
if(msg != NULL)
gst_message_unref(msg);
gst_object_unref(bus);
gst_element_set_state(data.announce,GST_STATE_NULL);
gst_object_unref(data.announce);
/* Connect to interesting signals in playbin */
g_signal_connect (G_OBJECT (data.playbin), "video-tags-changed", (GCallback) tags_cb, &data);
g_signal_connect (G_OBJECT (data.playbin), "audio-tags-changed", (GCallback) tags_cb, &data);
g_signal_connect (G_OBJECT (data.playbin), "text-tags-changed", (GCallback) tags_cb, &data);
/* Create the GUI */
create_ui (&data);
/* Instruct the bus to emit signals for each received message, and connect to the interesting signals */
bus = gst_element_get_bus (data.playbin);
gst_bus_add_signal_watch (bus);
g_signal_connect (G_OBJECT (bus), "message::error", (GCallback)error_cb, &data);
g_signal_connect (G_OBJECT (bus), "message::eos", (GCallback)eos_cb, &data);
g_signal_connect (G_OBJECT (bus), "message::state-changed", (GCallback)state_changed_cb, &data);
g_signal_connect (G_OBJECT (bus), "message::application", (GCallback)application_cb, &data);
gst_object_unref (bus);
/* Start playing */
ret = gst_element_set_state (data.playbin, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
g_printerr ("Unable to set the pipeline to the playing state.\n");
gst_object_unref (data.playbin);
return -1;
}
UartInit();
/* Register a function that GLib will call every second */
g_timeout_add_seconds (1, (GSourceFunc)refresh_ui, &data);
/* Start the GTK main loop. We will not regain control until gtk_main_quit is called. */
gtk_main ();
/* Free resources */
gst_element_set_state (data.playbin, GST_STATE_NULL);
gst_object_unref (data.playbin);
return 0;
}