QRC格式歌词转LRC格式

上一篇post里提到了QQ音乐的QRC歌词,不过其他播放器并不能识别出这个格式,于是只好自己写个转换器了。

稍微写了一下,感觉效果还不错~~如下图

屏幕快照 2015-03-24 下午1.23.31

代码在此~

#import <Foundation/Foundation.h>
#import <string>
#import <iostream>
#import <fstream>
#import <regex.h>

using namespace std;

/*!
 *  @brief      把微秒时间转为LRC中的时间
 *
 *  @discussion 并未考虑超过99:59.99的时间
 *
 *  @return     [dd:dd.dd]
 */
 
const char * microseconds_to_LRC_time(long long microsecond)
{
    double seconds = microsecond / 1000.0;
    int min = seconds / 60;
    double sec = seconds - 60 * min;
    return [NSString stringWithFormat:@"%02d:%05.2lf",min,sec].UTF8String;
}

@interface QRC : NSObject

/*!
 *  @brief  解析QRC到LRC
 *
 *  @param QRCPath QRC文件路径
 *  @param error   出错时返回错误码和原因
 */

+ (void)ParserQRCDoc:(NSString *)QRCPath Error:(NSError **)error;

@end

@implementation QRC

+ (void)ParserQRCDoc:(NSString *)QRCPath
               Error:(NSError **)error
{
    ifstream QRC_file(QRCPath.UTF8String);
    if(!QRC_file)
    {
        *error = [[NSError alloc] initWithDomain:@"com.[data deleted].QRC" code:-1 userInfo:@{@"Error":@"No such file"}];
        return;
    }

    string str;
    int cflags = REG_EXTENDED;
    regex_t reg;
    const char * pattern = "^\[([0-9]+)";
    // 匹配以'['开头, 并且后面跟着数字的就行了
    // 因为是转为LRC, 故提取出每句开始的时间就行

    int z = regcomp(&reg, pattern, cflags);
    if (z != 0)
    {
        char ebuf[128];
        regerror(z, &reg, ebuf, sizeof(ebuf));
        *error = [[NSError alloc] initWithDomain:@"com.[data deleted].QRC" code:-2 userInfo:@{@"Error":[NSString stringWithFormat:@"%s",ebuf]}];
        regfree(&reg);
        return;
    }

    regmatch_t pm[10];
    const size_t nmatch = 10;
    while(getline(QRC_file, str))
    {
        z = regexec(&reg, str.c_str(), nmatch, pm, 0);
        if (z == REG_NOMATCH)
        {
            continue;
        }
        else if (z != 0)
        {
            char ebuf[128];
            regerror(z, &reg, ebuf, sizeof(ebuf));
            *error = [[NSError alloc] initWithDomain:@"com.[data deleted].QRC" code:-3 userInfo:@{@"Error":[NSString stringWithFormat:@"%s",ebuf]}];
            regfree(&reg);
            return;
        }
        else
        {
            const char * line = str.c_str();
            for (int x = 1; x < nmatch && pm[x].rm_so != -1; ++ x)
            {
                char *mstr = strndup(line + pm[x].rm_so, pm[x].rm_eo - pm[x].rm_so);
                long long microseconds = atoll(mstr);
                free(mstr);
                printf("[%s]",microseconds_to_LRC_time(microseconds));
            }
            BOOL print = YES;
            for(int i = 0; i < strlen(line); i++)
            {
                if (line[i] == '[' || line[i] == '(')
                {
                    print = NO;
                    continue;
                }
                else if (line[i] == ']' || line[i] == ')')
                {
                    print = YES;
                    continue;
                }
                else
                {
                    if (print) printf("%c",line[i]);
                }
            }
            printf("n");
        }
        fflush(stdout);
    }
}
 
@end

int main(int argc, const char * argv[])
{
    @autoreleasepool

    {
        for (int i = 1; i < argc; i++) {
            NSError *error;
            [QRC ParserQRCDoc:[NSString stringWithUTF8String:argv[i]] Error:&error];
        }
    }
    return 0;
}
 

One thought on “QRC格式歌词转LRC格式”

Leave a Reply

Your email address will not be published. Required fields are marked *

4 × two =