/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.zhaofeng.util.lrc;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 表示一首歌的歌词对象,它可以以某种方式来画自己
*
* @author hadeslee
*/
public class Lyric implements Serializable {
private static final long serialVersionUID = 20071125L;
private String HOME = "/mnt/sdcard/";
private static Logger log = Logger.getLogger(Lyric.class.getName());
private int width;// 表示歌词的显示区域的宽度
private int height;// 表示歌词的显示区域的高度
private long time;// 表示当前的时间是多少了。以毫秒为单位
private long tempTime;// 表示一个暂时的时间,用于拖动的时候,确定应该到哪了
public List<Sentence> list = new ArrayList<Sentence>();// 里面装的是所有的句子
private boolean isMoving;// 是否正在被拖动
private int currentIndex;// 当前正在显示的歌词的下标
private boolean initDone;// 是否初始化完毕了
private transient PlayListItem info;// 有关于这首歌的信息
private transient File file;// 该歌词所存在文件
private boolean enabled = true;// 是否起用了该对象,默认是起用的
private long during = Integer.MAX_VALUE;// 这首歌的长度
private int offset;// 整首歌的偏移量
// 用于缓存的一个正则表达式对象
private static final Pattern pattern = Pattern
.compile("(?<=\\[).*?(?=\\])");
/**
* 用ID3V1标签的字节和歌名来初始化歌词 歌词将自动在本地或者网络上搜索相关的歌词并建立关联
* 本地搜索将硬编码为user.home文件夹下面的Lyrics文件夹 以后改为可以手动设置.
*
* @param songName
* 歌名
* @param data
* ID3V1的数据
*/
public Lyric(final PlayListItem info) {
this.offset = info.getOffset();
this.info = info;
// this.during = info.getDuration();
this.file = info.getLyricFile();
log.info("传进来的歌名是:" + info.toString());
// 只要有关联好了的,就不用搜索了直接用就是了
if (file != null && file.exists()) {
log.log(Level.INFO, "不用找了,直接关联到的歌词是:" + file);
init(file);
initDone = true;
return;
} else {
// 否则就起一个线程去找了,先是本地找,然后再是网络上找
new Thread() {
public void run() {
doInit(info);
initDone = true;
}
}.start();
}
}
/**
* 读取某个指定的歌词文件,这个构造函数一般用于 拖放歌词文件到歌词窗口时调用的,拖放以后,两个自动关联
*
* @param file
* 歌词文件
* @param info
* 歌曲信息
*/
public Lyric(File file, PlayListItem info) {
System.out.println(" Lyric file" + file);
this.offset = info.getOffset();
this.file = file;
this.info = info;
init(file);
initDone = true;
}
/**
* 根据歌词内容和播放项构造一个 歌词对象
*
* @param lyric
* 歌词内容
* @param info
* 播放项
*/
public Lyric(String lyric, PlayListItem info) {
this.offset = info.getOffset();
this.info = info;
this.init(lyric);
initDone = true;
}
private void doInit(PlayListItem info) {
init(info);
Sentence temp = null;
// 这个时候就要去网络上找了
if (list.size() == 1) {
temp = list.remove(0);
String lyric = "";
if (lyric != null) {
init(lyric);
// saveLyric(lyric, info);
} else {// 如果网络也没有找到,就要加回去了
}
list.add(temp);
}
}
/**
* 把下载到的歌词保存起来,免得下次再去找
*
* @param lyric
* 歌词内容
* @param info
* 歌的信息
*/
private void saveLyric(String lyric, PlayListItem info) {
try {
// 如果歌手不为空,则以歌手名+歌曲名为最好组合
String name = info.getFormattedName() + ".lrc";
File dir = new File(HOME, "Lyrics" + File.separator);
// File dir = Config.getConfig().getSaveLyricDir();
dir.mkdirs();
file = new File(dir, name);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(file), "GBK"));
bw.write(lyric);
bw.close();
info.setLyricFile(file);
log.info("保存完毕,保存在:" + file);
} catch (Exception exe) {
log.log(Level.SEVERE, "保存歌词出错", exe);
}
}
/**
* 设置此歌词是否起用了,否则就不动了
*
* @param b
* 是否起用
*/
public void setEnabled(boolean b) {
this.enabled = b;
}
/**
* 得到此歌词保存的地方
*
* @return 文件
*/
public File getLyricFile() {
return file;
}
/**
* 调整整体的时间,比如歌词统一快多少 或者歌词统一慢多少,为正说明要快,为负说明要慢
*
* @param time
* 要调的时间,单位是毫秒
*/
public void adjustTime(int time) {
// 如果是只有一个显示的,那就说明没有什么效对的意义了,直接返回
if (list.size() == 1) {
return;
}
offset += time;
info.setOffset(offset);
}
/**
* 根据一个文件夹,和一个歌曲的信息 从本地搜到最匹配的歌词
*
* @param dir
* 目录
* @param info
* 歌曲信息
* @return 歌词文件
*/
private File getMathedLyricFile(File dir, PlayListItem info) {
File matched = null;// 已经匹配的文件
File[] fs = dir.listFiles(new FileFilter() {
public boolean accept(File pathname) {
return pathname.getName().toLowerCase().endsWith(".lrc");
}
});
for (File f : fs) {
// 全部匹配或者部分匹配都行
if (matchAll(info, f) || matchSongName(info, f)) {
matched = f;
break;
}
}
return matched;
}
/**
* 根据歌的信息去初始化,这个时候 可能在本地找到歌词文件,也可能要去网络上搜索了
*
* @param info
* 歌曲信息
*/
private void init(PlayListItem info) {
File matched = null;
// 得到歌曲信息后,先搜索HOME文件夹
// 如果还不存在的话,那建一个目录,然后直接退出不管了
File dir = new File(HOME, "Lyrics" + File.separator);
if (!dir.exists()) {
dir.mkdirs();
// }
matched = getMathedLyricFile(dir, info);
}
log.info("找到的是:" + matched);
if (matched != null && matched.exists()) {
info.setLyricFile(matched);
file = matched;
init(matched);
} else {
init("");
}
}
/**
* 根据文件来初始化
*
* @param file
* 文件
*/
private void init(File file) {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(
file), "GBK"));
StringBuilder sb = new StringBuilder();
String temp = null;
while ((temp = br.readLine()) != null) {
sb.append(temp).append("\n");
}
init(sb.toString());
} catch (Exception ex) {
Logger.getLogger(Lyric.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
br.close();
} catch (Exception ex) {
Logger.getLogger(Lyric.class.getName()).log(Level.SEVERE, null,
ex);
}
}
}
/**
* 是否完全匹配,完全匹配是指直接对应到ID3V1的标签, 如果一样,则完全匹配了,完全匹配的LRC的文件格式是: 阿木 - 有一种爱叫放手.lrc
*
* @param info
* 歌曲信息
* @param file
* 侯选文件
* @return 是否合格
*/
private boolean matchAll
荣华富贵8
- 粉丝: 221
- 资源: 7653
最新资源
- 基于Vue.js高校学生选课系统-springboot毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- 基于Vue的米家商城的设计与实现-springboot毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- 基于Web的视频及游戏管理平台的设计及实现_0816q-springboot毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- 基于Spring Boot的阳光音乐厅订票系统_9z622-springboot毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- 基于java语言的考试信息报名系统_5n9zn--论文-springboot毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- 基于Java的小区物业管理系统设计与实现--论文-springboot毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- WORD办公教程网站模板 (H5自适应) WPS办公资源源码
- 基于改进遗传算法的风电场优化调度策略验证,改善风电场整体输出功率,达到最大功率输出,采用matlab编写,内容非常详实和完整
- 基于Layui和SpringBoot动漫商城管理的设计与实现--论文-springboot毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- 基于spring boot的疫情信息管理系统-springboot毕业项目,适合计算机毕-设、实训项目、大作业学习.rar
- 基于Spring boot的名城小区物业管理系统-springboot毕业项目,适合计算机毕-设、实训项目、大作业学习.rar
- 基于Spring Boot的企业员工薪酬关系系统的设计-springboot毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- 基于Spring Boot在线远程考试系统的设计与实现-springboot毕业项目,适合计算机毕-设、实训项目、大作业学习.rar
- springboot生活分享共享平台(源码+论文)-springboot毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- springboot健身房管理系统006(源码+sql)-springboot毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- 基于python+django+mysql实现教师评价系统设计与开发
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈