#include "core.h"
#include "list.h"
#include <malloc.h>
static PLAYSET *dumb;
static gboolean cb_play_bus(GstBus *bus, GstMessage *msg, gpointer data)
{
PLAYSET *player= (PLAYSET*)data;
GError *err;
gchar *debug;
/*
GstTagList *tags;
gchar *title;
gchar *artist;
gchar *album;
*/
switch(GST_MESSAGE_TYPE(msg) )
{
case GST_MESSAGE_ERROR:
gst_message_parse_error(msg, &err, &debug);
g_print("Error: %s\n", err->message);
g_error_free(err);
g_free(debug);
gst_element_set_state(player->play2, GST_STATE_NULL);
break;
case GST_MESSAGE_EOS:
coreNext(player);
break;
case GST_MESSAGE_TAG:
/* gst_message_parse_tag(msg, &tags);
if(gst_tag_list_get_string(tags, GST_TAG_TITLE, &title)&&
gst_tag_list_get_string(tags, GST_TAG_ARTIST, &artist)&&
gst_tag_list_get_string(tags, GST_TAG_ALBUM, &album) )
{
}
gst_tag_list_free(tags);
*/
break;
default:
break;
}
return TRUE;
}
static gboolean cb_dumb_bus(GstBus *bus, GstMessage *msg, gpointer data)
{
PLAYSET *player= (PLAYSET*)data;
GError *err;
gchar *debug;
GstTagList *tags;
gchar *title;
gchar *artist;
gchar *album;
GstFormat format= GST_FORMAT_TIME;
gint64 val= -1;
GList *p= NULL;
switch(GST_MESSAGE_TYPE(msg) )
{
case GST_MESSAGE_ERROR:
gst_message_parse_error(msg, &err, &debug);
g_print("Error: %s\n", err->message);
g_error_free(err);
g_free(debug);
gst_element_set_state(player->play2, GST_STATE_NULL);
break;
case GST_MESSAGE_EOS:
gst_element_set_state(player->play2, GST_STATE_NULL);
break;
case GST_MESSAGE_TAG:
gst_message_parse_tag(msg, &tags);
if(gst_tag_list_get_string(tags, GST_TAG_TITLE, &title)&&
gst_tag_list_get_string(tags, GST_TAG_ARTIST, &artist)&&
gst_tag_list_get_string(tags, GST_TAG_ALBUM, &album) )
{
p= g_list_nth(player->playlist, player->num);
g_stpcpy(((PlayList*)p->data)->title, title);
g_stpcpy(((PlayList*)p->data)->artist, artist);
g_stpcpy(((PlayList*)p->data)->album, album);
}
gst_tag_list_free(tags);
if(gst_element_query_duration(player->play2, &format, &val) )
{
p= g_list_nth(player->playlist, player->num);
/*((PlayList*)p->data)->duration= val/1000000000;*/
val= val/1000000000;
g_sprintf(((PlayList*)p->data)->duration, "%02d:%02ds", (gint)val/60, (gint)val%60);
gst_element_set_state(player->play2, GST_STATE_NULL);
if(!(2==player->mode||0==player->mode&&(g_list_length(player->playlist)-1==player->num) ) )
{
coreNext(player);
}
else
{
gst_element_set_state(player->play2, GST_STATE_NULL);
list_print(player->playlist);
return FALSE;
}
}
break;
default:
break;
}
return TRUE;
}
PLAYSET *coreCreate()
{
PLAYSET *player= NULL;
GstElement *play1;
GstElement *play2;
GstBus *bus;
player= (PLAYSET*)malloc(sizeof(PLAYSET) );
dumb= (PLAYSET*)malloc(sizeof(PLAYSET) );
if(NULL!= player&&NULL!=dumb)
{
play1= gst_element_factory_make("playbin2", "play1");
play2= gst_element_factory_make("playbin2", "play2");
bus= gst_pipeline_get_bus(GST_PIPELINE(play1) );
gst_bus_add_watch(bus, cb_play_bus, player);
gst_object_unref(GST_OBJECT(bus) );
gst_element_set_state(play1, GST_STATE_NULL);
gst_element_set_state(play2, GST_STATE_NULL);
player->play2= play1;
dumb->play2= play2;
g_object_set(G_OBJECT(dumb->play2), "mute", TRUE, NULL);
}
else
{
}
return player;
}
void select_item(PLAYSET * player, GList *list, int index)
{
player->playlist= list;
player->num= index;
}
void corePlay(PLAYSET *sets)
{
gst_element_set_state(sets->play2, GST_STATE_PLAYING);
}
void corePause(PLAYSET *sets)
{
gst_element_set_state(sets->play2, GST_STATE_PAUSED);
}
void coreNext(PLAYSET *sets)
{
GList *p= NULL;
gboolean flag= TRUE;
switch(sets->mode)
{
case 0:
sets->num++;
if(g_list_length(sets->playlist)<=sets->num )
{
gst_element_set_state(sets->play2, GST_STATE_NULL);
flag= FALSE;
}
break;
case 1:
sets->num= g_random_int_range(0, (gint32)g_list_length(sets->playlist) );
break;
case 2:
if(-1>= sets->num)
{
sets->num= 0;
}
if(g_list_length(sets->playlist)<=sets->num)
{
sets->num= g_list_length(sets->playlist)-1;
}
break;
case 3:
sets->num++;
if(g_list_length(sets->playlist)<=sets->num )
{
sets->num= 0;
}
break;
default:
gst_element_set_state(sets->play2, GST_STATE_NULL);
flag= FALSE;
break;
}
if(flag)
{
p= g_list_nth(sets->playlist, sets->num);
gst_element_set_state(sets->play2, GST_STATE_NULL);
if(g_str_has_prefix(((PlayList*)p->data)->uri, "file:///") &&
g_file_test(((PlayList*)p->data)->uri+7, G_FILE_TEST_IS_REGULAR|G_FILE_TEST_EXISTS) )
{
g_object_set(G_OBJECT(sets->play2), "uri", ((PlayList*)p->data)->uri, NULL);
gst_element_set_state(sets->play2, GST_STATE_PLAYING);
}
}
}
void corePrev(PLAYSET *sets)
{
GList *p= NULL;
gboolean flag= TRUE;
switch(sets->mode)
{
case 0:
sets->num--;
if(-1>= sets->num)
{
gst_element_set_state(sets->play2, GST_STATE_NULL);
flag= FALSE;
}
break;
case 1:
sets->num= g_random_int_range(0, (gint32)g_list_length(sets->playlist) );
break;
case 2:
if(-1>= sets->num)
{
sets->num= 0;
}
if(g_list_length(sets->playlist)<=sets->num)
{
sets->num= g_list_length(sets->playlist)-1;
}
break;
case 3:
sets->num--;
if(-1>= sets->num)
{
sets->num= g_list_length(sets->playlist)-1;
}
break;
default:
gst_element_set_state(sets->play2, GST_STATE_NULL);
flag= FALSE;
break;
}
if(flag)
{
p= g_list_nth(sets->playlist, sets->num);
gst_element_set_state(sets->play2, GST_STATE_NULL);
if(g_str_has_prefix(((PlayList*)p->data)->uri, "file:///") &&
g_file_test(((PlayList*)p->data)->uri+7, G_FILE_TEST_IS_REGULAR|G_FILE_TEST_EXISTS) )
{
g_object_set(G_OBJECT(sets->play2), "uri", ((PlayList*)p->data)->uri, NULL);
gst_element_set_state(sets->play2, GST_STATE_PLAYING);
}
}
}
int coreGetTAG(PLAYSET *sets, GList *list, int index)
{
GstBus *bus;
select_item(dumb, list, index-1);
coreSetMode(dumb, 0);
bus= gst_pipeline_get_bus(GST_PIPELINE(dumb->play2) );
gst_bus_add_watch(bus, cb_dumb_bus, dumb);
gst_object_unref(GST_OBJECT(bus) );
coreNext(dumb);
coreSetMode(dumb, 2);
return 0;
}
void coreSetMode(PLAYSET *sets, int val)
{
sets->mode= val;
if(0>val)
{
sets->mode= 0;
}
if(3<val)
{
sets->mode= 3;
}
}
void coreVolumeOn(PLAYSET *sets)
{
g_object_set(G_OBJECT(sets->play2), "mute", TRUE, NULL);
}
void coreVolumeOff(PLAYSET *sets)
{
g_object_set(G_OBJECT(sets->play2), "mute", FALSE, NULL);
}
void coreSetVolume(PLAYSET *sets, gdouble val)
{
g_object_set(G_OBJECT(sets->play2), "volume", val, NULL);
}
gdouble coreGetVolume(PLAYSET *sets)
{
gdouble val;
g_object_get(G_OBJECT(sets->play2), "volume", &val, NULL);
return val;
}
gint coreGetDuration(PLAYSET *sets)
{
GstFormat format= GST_FORMAT_TIME;
gint64 duration;
gint res= 0;
if(gst_element_query_duration(sets->play2, &format, &duration) );
res= duration/1000000000;
return res;
}
gint coreGetPosition(PLAYSET *sets)
{
GstFormat format= GST_FORMAT_TIME;
gint64 position;
gint res= 0;
if(gst_element_query_position(sets->play2, &format, &position) )
res= position/1000000000;
return res;
}
gdouble coreGetProgress(PLAYSET *sets)
{
GstFormat format= GST_FORMAT_TIME;
gint64 position;
gint64 duration;
gdouble progress= 0.0;
if(gst_element_query_position(sets->play2, &format, &position)&&
gst_element_query_duration(sets->play2, &format, &duration) )
{
progress= (gdouble)position/duration;
}
return progress;
}
void coreSeekPlay(PLAYSET *sets, gdouble pos)
{
GstFormat forma