/** * ly_aud_set_position: * @percent: The desire position you want to seek, it should be between 0 and 1. * * Seek. * * Returns: TRUE for success, others FALSE. */ gboolean ly_aud_set_position(gdouble percent) { LyMdhMetadata *md=ly_pqm_get_current_md(); if(!md) return FALSE; GstElement *play=ly_ppl_get_playbin(); if(!play) return FALSE; gint64 position=0; gint64 start=0; gint64 duration=0; duration=ly_mdh_time_str2int(md->duration); if(duration<10) { return FALSE; } start=ly_mdh_time_str2int(md->start); position=(duration*percent)+start; if(!gst_element_seek(play,1.0,GST_FORMAT_TIME,GST_SEEK_FLAG_FLUSH,GST_SEEK_TYPE_SET,position,GST_SEEK_TYPE_SET,start+duration)) { g_critical(_("Cannot seek to desired position!")); return FALSE; } return TRUE; }
/** * ly_aud_get_position_abs: * * Get the current position by GStreamer inner clock which is in a format of gint64. * * Returns: The abusolute position time. */ gint64 ly_aud_get_position_abs() { GstState state; state=ly_aud_get_state(); if((state!=GST_STATE_PLAYING)&&(state!=GST_STATE_PAUSED)) return 0; LyMdhMetadata *md=ly_pqm_get_current_md(); if(!md) return 0; GstElement *play=ly_ppl_get_playbin(); if(!play) return 0; GstFormat fmt=GST_FORMAT_TIME; gint64 start=0; gint64 dura=0; gint64 pos=0; start=ly_mdh_time_str2int(md->start); dura=ly_mdh_time_str2int(md->duration); if(dura<=0) { gst_element_query_duration(play, &fmt, &dura); dura-=start; gchar *str=ly_mdh_time_int2str(dura); gchar sql[128]=""; g_snprintf(sql, sizeof(sql), "UPDATE metadatas SET duration='%s' WHERE id=%d", str, md->id); g_free(str); ly_dbm_exec(sql, NULL, NULL); ly_pqm_set_current_md(md->id); } if(!gst_element_query_position(play, &fmt, &pos)) { ly_log_put_with_flag(G_LOG_LEVEL_DEBUG, _("Position wrong!")); return 0; } if(pos-start<-60000000000) { ly_log_put_with_flag(G_LOG_LEVEL_DEBUG, _("Position wrong!")); return 0; } pos=pos-start; if(pos<0) pos=0; else if(pos>dura) pos=dura; return pos; }
/** * ly_aud_get_position: * * Get the current postion in gdouble format. * * Returns: The current position of pipeline. */ gdouble ly_aud_get_position() { gint64 pos=0; pos=ly_aud_get_position_abs(); LyMdhMetadata *md=ly_pqm_get_current_md(); if(!md) return 0; GstElement *play=ly_ppl_get_playbin(); if(!play) return 0; gint64 dura=0; gdouble position; dura=ly_mdh_time_str2int(md->duration); if(dura<=0) return 0; position=pos/(double)dura; return position; }
gboolean ly_3lrc_widget_on_seek_cb(GtkWidget * widget, GdkEventButton *event, gpointer data) { LyMdhMetadata *md=ly_pqm_get_current_md(); if(!md) return FALSE; int length=ly_lrc_get_length(); if(length<=0) return FALSE; //GdkCursor *cursor; int index=0; if (event->button == 1) { switch(event->type) { case GDK_BUTTON_PRESS: flag_seek=TRUE; ly_3lrc_widget_pos_old[X] = event->x; ly_3lrc_widget_pos_old[Y] = event->y; index_mark=ly_lrc_get_index(); break; case GDK_BUTTON_RELEASE: if(flag_seek==TRUE&&flag_seeked==TRUE) { LyLrcLyric **array=ly_lrc_get_array(); index=ly_lrc_get_index(); ly_aud_set_position(array[index]->time/(double)ly_mdh_time_str2int(md->duration)); } flag_seek = FALSE; flag_seeked=FALSE; ly_lrc_set_update_state(TRUE); break; default: break; } } if(flag_seek) { int pos[2]={0,0}; gtk_widget_get_pointer(widget, &pos[X], &pos[Y]); ly_3lrc_widget_pos_delta[Y]=pos[Y]-ly_3lrc_widget_pos_old[Y]; if(pos[Y]-ly_3lrc_widget_pos_old[Y]) flag_seeked=TRUE; ly_lrc_set_update_state(FALSE); } if(flag_seek&&flag_seeked) { gint lrc_gap=20; if(!ly_reg_get("lrc_gap","%d",&lrc_gap)) { ly_reg_set("lrc_gap","%d",lrc_gap); } index=index_mark; if(ly_3lrc_widget_pos_delta[Y]>=0) { index-=(int)(abs(ly_3lrc_widget_pos_delta[Y])/lrc_gap); if(index<0) { index=0; } } else { index+=(int)(abs(ly_3lrc_widget_pos_delta[Y])/lrc_gap); if(index>=length) { index=length-1; } } ly_lrc_set_index(index); } return FALSE; }
gboolean ly_3lrc_widget_on_expose_cb(GtkWidget * widget, cairo_t *cr, gpointer data) { gint width; gint height; width = gtk_widget_get_allocated_width (widget); height = gtk_widget_get_allocated_height (widget); gchar title_font[1024]="Sans Regular 18"; ly_reg_get("3lrc_title_font", "%1024[^\n]", title_font); gchar normal_font[1024]="Sans Regular 10"; ly_reg_get("3lrc_normal_font", "%1024[^\n]", normal_font); /* * draw bg */ if(ly_3lrc_pixbuf_bg) { if(ly_3lrc_pixbuf_bg_copy) { int h=gdk_pixbuf_get_height(ly_3lrc_pixbuf_bg_copy); int w=gdk_pixbuf_get_width(ly_3lrc_pixbuf_bg_copy); if(h<height||h-height>2||w<width||w-width>2) { g_object_unref(ly_3lrc_pixbuf_bg_copy); ly_3lrc_pixbuf_bg_copy=gdk_pixbuf_scale_simple(ly_3lrc_pixbuf_bg, width, height, GDK_INTERP_BILINEAR); } } else { ly_3lrc_pixbuf_bg_copy=gdk_pixbuf_scale_simple(ly_3lrc_pixbuf_bg, width, height, GDK_INTERP_BILINEAR); } gdk_cairo_set_source_pixbuf(cr, ly_3lrc_pixbuf_bg_copy, 0, 0); cairo_paint(cr); } cairo_rectangle (cr, 0, 0, width, height); cairo_set_source_rgba (cr, 0, 0, 0, 0.5); cairo_fill(cr); //画标题 cairo_pattern_t *pat; pat = cairo_pattern_create_linear (0, 0, 0, 45); cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 0.5); cairo_pattern_add_color_stop_rgba (pat, 0.18, 1, 1, 1, 0.3); cairo_pattern_add_color_stop_rgba (pat, 0.25, 1, 1, 1, 0.1); cairo_pattern_add_color_stop_rgba (pat, 1, 1, 1, 1, 0.1); cairo_rectangle (cr, 0, 0, width, 45); cairo_set_source (cr, pat); cairo_fill(cr); cairo_pattern_destroy (pat); cairo_set_line_width(cr, 0.5); cairo_set_source_rgba (cr, 0.9, 0.9, 0.9, 0.6); cairo_move_to(cr, 0, 44); cairo_line_to(cr, width, 44); cairo_stroke(cr); cairo_set_source_rgba (cr, 0, 0, 0, 0.9); cairo_move_to(cr, 0, 44.5); cairo_line_to(cr, width, 44.5); cairo_stroke(cr); LyMdhMetadata *md=ly_pqm_get_current_md(); int length=ly_lrc_get_length(); if(md) { gchar title[1024]=""; g_snprintf(title, sizeof(title), "%s - %s", md->title,md->artist); cairo_set_source_rgb ( cr, 0.1, 0.1, 0.1); ly_3lrc_widget_draw_text_midx(cr, title, title_font, width ,6); cairo_set_source_rgb ( cr, 0.9, 0.9, 0.9); ly_3lrc_widget_draw_text_midx(cr, title, title_font, width ,7); } //没有找到歌词 if(length<=0||!md) { //画边框 cairo_set_source_rgba ( cr, 0.3 , 0.3 , 0.3 ,0.8) ; cairo_set_line_width ( cr,1); cairo_translate ( cr, width/2 , height/2); cairo_move_to(cr, -70, -30); cairo_line_to(cr, 70, -30); cairo_arc(cr, 70, 0.0, 30.0 ,-M_PI/2 ,-M_PI*3/2); cairo_line_to(cr, 70, 30); cairo_arc(cr, -70, 0.0, 30.0 ,M_PI/2 ,M_PI*3/2); cairo_fill (cr); //画闪烁的原点 cairo_translate ( cr, -60 , 0 ); static gdouble const trs[ 8 ] [ 8 ] = { { 0.0 , 0.15 , 0.30 , 0.5 , 0.65 , 0.80 , 0.9 , 1.0 } , { 1.0 , 0.0 , 0.15 , 0.30 , 0.5 , 0.65 , 0.8 , 0.9 } , { 0.9 , 1.0 , 0.0 , 0.15 , 0.3 , 0.5 , 0.65 , 0.8 } , { 0.8 , 0.9 , 1.0 , 0.0 , 0.15 , 0.3 , 0.5 , 0.65 } , { 0.65 , 0.8 , 0.9 , 1.0 , 0.0 , 0.15 , 0.3 , 0.5 } , { 0.5 , 0.65 , 0.8 , 0.9 , 1.0 , 0.0 , 0.15 , 0.3 } , { 0.3 , 0.5 , 0.65 , 0.8 , 0.9 , 1.0 , 0.0 , 0.15 } , { 0.15 , 0.3 , 0.5 , 0.65 , 0.8 , 0.9 , 1.0 , 0.0 ,} }; gint i = 0 ; for ( i = 0 ; i < 8 ; i++) { cairo_set_line_width ( cr, 8 ) ; cairo_set_line_cap ( cr, CAIRO_LINE_CAP_ROUND) ; cairo_set_source_rgba ( cr, 1.0 , 1.0 , 1.0 , trs[count%8][i]) ; cairo_move_to ( cr, 0.0 , -15.0 ); cairo_line_to (cr, 0.0, -15.0); cairo_rotate ( cr, M_PI / 4 ) ; cairo_stroke ( cr) ; } //写字“Serching Lyrics...” cairo_set_source_rgba ( cr, 1.0 , 1.0 , 1.0 , 1.0) ; cairo_move_to (cr, 30.0 , -6.0); ly_3lrc_widget_draw_text(cr,"Missing Lyrics...", "Sans Regular 10"); count=(count+1)%8; } //有歌词 else { gint lrc_gap=20; if(!ly_reg_get("lrc_gap","%d",&lrc_gap)) { ly_reg_set("lrc_gap","%d",lrc_gap); } int y=height/2; LyLrcLyric **array=ly_lrc_get_array(); int index=ly_lrc_get_index(); if(flag_seek&&flag_seeked) { cairo_set_source_rgba ( cr, 0.8, 0.8, 0.8, 0.8); cairo_set_line_width ( cr,20); cairo_set_line_cap ( cr, CAIRO_LINE_CAP_ROUND) ; cairo_move_to(cr, 10.0, height/2.0+8); cairo_line_to(cr, width-10.0, height/2.0+8); cairo_stroke (cr); y=height/2.0; } else { gint64 t1=0; gint64 t2=0; if(index+1<length) { t1=array[index+1]->time-array[index]->time; } else t1=ly_mdh_time_str2int(md->duration)-array[index]->time; t2=ly_aud_get_position_abs()-array[index]->time; if(t1!=0) { y=y-(int)((t2/(gdouble)t1)*lrc_gap); } } //正式画歌词区域 //画当前歌词 cairo_set_source_rgb(cr,1, 1, 1); if(y>height/5.0&&y<height*4/5.0) ly_3lrc_widget_draw_text_midx(cr,array[index]->text, normal_font,width,y); //画普通歌词 cairo_set_source_rgb(cr,0.5,0.5,0.5); int i=1; for(i=1;i<=10;i++) { if(index-i>=0 &&(y-i*(lrc_gap)>height/5.0)) { ly_3lrc_widget_draw_text_midx(cr,array[index-i]->text, normal_font,width,y-i*(lrc_gap)); } else break; } for(i=1;i<=10;i++) { if(index+i<length &&(y+i*(lrc_gap)<(height/5.0*4))) { ly_3lrc_widget_draw_text_midx(cr,array[index+i]->text,normal_font,width,y+i*(lrc_gap)); } else break; } } return FALSE; }
gboolean ly_3lrc_desktop_on_expose_cb (GtkWidget * widget, cairo_t *cr, gpointer data) { gchar desktop_font[1024]="Sans Regular 25"; ly_reg_get("3lrc_desktop_font", "%1024[^\n]", desktop_font); gchar path[1024]; g_snprintf(path,sizeof(path),"%sicon/null.png",LY_GLB_PROG_UIXDIR); if(!desktop_bg) desktop_bg=cairo_image_surface_create_from_png(path); cairo_set_source_surface(cr, desktop_bg, 0, 0); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_paint(cr); int width; int height; width = gtk_widget_get_allocated_width (widget); height = gtk_widget_get_allocated_height (widget); int x=0; int y=height; //鼠标进入 if(flag_notify) { //填充圆角矩形拖动区域 cairo_set_source_rgba(cr,0,0,0,0.3); cairo_move_to (cr, 0 + 5, 0); cairo_line_to (cr, 0 + width - 5, 0); cairo_move_to (cr, 0 + width, 0 + 5); cairo_line_to (cr, 0 + width, 0 + height - 5); cairo_move_to (cr, 0 + width - 5, 0 + height); cairo_line_to (cr, 0 + 5, 0 + height); cairo_move_to (cr, 0, 0 + height - 5); cairo_line_to (cr, 0, 0 + 5); cairo_arc (cr, 0 + 5, 0 + 5, 5, M_PI, 3 * M_PI / 2.0); cairo_arc (cr, 0 + width - 5, 0 + 5, 5, 3 * M_PI / 2, 2 * M_PI); cairo_arc (cr, 0 + width - 5, 0 + height - 5, 5, 0, M_PI / 2); cairo_arc (cr, 0 + 5, 0 + height - 5, 5, M_PI / 2, M_PI); cairo_fill(cr); } if(ly_lrc_get_length()>0) { //计算占空比 gint64 t1=0; gint64 t2=0; LyMdhMetadata *md=NULL; md=ly_pqm_get_current_md(); if(!md) return FALSE; if(ly_lrc_get_index()+1<ly_lrc_get_length()) t1=(ly_lrc_get_array()[ly_lrc_get_index()+1])->time-(ly_lrc_get_array()[ly_lrc_get_index()])->time; else t1=ly_mdh_time_str2int(md->duration)-ly_mdh_time_str2int(md->start)-(ly_lrc_get_array()[ly_lrc_get_index()])->time; t2=ly_aud_get_position_abs()-ly_mdh_time_str2int(md->start)-(ly_lrc_get_array()[ly_lrc_get_index()])->time; if(t1!=0) { x=(int)((t2/(gdouble)t1)*pos_layout[X]); } //画歌词 cairo_set_source_rgb(cr,0,0,0); //确定起始点 if((x>=width/2)&&(pos_layout[X]>width)&&(width<(pos_layout[X]-x)*2)) { cairo_move_to(cr, 0-(x-width/2), 5); x=width/2; } else if((x>=width/2)&&(pos_layout[X]>width)&&(width>=(pos_layout[X]-x)*2)) cairo_move_to(cr, 0-(pos_layout[X]-width), 5); else cairo_move_to(cr, 0, 5); PangoLayout *layout; PangoFontDescription *desc; layout = pango_cairo_create_layout (cr); pango_layout_set_text(layout, ly_lrc_get_array()[ly_lrc_get_index()]->text, -1); desc = pango_font_description_from_string (desktop_font); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_get_size(layout,&pos_layout[X],&pos_layout[Y]); pos_layout[X]=pos_layout[X]/1000; pango_cairo_update_layout (cr, layout); pango_cairo_layout_path (cr, layout); cairo_clip(cr); g_object_unref (layout); //画背景条 cairo_pattern_t *pat; pat = cairo_pattern_create_linear (0, 0,10.0, 150); cairo_pattern_add_color_stop_rgb (pat, 0.1, 65535/65535.0, 10449/65535.0, 0/65535.0); cairo_pattern_add_color_stop_rgb (pat, 0.5, 65535/65535.0, 61062/65535.0, 0/65535.0); cairo_pattern_add_color_stop_rgb (pat, 0.9, 65535/65535.0, 10449/65535.0, 0/65535.0); //画矩形 if((x>=width/2)&&(pos_layout[X]>width)&&(width<(pos_layout[X]-x)*2)) cairo_rectangle (cr, 0, 0, width/2, y); else if((x>=width/2)&&(pos_layout[X]>width)&&(width>=(pos_layout[X]-x)*2)) cairo_rectangle (cr, 0, 0, width-(pos_layout[X]-x), y); else cairo_rectangle (cr, 0, 0, x, y); cairo_set_source (cr, pat); cairo_fill(cr); cairo_pattern_destroy (pat); pat = cairo_pattern_create_linear (0, 0,10.0, 150); cairo_pattern_add_color_stop_rgb (pat, 0.1, 19532/65535.0, 65535/65535.0, 65535/65535.0); cairo_pattern_add_color_stop_rgb (pat, 0.5, 5539/65535.0, 0/65535.0, 65535/65535.0); cairo_pattern_add_color_stop_rgb (pat, 0.9, 19532/65535.0, 65535/65535.0, 65535/65535.0); //画矩形 if((x>=width/2)&&(pos_layout[X]>width)&&(width<(pos_layout[X]-x)*2)) cairo_rectangle (cr, width/2, 0, width-(width/2), y); else if((x>=width/2)&&(pos_layout[X]>width)&&(width>=(pos_layout[X]-x)*2)) cairo_rectangle (cr, width-(pos_layout[X]-x), 0, pos_layout[X]-x, y); else cairo_rectangle (cr, x, 0, width-x, y); cairo_set_source (cr, pat); cairo_fill(cr); cairo_pattern_destroy (pat); } int lrc_desktop=1; int lrc_desktop_fix=0; if(!ly_reg_get("3lrc_desktop_state", "%d:%d", &lrc_desktop, &lrc_desktop_fix)) { ly_reg_set("3lrc_desktop_state", "%d:%d", lrc_desktop, lrc_desktop_fix); } if(lrc_desktop_fix>0) gtk_widget_set_sensitive(widget,FALSE); else gtk_widget_set_sensitive(widget,TRUE); cairo_region_t *region; if(!(lrc_desktop_fix)) { cairo_rectangle_int_t rect; rect.x=rect.y=0; rect.width=width; rect.height=height; region=cairo_region_create_rectangle(&rect); } else { region=cairo_region_create(); } gdk_window_input_shape_combine_region (gtk_widget_get_window(widget), region, 0, 0); cairo_region_destroy (region); return FALSE; }