背景:
酷狗音乐歌词文件分为KRC文件和LRC,由于LRC文件只能将歌词显示的精度确定到行,因此需要解压KRC文件,并输入到LRC文件中,由此得到更加精准的能够将歌词显示精确到每一个字的LRC文件!
本章简单介绍一下,如何用Qt调用Zlib库来解压KRC文件。
解码前的KRC文件效果图
解码后的LRC文件效果图
LRC文件说明
以该首歌词的第一句为例:
[26317,2839]<0,657,0>光<657,405,0>是<1062,405,0>谁<1467,411,0>燃<1878,305,0>烛<2183,354,0>照<2537,302,0>亮
中括号表示:[此行开始时刻距0时刻的毫秒数,此行持续的毫秒数]
尖括号表示:<此字开始时刻距此行开始时刻的毫秒数,此字持续的毫秒数,0>
核心代码
void toLrcFile(const QString &krcFileName, const QString &lrcFileName)
{
QFile krcFile(krcFileName);
QFile lrcFile(lrcFileName);
if (!krcFile.open(QIODevice::ReadOnly))
return;
//密码字节数组(解码前)
QByteArray encodeKrcBuffer = krcFile.readAll();
//解码字节数组(解码后)
QByteArray decodeKrcBuffer;
//校验开头4字符
if (encodeKrcBuffer.left(4) == "krc1")
{
//去除文件头标识
encodeKrcBuffer.remove(0, 4);
//xor法解码
const int Keys[] = {64, 71, 97, 119, 94, 50, 116, 71, 81, 54, 49, 45, 206, 210, 110, 105};
for (int i = 0; i < encodeKrcBuffer.size(); i++)
{
decodeKrcBuffer.append((char)(encodeKrcBuffer[i] ^ Keys[i % 16]));
}
}
//注意:如果您想使用该函数来解压缩使用zlib压缩的外部数据,您首先需要在包含数据的字节数组前面加上一个四字节头。
//标头必须包含未压缩数据的预期长度(以字节为单位),表示为无符号、大端、32位整数。
//因此设计了下方添加的四个字节,无论大小端皆可使用
decodeKrcBuffer.insert(0, '1');
decodeKrcBuffer.insert(0, '0');
decodeKrcBuffer.insert(0, '0');
decodeKrcBuffer.insert(0, '1');
//解压文件
QByteArray lrcBuffer = qUncompress(decodeKrcBuffer);
if (lrcFile.open(QIODevice::WriteOnly))
{
lrcFile.write(lrcBuffer);
lrcFile.close();
}
krcFile.close();
}