Android Music player Development Sweetmusicplayer Smart match Local lyrics

Source: Internet
Author: User
Tags drawtext

The previous article wrote about using MediaPlayer to play music, http://blog.csdn.net/huweigoodboy/article/details/39861539, now to load the local lyrics. OK, still use that picture.


one, match lyrics from memory card

will be matched from the following path

1) sweetmusicplayer/lyrics/

2) songs in the same sibling directory

3) Song parent directory/lryics (Lryic Plus s, first letter size or not)


Lrccontent

Package Com.huwei.sweetmusicplayer.models;public class Lrccontent {private String lrcstr;//lyrics content private int lrctime;// Current lyrics Time public String getlrcstr () {return lrcstr;} public void Setlrcstr (String lrcstr) {this.lrcstr = Lrcstr;} public int Getlrctime () {return lrctime;} public void setlrctime (int lrctime) {this.lrctime = Lrctime;}}
Lrcprocess

Package Com.huwei.sweetmusicplayer.models;import Java.io.bufferedreader;import Java.io.file;import Java.io.fileinputstream;import Java.io.filenotfoundexception;import Java.io.ioexception;import Java.io.inputstreamreader;import Java.io.unsupportedencodingexception;import Java.util.ArrayList;import Java.util.collections;import Java.util.list;import Android.util.log;import Com.huwei.sweetmusicplayer.comparator.lrccomparator;import Com.huwei.sweetmusicplayer.datamanager.MusicManager; Import Com.huwei.sweetmusicplayer.util.onlinelrcutil;import Com.huwei.sweetmusicplayer.util.timeutil;public class lrcprocess {private list<lrccontent> lrclists;public lrcprocess () {super (); lrclists = new arraylist< Lrccontent> (); Lrclists.clear ();} Public String LOADLRC (song song) {String path = Song.getpath (); StringBuffer StringBuffer = new StringBuffer ();//Get Lyrics file path string lrcpathstring = path.substring (0, Path.lastindexof (".")) + ". LRC"; int index = Lrcpathstring.lastindexof ("/"); String Parentpath; String lrcname;//if (index!=-1) {Parentpath = lrcpathstring.substring (0, index); lrcname = lrcpathstring.substring (index); /}file File = new file (lrcpathstring);//Match Sweetmusicplayer/lyricsif (!file.exists ()) {file = new file (onlinelrcutil.get Instance (). Getlrcpath (Song.gettitle (), Song.getartist ())); LOG.I ("Path", File.getabsolutepath (). toString ());//Match Lyricsif (!file.exists ()) {file = new file (Parentpath + "/). /"+" lyrics/"+ Lrcname);} LOG.I ("Path", File.getabsolutepath (). toString ());//Match Lyricif (!file.exists ()) {file = new file (Parentpath + "/). /"+" lyric/"+ Lrcname);} LOG.I ("Path", File.getabsolutepath (). toString ());//Match Lyricif (!file.exists ()) {file = new file (Parentpath + "/). /"+" lyric/"+ Lrcname);} LOG.I ("Path", File.getabsolutepath (). toString ());//Match Lyricsif (!file.exists ()) {file = new file (Parentpath + "/). /"+" lyrics/"+ Lrcname);} LOG.I ("Path", File.getabsolutepath (). toString ()); if (!file.exists ()) {Stringbuffer.append ( MusicManager.OperateState.READLRCFILE_FAIL); return StRingbuffer.tostring ();} try {fileinputstream fin = new FileInputStream (file), InputStreamReader ISR = new InputStreamReader (FIN, "utf-8"); BufferedReader br = new BufferedReader (ISR); String S;boolean ISLRC = False;while ((s = br.readline ()) = null) {//if (ISLRC) {s = S.replace ("[", "" "); Remove the left parenthesis string lrcdata[] = S.split ("]");//This sentence is the lyrics if (Lrcdata[0].matches ("^\\d{2}:\\d{2}.\\d+$")) {int len = Lrcdata.length;int end = Lrcdata[len-1].matches ("^\\d{2}:\\d{2}.\\d+$")? len:len-1;for (int i = 0; i < end; i++) {Lrccontent lrccontent = new lrccontent (); int lrctime = Timeutil.getlrcmilltime (Lrcdata[i]); Lrccontent.setlrctime ( Lrctime); if (lrcdata.length = = end) Lrccontent.setlrcstr (""); Blank line Elselrccontent.setlrcstr (lrcdata[len-1]); Lrclists.add (lrccontent);}} Sort by Time Collections.sort (lrclists, New Lrccomparator ()); if (lrclists.size () = = 0) {stringbuffer.append ( MusicManager.OperateState.READLRC_LISTNULL);} else {stringbuffer.append (MusicManager.OperateState.READLRC_SUCCESS);}} catch (FilenOtfoundexception e) {//TODO auto-generated catch Blocke.printstacktrace ();//Stringbuffer.append ("lyrics File not Found");} catch ( Unsupportedencodingexception e) {//TODO auto-generated catch Blocke.printstacktrace ();//Stringbuffer.append ("Unsupported encoding ");} catch (IOException e) {//TODO auto-generated catch Blocke.printstacktrace ();//Stringbuffer.append ("IO Error");} return stringbuffer.tostring ();} Public list<lrccontent> getlrclists () {return lrclists;}}

two, lyrics analysisPick a song first

TI: quiet]
[AR: Jay Chou]
[Al: Fant West]
[By:midas]
[00:03.16]
[00:04.50] Jay Chou-quiet
[00:14.5] Word: Jay Chou Song: Jay Chou: Zhongxingmin
[00:25.17]
[02:27.48] [00:27.02] Only the piano left me a day to talk
[02:32.76] [00:32.51] sleeping cello quiet old old
[02:39.6] [00:38.67]
[02:40.74] [00:40.48] I think you've been very clear.
[02:46.04] [00:45.7] I know that you're not reluctant
[02:53.23] [00:52.53]
[02:54.04] [00:53.76] You said you'd be sad too, I don't believe it.
[03:00.59] [01:00.36] Holding you accompany me is just once
[03:06.63] [01:06.24] I hope he really loves you more than I do.
[03:13.29] [01:12.96] I will force myself to leave.


Each time a row is traversed, the first thing to do is to replace "[" with "", to match what is the time part, to match "^\\d{2}:\\d{2}.\\d+$", then Split ("]"), to get an array of data[], the last is the content, the front is the lyrics, iterate over the array, Loading time lyrics to list.


Time processing: Turn into milliseconds


After all rows have been traversed, the list is sorted by time.


The code lrcprogress above.

three, Lrcview controlsIs divided into the following states:

public static String readlrc_success= "Readlrc_success"; //Read Local lyrics successfully
public static String readlrc_listnull= "Readlrc_listnull"; //Read lyrics list is null
public static String readlrc_online= "Readlrc_online"; //Loading lyrics from the network
public static String readlrcfile_fail= "Readlrcfile_fail"; //Failed to read lyrics file
public static String readlrconline_fail= "Readlrconline_fail"; //Load lyrics from the network failed


Draw different content based on different states.

Lrcview inherit from ScrollView, and then add a layer of linearlayout, lyrics drawn on the TextView, according to the play time scrolling, you can ensure that the current playing lyrics in the middle of the screen.

About custom controls, be aware of the good understanding of Onmeasure (), OnLayout (), OnDraw (), sometimes encountering OnDraw () cannot execute, remember to add Setwillnotdraw (false), This is directly inherited from the ScrollView, there is no need to consider so much.


Here you need to calculate the current playback position based on the playback time, the lyrics in the line, and then different times, to update the lyrics interface.



Adjust Lyrics progress:

When touch listening, action_move to draw the lyrics progress preview (including adjusted to the time preview), action_up adjust to the corresponding progress.



Package Com.huwei.sweetmusicplayer.ui.widgets;import java.util.List; Import Com.huwei.sweetmusicplayer.datamanager.musicmanager;import com.huwei.sweetmusicplayer.models.LrcContent; Import Com.huwei.sweetmusicplayer.util.TimeUtil; Import Android.content.context;import Android.content.intent;import Android.graphics.canvas;import Android.graphics.color;import Android.graphics.paint;import Android.graphics.typeface;import Android.os.Handler; Import Android.os.message;import android.util.attributeset;import Android.util.log;import android.view.MotionEvent ; Import Android.view.view;import Android.view.viewtreeobserver.onscrollchangedlistener;import Android.widget.scrollview;import Android.widget.textview;import Android.view.view.ontouchlistener;public Class Lrcview extends ScrollView implements onscrollchangedlistener,ontouchlistener{private float width;//lyrics View width private Float height;//Lyrics View height Private paint currentpaint;//Current Brush Object Private paint notcurrentpaint;//non-current brush object Private final float textheight=40;//text height Private final float textsize=36;//highlight text size private final float nottextsize=30;//non-highlighted text size private int index;// Lyrics List set subscript private String lrcstate;private lrctextview lrctextview;private list<lrccontent> lrclists;private int scrolly;private boolean candrawline=false;private int pos=-1;  Press the position of the lyrics to the location of the private Paint linepaint;private Boolean cantouchlrc=false;//can touch and adjust the lyrics private int count=0; The number of times the load point was drawn private context mcontext;public Lrcview (context context) {this (context,null);//TODO auto-generated Constructor Stub}public Lrcview (context context, AttributeSet Attrs) {This (context, attrs,0);//TODO auto-generated Constructor Stub}public Lrcview (context context, AttributeSet attrs, int defstyle) {Super (context, attrs, defstyle);/To Do auto-generated constructor Stubmcontext=context;this.setontouchlistener (this); Init (); }public list<lrccontent> getlrclists () {return lrclists;} public void Setlrclists (list<lrccontent> lrclists) {this.lrclists = lrclists;//determines whether the lyrics interface can touch if (lrclists==null| | Lrclists.size () ==0) Cantouchlrc=false;else cantouchlrc=true;//set index=-1this.index=-1; Layoutparams params1=new Layoutparams (layoutparams.match_parent,layoutparams.match_parent); lrcTextView=new Lrctextview (This.getcontext ()); Lrctextview.setlayoutparams (PARAMS1); This.removeallviews (); This.addview (Lrctextview);} public int GetIndex () {return index;} public void Setindex (int index) {//song position changed, and the finger is not the state where the lyrics are adjusted if (this.index!=index&&pos==-1) {this.scrollto (0, (int) (Index*textheight));} This.index = index;} @Overrideprotected void onsizechanged (int w, int h, int oldw, int oldh) {//TODO auto-generated method Stubsuper.onsizecha Nged (W, H, OLDW, OLDH); this.width=w;this.height=h;} public int Getindexbylrctime (int. currenttime) {for (int i=0;i<lrclists.size (); i++) {if (currenttime<lrclists.get (i). Getlrctime ()) {return i-1;}} Return Lrclists.size ()-1;}  public void Clear () {lrclists=null;} Public String Getlrcstate () {return lrcstate;} public void Setlrcstate (String lrcstate) {this.Lrcstate = Lrcstate;this.invalidate ();} Class Lrctextview extends Textview{public Lrctextview (context context) {this (context,null);//TODO auto-generated const Ructor Stub}public Lrctextview (context context, AttributeSet Attrs) {This (context, attrs,0);//TODO auto-generated Constructor Stub}public Lrctextview (context context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle) ;//TODO auto-generated constructor Stubthis.setwillnotdraw (false); }//Draw lyrics @overrideprotected void OnDraw (canvas canvas) {//TODO auto-generated method Stubsuper.ondraw (canvas);      LOG.I ("Lrctextview onDraw", "Lrctextview OnDraw"), if (canvas==null) return;        int tempy= (int) HEIGHT/2; if (MusicManager.OperateState.READLRC_LISTNULL.equals (lrcstate)) {canvas.drawtext ("Lyrics content is empty", WIDTH/2, Tempy,    Notcurrentpaint);    Return }else if (MusicManager.OperateState.READLRCFILE_FAIL.equals (lrcstate)) {canvas.drawtext ("lyrics File not found", WIDTH/2, Tempy,    Notcurrentpaint);    Return } else if (Musicmanager.OperateState.READLRC_SUCCESS.equals (lrcstate)) {//Draw lyrics for (int i=0;i<lrclists.size (); i++,tempy+=textheight) {    if (i==index) {Canvas.drawtext (Lrclists.get (i). GETLRCSTR (), WIDTH/2, Tempy, Currentpaint);    }else if (i==pos) {Canvas.drawtext (Lrclists.get (i). GETLRCSTR (), WIDTH/2, Tempy, Linepaint);    }else{Canvas.drawtext (Lrclists.get (i). GETLRCSTR (), WIDTH/2, Tempy, Notcurrentpaint);    }} return;        }else if (MusicManager.OperateState.READLRC_ONLINE.equals (lrcstate)) {String drawcontentstr= "match lyrics online";        for (int i=0;i<count;i++) {drawcontentstr+= ".";}    count++;        if (count>=6) count=0;             Canvas.drawtext (Drawcontentstr, WIDTH/2, Tempy, Notcurrentpaint);    Handler.sendemptymessagedelayed (1, 500);    Return }else if (MusicManager.OperateState.READLRCONLINE_FAIL.equals (lrcstate)) {Canvas.drawtext ("failed to load lyrics from the network", WIDTH/2,    Tempy, Notcurrentpaint);    Return }} @Overrideprotected void onmeasure (int widthmeasuresPEC, int heightmeasurespec) {//TODO auto-generated method Stubsuper.onmeasure (Widthmeasurespec, Heightmeasurespec); heightmeasurespec= (int) (height+textheight* (Lrclists.size ()-1)) Setmeasureddimension (Widthmeasurespec, HEIGHTMEASURESPEC);}}; @Overrideprotected void OnDraw (canvas canvas) {//TODO auto-generated method Stubsuper.ondraw (Canvas), if (candrawline) { Canvas.drawline (0, SCROLLY+HEIGHT/2, width, SCROLLY+HEIGHT/2, linepaint); Canvas.drawtext (Timeutil.totime ( Lrclists.get (POS). Getlrctime ()), scrolly+height/2-2, Linepaint);}}  private void Init () {setfocusable (true);//Set the control to have focus This.setwillnotdraw (false); Highlight Lyrics Section currentpaint=new Paint (); Currentpaint.setantialias (true);//Set anti-aliasing currentpaint.settextalign ( Paint.Align.CENTER);//Set Text Center//non-highlighted lyrics part notcurrentpaint=new Paint (); Notcurrentpaint.setantialias (true); Notcurrentpaint.settextalign (Paint.Align.CENTER);//linepaint=new Paint (); Linepaint.setantialias (true); Linepaint.settextalign (Paint.Align.CENTER);//Set Brush color Currentpaint.setcolor (COLOR.ARGB (210, 251, 248, 29));      Notcurrentpaint.setcolor (COLOR.ARGB (140, 255, 255, 255));        Linepaint.setcolor (color.red);    Currentpaint.settextsize (textSize);        Currentpaint.settypeface (Typeface.serif);    Notcurrentpaint.settextsize (nottextsize);        Notcurrentpaint.settypeface (Typeface.default);    Linepaint.settextsize (textSize);    Linepaint.settypeface (Typeface.serif); } @Overridepublic void Invalidate () {//TODO auto-generated method Stubsuper.invalidate (); Lrctextview.invalidate ();} @Overridepublic void onscrollchanged () {//TODO auto-generated Method stub} @Overridepublic boolean OnTouch (View V, Motion Event event) {//TODO auto-generated Method stub//interface cannot be touched if (!CANTOUCHLRC) return True;switch (Event.getaction ()) {case Motionevent.action_move:scrolly=this.getscrolly ();p os= (int) (this.getscrolly ()/textheight); canDrawLine=true; This.invalidate (); LOG.I ("Lrcview", "Action_down"); Break;casemotionevent.action_up:musicmanager.getinstance (). SetProgress ( Lrclists.get (POS). getlrctIME ()); Candrawline=false;pos=-1;this.invalidate (); break;} return false;} Private Handler handler=new Handler () {@Overridepublic void Handlemessage (Message msg) {//TODO auto-generated method stub Invalidate ();}};}




Android Music player Development Sweetmusicplayer Smart match Local lyrics

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.