第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > android 本地lrc 歌词同步 android 音乐播放器-------歌词同步 lrc

android 本地lrc 歌词同步 android 音乐播放器-------歌词同步 lrc

时间:2018-11-22 02:24:36

相关推荐

android 本地lrc 歌词同步 android 音乐播放器-------歌词同步 lrc

lrc格式:

[al:这首歌所在的唱片集]

[ar:歌词作者]

[by:本LRC文件的创建者]

[offset:+/- 以毫秒为单位整体时间戳调整,+增加,-减小]

[re:创建此LRC文件的播放器或编辑器]

[ti:歌词(歌曲)的标题]

[ve:程序的版本]

时间标记的格式为[mm:ss.xx]其中mm为分钟数,ss为秒数并且xx为百分之一秒

例子:

[ti:爱]

[ar:小虎队]

[al:华纳国语情浓13首]

[by:爱上你了音乐网]

百度百科关于lrc的解释:

/view/80650.htm

[ti:青花瓷]

[ar:周杰伦]

[al:我很忙]

[by:张琪]

[00:00.00]发送短信18到291199下载该歌曲到手机

[00:01.11]青花瓷

[03:36.49]

[00:21.39]素眉勾勒秋千话北风龙转丹

[00:26.08]屏层鸟绘的牡丹一如你梳妆

[00:30.46]黯然腾香透过窗心事我了然

[00:34.93]宣纸上皱边直尺各一半

[00:39.49]油色渲染侍女图因为被失藏

[00:43.83]而你嫣然的一笑如含苞待放

[00:48.30]你的美一缕飘散

[00:50.77]去到我去不了的地方

[02:23.97][00:55.77]

[03:01.92][02:25.63][00:56.90]天正在等烟雨

[03:03.57][02:27.91][00:58.99]而我在等你

[03:05.92][02:30.44][01:00.93]炊烟袅袅升起

[03:07.76][02:32.25][01:03.49]隔江千万里

[03:10.36][02:34.85][01:05.84]在平地书刻你房间上的飘影

[03:14.67][02:38.73][01:09.87]就当我为遇见你伏笔

[03:18.83][02:43.35][01:14.34]天正在等烟雨

[03:21.20][02:45.60][01:16.68]而我在等你

[03:23.71][02:48.01][01:18.99]月色被打捞起

[03:25.74][02:50.10][01:21.18]掩盖了结局

[03:28.33][02:52.54][01:23.72]如传世的青花瓷在独自美丽

[03:32.30][02:56.67][01:27.65]你眼的笑意

[01:50.25]色白花青的景已跃然于碗底

[01:54.69]临摹宋体落款时却惦记着你

[01:59.22]你隐藏在药效里一千年的秘密

[02:03.75]急溪里犹如羞花沾落地

[02:08.32]林外芭蕉惹咒语

[02:10.57]梦幻的铜绿

[02:12.84]而我路过那江南小镇的等你

[02:17.19]在泼墨山水画里

[02:19.75]你从墨色深处被隐去

前面“[ ]”中的数字表示其后歌词的开始时间。例如,“[01:50.25]色白花青的景已跃然于碗底”表示在1分50.25秒时,歌词内容是“色白花青的景已跃 然于碗底”。

还有一种形式是“[03:01.92][02:25.63][00:56.90]天正在等烟雨”这种形式常用于赋格部分(俗称:歌曲的高潮部分),它表示 在 03:01.92, 02:25.63, 00:56.90 时的歌词都是“天正在等烟雨”。

代码实现,歌词类

packagecom.android.music;

importjava.io.BufferedInputStream;

importjava.io.BufferedReader;

importjava.io.File;

importjava.io.FileInputStream;

importjava.io.InputStream;

importjava.io.InputStreamReader;

importjava.util.Collections;

parator;

importjava.util.Vector;

importandroid.util.Log;

publicclassLRCUtils{

privatestaticfinalStringTAG="LRCUtils";

MediaPlayActivitymediaPlay;

privatestaticVectorlrclist;

privatebooleanIsLyricExist=false;

privateintlastLine=0;

publicLRCUtils(MediaPlayActivitymediaPlayActivity){

mediaPlay=mediaPlayActivity;

}

publicvoidRefreshLRC(intcurrent)

{

if(IsLyricExist){

for(inti=0;i

{

if(current

if(i==0||current>=lrclist.get(i-1).getTimePoint())

{

Log.d(TAG,"string="+lrclist.get(i-1).getLrcString());

mediaPlay.setLRCText(lrclist.get(i-1).getLrcString(),lastLine!=(i-1));

lastLine=i-1;

//playlrcText.setText(lrclist.get(i-1).getLrcString());

}

}

}

}

publicvoidReadLRC(Filef)

{

try

{

if(!f.exists())

{

Log.d(TAG,"notexitthelrcfile");

IsLyricExist=false;

//strLRC=main.getResources().getString(R.string.lrcservice_no_lyric_found);

}

else

{

lrclist=newVector();

IsLyricExist=true;

InputStreamis=newBufferedInputStream(newFileInputStream(f));

BufferedReaderbr=newBufferedReader(newInputStreamReader(is,GetCharset(f)));

StringstrTemp="";

while((strTemp=br.readLine())!=null)

{

//Log.d(TAG,"strTemp="+strTemp);

strTemp=AnalyzeLRC(strTemp);//???з???LRC

}

br.close();

is.close();

Collections.sort(lrclist,newSort());

for(inti=0;i

Log.d(TAG,"time="+lrclist.get(i).getTimePoint()+"string="+lrclist.get(i).getLrcString());

}

}

}

catch(Exceptione)

{

e.printStackTrace();

}

}

privateStringAnalyzeLRC(StringLRCText)

{

try

{

intpos1=LRCText.indexOf("[");//????????????

intpos2=LRCText.indexOf("]");//????????????

//????????????????????λ?????????[????

if(pos1==0&&pos2!=-1)

{//???

Longtime[]=newLong[GetPossiblyTagCount(LRCText)];

time[0]=TimeToLong(LRCText.substring(pos1+1,pos2));//???????ε????

if(time[0]==-1)//??????????

return"";//LRCText

StringstrLineRemaining=LRCText;

inti=1;

while(pos1==0&&pos2!=-1)

{

strLineRemaining=strLineRemaining.substring(pos2+1);//??μ?????

pos1=strLineRemaining.indexOf("[");

pos2=strLineRemaining.indexOf("]");

if(pos2!=-1)

{

time[i]=TimeToLong(strLineRemaining.substring(pos1+1,pos2));

if(time[i]==-1)//??????????

return"";//LRCText

i++;

}

}

timelrctl=newtimelrc();

for(intj=0;j

{

if(time[j]!=null)

{

//Log.d(TAG,"time["+j+"]="+time[j].intValue()+"strLineRemaining="+strLineRemaining);

tl.setTimePoint(time[j].intValue());

tl.setLrcString(strLineRemaining);

lrclist.add(tl);

tl=newtimelrc();

//map.put(time[j],strLineRemaining);

//lstTimeStamp.add(time[j]);

}

}

returnstrLineRemaining;

}

else

return"";

}

catch(Exceptione)

{

return"";

}

}

privateintGetPossiblyTagCount(StringLine)

{

StringstrCount1[]=Line.split("//[");

StringstrCount2[]=Line.split("//]");

if(strCount1.length==0&&strCount2.length==0)

return1;

elseif(strCount1.length>strCount2.length)

returnstrCount1.length;

else

returnstrCount2.length;

}

publiclongTimeToLong(StringTime)

{

try

{

String[]s1=Time.split(":");

intmin=Integer.parseInt(s1[0]);

String[]s2=s1[1].split("//.");

intsec=Integer.parseInt(s2[0]);

intmill=0;

if(s2.length>1)

mill=Integer.parseInt(s2[1]);

returnmin*60*1000+sec*1000+mill*10;

}

catch(Exceptione)

{

return-1;

}

}

publicStringGetCharset(Filefile){

Stringcharset="GBK";

byte[]first3Bytes=newbyte[3];

try

{

booleanchecked=false;

BufferedInputStreambis=newBufferedInputStream(newFileInputStream(file));

bis.mark(0);

intread=bis.read(first3Bytes,0,3);

if(read==-1)

returncharset;

if(first3Bytes[0]==(byte)0xFF&&first3Bytes[1]==(byte)0xFE)

{

charset="UTF-16LE";

checked=true;

}

elseif(first3Bytes[0]==(byte)0xFE&&first3Bytes[1]==(byte)0xFF)

{

charset="UTF-16BE";

checked=true;

}

elseif(first3Bytes[0]==(byte)0xEF&&first3Bytes[1]==(byte)0xBB&&first3Bytes[2]==(byte)0xBF)

{

charset="UTF-8";

checked=true;

}

bis.reset();

if(!checked)

{

intloc=0;

while((read=bis.read())!=-1)

{

loc++;

if(read>=0xF0)

break;

if(0x80<=read&&read<=0xBF)//????????BF???μ???????GBK

break;

if(0xC0<=read&&read<=0xDF)

{

read=bis.read();

if(0x80<=read&&read<=0xBF)//????(0xC0-0xDF),(0x80-xBF)???????GB??????

continue;

else

break;

}

elseif(0xE0<=read&&read<=0xEF)

{//??п??????????????С

read=bis.read();

if(0x80<=read&&read<=0xBF)

{

read=bis.read();

if(0x80<=read&&read<=0xBF)

{

charset="UTF-8";

break;

}

else

break;

}

else

break;

}

}

}

bis.close();

}

catch(Exceptione)

{

e.printStackTrace();

}

returncharset;

}

privateclassSortimplementsComparator{

publicSort(){

}

publicintcompare(timelrctl1,timelrctl2){

returnsortUp(tl1,tl2);

}

privateintsortUp(timelrctl1,timelrctl2){

if(tl1.getTimePoint()

return-1;

elseif(tl1.getTimePoint()>tl2.getTimePoint())

return1;

else

return0;

}

}

publicstaticclasstimelrc{

privateStringlrcString;

privateintsleepTime;

privateinttimePoint;

timelrc(){

lrcString=null;

sleepTime=0;

timePoint=0;

}

publicvoidsetLrcString(Stringlrc){

lrcString=lrc;

}

publicvoidsetSleepTime(inttime){

sleepTime=time;

}

publicvoidsetTimePoint(inttPoint){

timePoint=tPoint;

}

publicStringgetLrcString(){

returnlrcString;

}

publicintgetSleepTime(){

returnsleepTime;

}

publicintgetTimePoint(){

returntimePoint;

}

};

}

实现思路:

定义一个类,timelrc,用来存放每一句歌词的内容和时间,每当播放的歌曲的时间改变时,即显示播放的seekbar改变时,刷新歌词RefreshLRC(int),并将取得的歌词的getLrcString()显示到应用程序中。

使用方法:

在音乐播放的activity界面,获取当前播放歌曲的path,歌词路径。

privatevoidgetLrcPath(Stringpath){

Log.d(TAG,"path="+path);

if(path!=null){

path=path.substring(0,path.lastIndexOf(".")).concat(".lrc");

Filefile=newFile(path);

lrcService.ReadLRC(file);

}

}

通过该函数的调用,如上类会将歌词存储起来。

当播放时间改变时,调用lrcService.RefreshLRC(current); 刷新

在播放界面显示正在播放的歌词内容

public void setLRCText(String lrcString,boolean changeLine) {

if(changeLine){

flipperLrc.showNext();

}

playlrcText.setText(lrcString);

}

(未完待续。。。)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。