在开发音乐网站或APP的时候,都必须要面对这一个问题:如何让正在播放的歌曲的歌词与音频对应?也就是歌曲正在唱哪一句对应显示这一句的歌词?这便是今天这篇博客主要谈论的主题,先抛开爬虫爬取这一说,今天讲的这个方法需要把歌词录入TXT文件中,然后用Java的各种技术来实现歌词与歌曲对应的效果。直接显示所有歌词就比较简单了,直接用IO流得到歌词并输出至网页即可;稍微复杂的就是只在播放那一句歌时显示那一句对应的歌词
我的设计思路是这样的,首先在歌词文本文件中将歌词出现的时刻录入文件(当然如果能找到带有时间点的歌词更好不用再录了),然后在项目中新建一个jsp,这个jsp负责根据时刻查找到文件中的对应时刻的歌词,同时将这句歌词存入cookie中以便下一句歌词出来之前照常显示,然后在js中通过ajax异步获取并显示,这个js函数每秒执行一次,如果文件中没有该秒,就取出cookie中的歌词并显示,这样保证每一秒都会有歌词显示。。。
感觉叙述的有些啰嗦,可能还没说清楚,下面就用代码来详细实现吧。
首先在页面中定义一个歌词显示的地方,并为其设置一个id
<span id="lyric"></span>
然后在js的monitor函数中添加ajax部分,其中url中传入要获取歌词的歌曲名及当前时刻以及获取类型(包括获取全部歌词和获取当前播放的一句歌词)
var xmlHttp=false;
if(window.XMLHttpRequest){xmlHttp=new XMLHttpRequest();
}else if(window.ActiveXObject){xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
var mname=encodeURI(encodeURI(cname));//编码中文歌词名var url="loadLyric.jsp?name="+mname+"&time="+getTime(ctime)+"&type=1";xmlHttp.open("post", url, true);xmlHttp.onreadystatechange=function() {//异步获取的歌词加载到歌词显示区域document.getElementById("lyric").innerHTML=xmlHttp.responseText;
}
xmlHttp.send();
接着,再用以下方法,每秒执行一次该函数,异步获取一次歌词
window.setInterval("monitor()", 1000);
最后,编写ajax异步获取的歌词的jsp,这个也是实时获取歌词的关键
String name=request.getParameter("name");
name=URLDecoder.decode(name,"utf-8");
String time=request.getParameter("time");
String type=request.getParameter("type");
if(type.equals("1")){//monitor函数中调用,当前播放歌词
try{File file=new File("E:/AAAA/lyric/Time_"+name+".txt");if(!file.exists()){//说明是在云服务器上file=new File("/home/ubuntu/tomcat/webapps/Minimusic/lyric/Time_"+name+".txt");}byte[] s=new byte[2048];FileInputStream fis=new FileInputStream(file);int m=fis.read(s);String ly=new String(s,"utf-8");//所有歌词String l="";//最终为当前播放歌词if(ly.contains(time)){//把文件中与当前时间匹配的时间点前面的歌词截取出来l=ly.substring(0,ly.indexOf(time)+5);String ls[]=l.split("《");l=ls[ls.length-2];//当前播放的歌词if(l.contains(":")){l=l.substring(l.indexOf(":")+3);}//将这句词存入cookie以供下一句歌词出现之前显示Cookie cookie=new Cookie("lyric",URLEncoder.encode(l,"utf-8"));cookie.setMaxAge(1*60);response.addCookie(cookie);}else{//如果歌词文件没有该时间点,则显示利用cookie记住的歌词Cookie[] cs=request.getCookies();for(int i=0;i<cs.length;i++){if(cs[i].getName().toString().equals("lyric")){l=cs[i].getValue().toString();l=URLDecoder.decode(l,"utf-8");}}}out.write(l);
}catch(Exception e){out.write("暂无歌词");
}
}
以下是我存储的歌词文本的样式,结合上方的Java程序,即可实现每秒获取一次歌词并显示至页面指定位置
要获取所有的歌词并显示就相对比较简单了,只需在上述jsp中添加如下代码
else{//type=2,play函数中调用,所有歌词try{File file=new File("E:/AAAA/lyric/"+name+".txt");if(!file.exists()){file=new File("/home/ubuntu/tomcat/webapps/Minimusic/lyric/"+name+".txt");}//FileReader fr=new FileReader(file);//char s[]=new char[2048];byte[] s=new byte[2048];FileInputStream fis=new FileInputStream(file);int m=fis.read(s);String ly=new String(s,"utf-8");//所有歌词out.println("<font size='-1' color='white'>"+ly+"</font>");}catch(Exception e){out.write("暂无歌词");}
}
今天的博客就写到这里了,如果有什么疑问,可以在评论区里交流。附哆啦网和553音乐,欢迎访问