Wxwidgets GStreamer GSTBussynchronizandler停止、暂停和播放状态

Wxwidgets GStreamer GSTBussynchronizandler停止、暂停和播放状态,wxwidgets,gstreamer,Wxwidgets,Gstreamer,我使用Gstreamer作为播放视频和音频的基础,到目前为止,它工作正常。现在我想知道媒体何时停止、暂停、加载或开始播放,并通知GUI。现在,这些消息不断重复(请参见附图)。现在在这种情况下,它将淹没我的GUI。我只想接收一次事件(例如,当媒体停止或暂停或加载时)。 我得到的唯一一致的信息(一次)是流的结束 有没有一种方法可以在上述信息发生时只获得一次? 这是我目前的代码 extern "C" { static GstBusSyncReply bus_sync(GstBus* b

我使用Gstreamer作为播放视频和音频的基础,到目前为止,它工作正常。现在我想知道媒体何时停止、暂停、加载或开始播放,并通知GUI。现在,这些消息不断重复(请参见附图)。现在在这种情况下,它将淹没我的GUI。我只想接收一次事件(例如,当媒体停止或暂停或加载时)。 我得到的唯一一致的信息(一次)是流的结束

有没有一种方法可以在上述信息发生时只获得一次? 这是我目前的代码

extern "C"
{
    static GstBusSyncReply
    bus_sync(GstBus* bus, GstMessage* message, gpointer user_data)
    {
        CustomData* data = reinterpret_cast<CustomData*>(user_data);

        GstState old_state, new_state, pending;             
        gst_message_parse_state_changed(message, &old_state, &new_state, &pending);
        g_print ("State set from %s to %s --- %s\n", gst_element_state_get_name (old_state), gst_element_state_get_name (new_state), gst_element_state_get_name (pending));

        switch(GST_MESSAGE_TYPE(message))
        {
            case GST_MESSAGE_STATE_CHANGED:
            {
                wxGStreamer* win = dynamic_cast<wxGStreamer*>(data->parent);
                if(win)
                {
                    win->SendMessage(wxMEDIASTATE_CHANGED); 
                }               

                if(data->state!=new_state)
                {
                    //state changed, save it
                    data->state = new_state; 

                    if(old_state==GST_STATE_NULL && new_state == GST_STATE_READY && pending== GST_STATE_PLAYING)
                    {
                        g_print ("***Loaded***\n");
                    } 
                    else if(old_state==GST_STATE_PLAYING && new_state == GST_STATE_PAUSED && pending== GST_STATE_VOID_PENDING)
                    {
                        g_print ("***Paused***\n");
                    }
                    else if(old_state==GST_STATE_READY && new_state == GST_STATE_NULL && pending== GST_STATE_VOID_PENDING)
                    {
                        g_print ("***Stopped***\n");
                    } 
                    else if(new_state == GST_STATE_PLAYING &&(old_state==GST_STATE_READY||old_state==GST_STATE_PAUSED) )
                    {
                        g_print ("***Playing***\n");
                    } 
                }
                break;
            }
        }  
    }
}
extern“C”
{
静态GstBusSyncReply
总线同步(GstBus*总线、GstMessage*消息、gpointer用户数据)
{
CustomData*data=重新解释(用户数据);
GST州旧州、新州、待定;
gst_消息_解析_状态_更改(消息、旧状态、新状态和待定);
g_print(“从%s到%s的状态设置---%s\n”、gst_元素状态获取名称(旧状态)、gst_元素状态获取名称(新状态)、gst_元素状态获取名称(待定));
开关(GST\信息\类型(信息))
{
案例GST\消息\状态\更改:
{
wxGStreamer*win=动态施法(数据->父级);
如果(赢)
{
win->SendMessage(wxMEDIASTATE\u已更改);
}               
如果(数据->状态!=新状态)
{
//状态已更改,请保存它
数据->状态=新状态;
如果(旧状态==GST\U状态\U NULL和新状态==GST\U状态\U就绪和挂起==GST\U状态\U播放)
{
g_打印(“***加载***\n”);
} 
否则,如果(旧状态==GST\U状态\播放和新状态==GST\U状态\暂停和挂起==GST\U状态\无效\挂起)
{
g_print(“***暂停***\n”);
}
else if(旧州==GST\U州\准备就绪和新州==GST\U州\空和待决==GST\U州\无效\待决)
{
g_打印(“***停止***\n”);
} 
否则,如果(新状态==GST状态&&(旧状态==GST状态|就绪|旧状态==GST状态|暂停))
{
g_print(“***播放***\n”);
} 
}
打破
}
}  
}
}

简单地回答:除了播放/停止状态,您可以从GstBus收到更多的消息。 在代码中实现一个开关,并且只调用一次if/else语句:

switch (GST_MESSAGE_TYPE (msg)) {
  case GST_MESSAGE_ERROR:
    break;
  case GST_MESSAGE_WARNING:
    break;
  case GST_MESSAGE_INFO:
    break;
  case GST_MESSAGE_EOS:
    break;
  case GST_MESSAGE_BUFFERING:
    break;
  case GST_MESSAGE_STATE_CHANGED: {
    GstState old_state, new_state, pending_state;
    gst_message_parse_state_changed (msg, &old_state, 
        &new_state, &pending_state);

    if (GST_MESSAGE_SRC (msg) == GST_OBJECT (__YOUR_PIPELINE_POINTER__)) {
      // your code here
    }
  }
  break;
}
// DON'T FORGET TO RETURN
return GST_BUS_DROP;

希望有帮助;-)

让我测试一下,看看它是否有效。谢谢你的回答,先生!