酷狗krc歌词解析并转换为lrc歌词php版

三月 06, 2019 | views
Comments 0

最近在进行一次对酷狗音乐歌词采集时发现酷狗音乐的歌词直接浏览都是“乱码”,自己平时所见的歌词都是lrc格式的文本,这种酷狗专用的krc格式的显然是经过特别处理过的,平时用酷狗听音乐也没仔细看他的歌词有什么不同,只是与天天静听等不同的是可以逐字高亮显示歌词.

于是搜索了下发现有个java版的半成品解密代码,测试了下竟然还是“乱码”,巨坑!于是只有采用最原始的办法,对酷狗的flash播放器进行反编译,发现这段krc解密的ActionScript代码:

  1. public function loaderCompleteHandler(param1:ByteArray) : void{  
  2.  this.newkeyBytes = [64, 71, 97, 119, 94, 50, 116, 71, 81, 54, 49, 45, 206, 210, 110, 105];  
  3.  var result:* = param1;  
  4.  var krcBytes:* = new ByteArray();  
  5.  result.position = 4;  
  6.  result.readBytes(krcBytes);  
  7.  var l:* = krcBytes.length;  
  8.  var i:int;  
  9.  while (i < l) { 
  10.   krcBytes[i] = krcBytes[i] ^ this.newkeyBytes[i % this.newkeyBytes.length];  
  11.   i = (i + 1);  
  12.  } 
  13.  try {  
  14.   krcBytes.uncompress();  
  15.  } catch (error:SecurityError) {  
  16.   errorfun("uncompressError"); 
  17.   return;  
  18.  }  
  19.  krcBytes.position = 0;  
  20.  this.myLyric.dataStr = krcBytes.readUTFBytes(krcBytes.length);  
  21.  this.successfun();  
  22.  return;  

根据这段代码可以很快转换成php解析代码:

  1. $enKey = array(64, 71, 97, 119, 94, 50, 116, 71, 81, 54, 49, 45, 206, 210, 110, 105); 
  2. $krc_content = substr($krc_content,4); 
  3. $len = strlen($krc_content); 
  4. $krc_compress = ''
  5. for ($k = 0; $k < $len$k++){ 
  6.  $krc_compress .= chr(ord($krc_content[$k]) ^ $enKey[$k % 16]); 
  7. $krc_text = gzuncompress($krc_compress); 

上面的$krc_content为krc歌词压缩加密的文本内容,得到了解析后的krc明文文本歌词$krc_text,然后就可以很容易的转换成lrc歌词了,代码如下:

  1. /** 
  2.  * krc歌词解析并转换为lrc歌词 
  3.  * $Name: krc2lrc  2014-4-18  qaulau<qaulau@hotmail.com>$ 
  4.  *  
  5.  * @param string $krc_content 加密的krc歌词内容 
  6.  * @param string $glue   处理后的lrc歌词连接字符,默认为换行符n 
  7.  */ 
  8. function krc2lrc($krc_content,$glue = "n"){ 
  9.     $enKey = array(64, 71, 97, 119, 94, 50, 116, 71, 81, 54, 49, 45, 206, 210, 110, 105); 
  10.  $krc_content = substr($krc_content,4); 
  11.  $len = strlen($krc_content); 
  12.  $krc_compress = ''
  13.  for ($k = 0; $k < $len$k++){ 
  14.   $krc_compress .= chr(ord($krc_content[$k]) ^ $enKey[$k % 16]); 
  15.  } 
  16.  $krc_text = gzuncompress($krc_compress); 
  17.  preg_match_all("/[(ar|ti|offset):(.+)]/",$krc_text,$matches); 
  18.  $lrc_text = implode($glue,$matches[0]).$glue
  19.  preg_match_all("/[(d{0,8}),(d{0,8})](.+)/",$krc_text,$matches); 
  20.  unset($krc_text,$krc_compress,$krc_content,$enKey); 
  21.  if(!emptyempty($matches[1])){ 
  22.   foreach($matches[1] as $k=>$v){ 
  23.    list($seconds$millis) = explode('.'$v / 1000);  
  24.    $lrc_time = date('i:s',1388534400 + $seconds).'.'.substr($millis,0,2); 
  25.    $lrc_cont = preg_replace("/<d{1,8},d{1,8},d{1,8}>/",'',$matches[3][$k]);  //开源软件:phpfensi.com 
  26.    $lrc_text .= "[{$lrc_time}]{$lrc_cont}{$glue}"
  27.   } 
  28.  } 
  29.  return $lrc_text

简单的示例:

  1. $content = file_get_contents('1.krc'); 
  2. echo krc2lrc($content,'<br/>'); 

分享一下,方便日后有类似需要的人查询.



zend