Rover12421's Blog

The End.

酷狗krc歌词转换成lrc歌词

在手机上用酷狗下了些歌曲,想靠到笔记本上听,结果歌词显示不了,仔细看了下才发现酷狗的歌词格式是krc的,找了下资料,确实有工具可以转换,是windows平台的,但是我用的是Ubuntu,不想弄到虚拟机里搞,于是把酷狗的apk反编译了.自己用java写了个简单转换工具.源码奉上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
package com.rover12421.kugou.lyric;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;

import com.jcraft.jzlib.ZInputStream;

public class Krc2Lrc {

  public static void main(String[] args) throws IOException {
//       if (args.length != 1) {
//           System.out.println("请输入文件夹路径!");
//           return;
//       }
//
//       File file = new File(args[0]);
//       if (!file.isDirectory()) {
//           System.out.println(args[0] + " 不是一个有效的文件夹路径!");
//           return;
//       }

      File file = new File("/home/rover12421/Downloads/Music/墨明棋妙");

      String krcFiles[] = file.list(new FilenameFilter() {

          @Override
          public boolean accept(File dir, String name) {
              if (name.toLowerCase().endsWith(".krc")) {
                  return true;
              }
              return false;
          }
      });

      for (int i = 0; i < krcFiles.length; i++) {
          String krc = file.getAbsolutePath() + File.separator + krcFiles[i];
          String lrc = krc.substring(0, krc.length() - 3) + "lrc";
          System.out.println(krc + " >>> " + lrc);
          convertToLrc(krc, lrc);
      }

      System.out.println(krcFiles.length + " 个krc文件转换完成!");

//       convertToLrc("/home/rover12421/Downloads/Music/墨明棋妙/墨明棋妙 - 大唐红颜赋 - 乐团.krc", "/home/rover12421/Downloads/Music/墨明棋妙/墨明棋妙 - 大唐红颜赋 - 乐团.lrc");
  }

  public static void convertToLrc(String krc, String lrc) {
      char[] key = new char[]{0x40, 0x47, 0x61, 0x77, 0x5e, 0x32, 0x74, 0x47, 0x51, 0x36, 0x31, 0x2d, 0xce, 0xd2, 0x6e, 0x69};

      FileInputStream fis = null;
      BufferedInputStream bif = null;
      FileOutputStream fos = null;

      try {
          fis = new FileInputStream(krc);
          bif = new BufferedInputStream(fis);

          byte[] bytes = new byte[4];
          bif.read(bytes);
          String flag = "krc1";
          if (!flag.equalsIgnoreCase(new String(bytes))) {
              System.out.println("the file " + krc + " is non kugou krc file format!!!");
              bif.close();
              fis.close();
              return;
          }

          File krcFile = new File(krc);
          int filelen = (int)krcFile.length();
          bytes = new byte[filelen-4];
          bif.read(bytes);

          for (int i = 0; i < bytes.length; i++) {
              int off = i % key.length;
              bytes[i] ^= key[off];
          }

          bytes = unzip(bytes);

          String lrcStr = new String(bytes, "utf-8");
          lrcStr = timeFromatConvert(lrcStr);
//           System.out.println(lrcStr);

          fos = new FileOutputStream(lrc);
          fos.write(lrcStr.getBytes());

      } catch (FileNotFoundException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      } finally {
          if (bif != null) {
              try {
                  bif.close();
              } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
          }
          if (fis != null) {
              try {
                  fis.close();
              } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
          }
          if (fos != null) {
              try {
                  fos.close();
              } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
          }
      }

  }

  public static byte[] unzip(byte[] bytes) throws IOException {
      ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
      ZInputStream zis = new ZInputStream(bais);
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      byte[] tmp = new byte[1024];
      int len = -1;

      while ((len = zis.read(tmp, 0, 1024)) != -1) {
          baos.write(tmp, 0, len);
      }

      tmp = baos.toByteArray();
      baos.close();
      bais.close();
      return tmp;
  }

  private static String timeFromatConvert(String str) {
      //去掉每个字的时间
      str = str.replaceAll("<\\d+,\\d+,\\d+>", "");
      String[] lines = str.split("\r\n");

      str = "";
      for (int i = 0; i < lines.length; i++) {
          String line = lines[i];
          int off = line.indexOf(",");

          if (off > 0) {
              try {
                  String timeStr = line.substring(1, off);
                  long time = Long.parseLong(timeStr);
                  //时
                  timeStr = "[0" + (time/3600/1000) + ":";
                  timeStr = timeStr.substring(timeStr.length() - 4);
                  //分
                  String tmp = "0" + ((time/60/1000) % 60) + ":";
                  timeStr += tmp.substring(tmp.length()-3);
                  //秒
                  tmp = "0" + ((time/1000) % 60) + ".";
                  timeStr += tmp.substring(tmp.length()-3);
                  //毫秒
                  tmp = "0" + ((time%1000) / 100) + "]";
                  timeStr += tmp.substring(tmp.length()-3);

                  line = line.replaceFirst("\\[\\d+,\\d+\\]", timeStr);
//                   System.out.println(i + " >>> " + line + " >>> " + timeStr);
              } catch (Exception e) {
                  // TODO: handle exception
                  //只要有异常就用原始line,说明这里不是时间,无需转换
              }

          }

          str += line + "\r\n";
      }

      return str;
  }

}

Comments