Beispiel #1
0
	/**
	 * 最重要的一个方法,它根据读到的歌词内容 进行初始化,比如把歌词一句一句分开并计算好时间
	 * 
	 * @param content
	 *            歌词内容
	 */
	private void init(String content) {
		// 如果歌词的内容为空,则后面就不用执行了
		// 直接显示歌曲名就可以了
		if (content == null || content.trim().equals("")) {
			list.add(new Sentence(info.getFormattedName(), Integer.MIN_VALUE,
					Integer.MAX_VALUE));
			return;
		}
		try {
			BufferedReader br = new BufferedReader(new StringReader(content));
			String temp = null;
			while ((temp = br.readLine()) != null) {
				parseLine(temp.trim());
			}
			br.close();
			// 读进来以后就排序了
			Collections.sort(list, new Comparator<Sentence>() {

				public int compare(Sentence o1, Sentence o2) {
					return (int) (o1.getFromTime() - o2.getFromTime());
				}
			});
			// 处理第一句歌词的起始情况,无论怎么样,加上歌名做为第一句歌词,并把它的
			// 结尾为真正第一句歌词的开始
			if (list.size() == 0) {
				list.add(new Sentence(info.getFormattedName(), 0,
						Integer.MAX_VALUE));
				return;
			} else {
				Sentence first = list.get(0);
				list.add(
						0,
						new Sentence(info.getFormattedName(), 0, first
								.getFromTime()));
			}

			int size = list.size();
			for (int i = 0; i < size; i++) {
				Sentence next = null;
				if (i + 1 < size) {
					next = list.get(i + 1);
				}
				Sentence now = list.get(i);
				if (next != null) {
					now.setToTime(next.getFromTime() - 1);
				}
			}
			// 如果就是没有怎么办,那就只显示一句歌名了
			if (list.size() == 1) {
				list.get(0).setToTime(Integer.MAX_VALUE);
			} else {
				Sentence last = list.get(list.size() - 1);
				last.setToTime(info == null ? Integer.MAX_VALUE : info
						.getLength() * 1000 + 1000);
			}
		} catch (Exception ex) {
			Logger.getLogger(Lyric.class.getName()).log(Level.SEVERE, null, ex);
		}
	}
Beispiel #2
0
	/**
	 * 是否匹配了歌曲名
	 * 
	 * @param info
	 *            歌曲信息
	 * @param file
	 *            侯选文件
	 * @return 是否合格
	 */
	private boolean matchSongName(PlayListItem info, File file) {
		String name = info.getFormattedName();
		String rn = file.getName()
				.substring(0, file.getName().lastIndexOf("."));
		if (name.equalsIgnoreCase(rn) || info.getTitle().equalsIgnoreCase(rn)) {
			return true;
		} else {
			return false;
		}
	}
Beispiel #3
0
	/**
	 * 读取某个指定的歌词文件,这个构造函数一般用于 拖放歌词文件到歌词窗口时调用的,拖放以后,两个自动关联
	 * 
	 * @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;
	}
Beispiel #4
0
	/**
	 * 调整整体的时间,比如歌词统一快多少 或者歌词统一慢多少,为正说明要快,为负说明要慢
	 * 
	 * @param time
	 *            要调的时间,单位是毫秒
	 */
	public void adjustTime(int time) {
		// 如果是只有一个显示的,那就说明没有什么效对的意义了,直接返回
		if (list.size() == 1) {
			return;
		}
		offset += time;
		info.setOffset(offset);
	}
Beispiel #5
0
	/**
	 * 把下载到的歌词保存起来,免得下次再去找
	 * 
	 * @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);
		}
	}
Beispiel #6
0
	/**
	 * 是否完全匹配,完全匹配是指直接对应到ID3V1的标签, 如果一样,则完全匹配了,完全匹配的LRC的文件格式是: 阿木 - 有一种爱叫放手.lrc
	 * 
	 * @param info
	 *            歌曲信息
	 * @param file
	 *            侯选文件
	 * @return 是否合格
	 */
	private boolean matchAll(PlayListItem info, File file) {
		String name = info.getFormattedName();
		String fn = file.getName()
				.substring(0, file.getName().lastIndexOf("."));
		if (name.equals(fn)) {
			return true;
		} else {
			return false;
		}
	}
Beispiel #7
0
	/**
	 * 用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();
		}

	}
Beispiel #8
0
	/**
	 * 把如00:00.00这样的字符串转化成 毫秒数的时间,比如 01:10.34就是一分钟加上10秒再加上340毫秒 也就是返回70340毫秒
	 * 
	 * @param time
	 *            字符串的时间
	 * @return 此时间表示的毫秒
	 */
	private long parseTime(String time) {
		String[] ss = time.split("\\:|\\.");
		// 如果 是两位以后,就非法了
		if (ss.length < 2) {
			return -1;
		} else if (ss.length == 2) {// 如果正好两位,就算分秒
			try {
				// 先看有没有一个是记录了整体偏移量的
				if (offset == 0 && ss[0].equalsIgnoreCase("offset")) {
					offset = Integer.parseInt(ss[1]);
					info.setOffset(offset);
					System.err.println("整体的偏移量:" + offset);
					return -1;
				}
				int min = Integer.parseInt(ss[0]);
				int sec = Integer.parseInt(ss[1]);
				if (min < 0 || sec < 0 || sec >= 60) {
					throw new RuntimeException("数字不合法!");
				}
				// System.out.println("time" + (min * 60 + sec) * 1000L);
				return (min * 60 + sec) * 1000L;
			} catch (Exception exe) {
				return -1;
			}
		} else if (ss.length == 3) {// 如果正好三位,就算分秒,十毫秒
			try {
				int min = Integer.parseInt(ss[0]);
				int sec = Integer.parseInt(ss[1]);
				int mm = Integer.parseInt(ss[2]);
				if (min < 0 || sec < 0 || sec >= 60 || mm < 0 || mm > 99) {
					throw new RuntimeException("数字不合法!");
				}
				// System.out.println("time" + (min * 60 + sec) * 1000L + mm *
				// 10);
				return (min * 60 + sec) * 1000L + mm * 10;
			} catch (Exception exe) {
				return -1;
			}
		} else {// 否则也非法
			return -1;
		}
	}
Beispiel #9
0
	/**
	 * 根据歌的信息去初始化,这个时候 可能在本地找到歌词文件,也可能要去网络上搜索了
	 * 
	 * @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("");
		}
	}
Beispiel #10
0
	/**
	 * 分析这一行的内容,根据这内容 以及标签的数量生成若干个Sentence对象 当此行中的时间标签分布不在一起时,也要能分析出来 所以更改了一些实现
	 * 20080824更新
	 * 
	 * @param line
	 *            这一行
	 */
	private void parseLine(String line) {
		if (line.equals("")) {
			return;
		}
		Matcher matcher = pattern.matcher(line);
		List<String> temp = new ArrayList<String>();
		int lastIndex = -1;// 最后一个时间标签的下标
		int lastLength = -1;// 最后一个时间标签的长度
		while (matcher.find()) {
			String s = matcher.group();
			int index = line.indexOf("[" + s + "]");
			if (lastIndex != -1 && index - lastIndex > lastLength + 2) {
				// 如果大于上次的大小,则中间夹了别的内容在里面
				// 这个时候就要分段了
				String content = line.substring(lastIndex + lastLength + 2,
						index);
				for (String str : temp) {
					long t = parseTime(str);
					if (t != -1) {
						System.out.println("content = " + content);
						System.out.println("t = " + t);
						list.add(new Sentence(content, t));
					}
				}
				temp.clear();
			}
			temp.add(s);
			lastIndex = index;
			lastLength = s.length();
		}
		// 如果列表为空,则表示本行没有分析出任何标签
		if (temp.isEmpty()) {
			return;
		}
		try {
			int length = lastLength + 2 + lastIndex;
			String content = line.substring(length > line.length() ? line
					.length() : length);
			// if (Config.getConfig().isCutBlankChars()) {
			// content = content.trim();
			// }
			// 当已经有了偏移量的时候,就不再分析了
			if (content.equals("") && offset == 0) {
				for (String s : temp) {
					int of = parseOffset(s);
					if (of != Integer.MAX_VALUE) {
						offset = of;
						info.setOffset(offset);
						break;// 只分析一次
					}
				}
				return;
			}
			for (String s : temp) {
				long t = parseTime(s);
				if (t != -1) {
					list.add(new Sentence(content, t));
					System.out.println("content = " + content);
					System.out.println("t = " + t);
				}
			}
		} catch (Exception exe) {
		}
	}
Beispiel #11
0
	/**
	 * 根据歌词内容和播放项构造一个 歌词对象
	 * 
	 * @param lyric
	 *            歌词内容
	 * @param info
	 *            播放项
	 */
	public Lyric(String lyric, PlayListItem info) {
		this.offset = info.getOffset();
		this.info = info;
		this.init(lyric);
		initDone = true;
	}