歌词解析

#import <Foundation/Foundation.h>

@interface JYLrcItem : NSObject

@property (nonatomic) float time;
@property (nonatomic) NSString *lrc;

- (BOOL)isBiggerTimeThan:(JYLrcItem *)aItem;

@end
---------------------------------------------------------------------------

#import "JYLrcItem.h"

@implementation JYLrcItem

- (BOOL)isBiggerTimeThan:(JYLrcItem *)aItem
{
    return _time > aItem.time;
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"%.2f %@", _time,_lrc];
}

@end

---------------------------------------------------------------------------

#import <Foundation/Foundation.h>

@interface JYLrcParser : NSObject

// 歌词作者 [ar:歌词作者]
@property NSString *author;
// 歌词所在的唱片集 [al:这首歌所在的唱片集]
@property NSString *albume;
// 本lrc编辑作者 [by:本LRC文件的创建者]
@property NSString *byEditor;
// 歌曲标题 [ti:歌词(歌曲)的标题]
@property NSString *title;
// 歌曲版本 [ve:程序的版本]
@property NSString *version;

//把解析的歌词模型 对象地址放入数组中
//存放的是JYLrcItem类的对象地址
@property NSMutableArray *allLrcItems;

// 初始化这个lrc
- (id) initWithFile:(NSString *)file;
// 通过second取得当前的歌词
- (NSString *) getLrcByTime:(float)second;

//显示歌曲信息
- (void)showSongInfo;

- (void)showAllInfo;

@end

-----------------------------------------------------------------------------------

#import "JYLrcParser.h"
#import "JYLrcItem.h"

@implementation JYLrcParser

- (id)initWithFile:(NSString *)file
{
    if (self = [super init]) {
        _allLrcItems = [[NSMutableArray alloc] init];
        //调用方法解析歌词文件
        [self parseLrcWithFile:file];
    }
    return self;
}

- (void)parseLrcWithFile:(NSString *)file
{
    //1、读取歌词文件
    NSString *lrc = [NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil];
    //2、按照‘\n‘进行切割
    NSArray *ary = [lrc componentsSeparatedByString:@"\n"];
    /*
     [ti:蓝莲花]
     [ar:许巍]
     [al:时光-漫步]
     [by:fanver]
     [offset:500]
     [00:00.20]蓝莲花
     
     [00:20.81]
     */
    //3、遍历数组,解析每行信息
    for (NSString *str in ary) {
        //过滤空行(哪个二哥随意敲回车)
        if ([str isEqualToString:@""]) {
            continue;
        }
        
        //获取第一个字符
        unichar ch = [str characterAtIndex:1];
        //判读该行是否为歌词信息
        if (ch>=‘0‘ && ch<=‘9‘) {
            //4-1、是歌词信息
            [self parseLrcWithTimeString:str];
        } else {
            //4-2、是歌曲信息
            [self parseLrcWithSongInformation:str];
        }
    }
    //5、将歌词按照时间进行排序
    [_allLrcItems sortUsingSelector:@selector(isBiggerTimeThan:)];
}

//4-1、歌词信息解析
- (void)parseLrcWithTimeString:(NSString *)timeString
{
    /*
     [02:11.27][01:50.22][00:21.95]穿过幽暗地岁月
     */
    //按照‘]‘进行切割
    NSArray *ary = [timeString componentsSeparatedByString:@"]"];
    
    //[00:20.81、@""
    //过滤没有歌词的时间行
    if ([ary.lastObject isEqualToString:@""]) {
        return;
    }
    /*
     [02:11.27
     [01:50.22
     [00:21.95
     穿过幽暗地岁月
     */
    for (int i=0; i<ary.count-1; i++) {
        //[02:11.27
        int min = [[ary[i] substringWithRange:NSMakeRange(1, 2)] intValue];
        float sec = [[ary[i] substringFromIndex:4] floatValue];
        float time = min*60 + sec;
        //创建歌词对象,保存信息
        JYLrcItem *item = [[JYLrcItem alloc] init];
        item.time = time;
        item.lrc = [ary lastObject];
        //将歌词对象添加到_allLrcItems
        [_allLrcItems addObject:item];
    }
}

//4-2、歌曲信息解析
- (void)parseLrcWithSongInformation:(NSString *)info
{
    /*
     [ti:蓝莲花]
     [ar:许巍]
     [al:时光-漫步]
     [by:fanver]
     */
    NSString *item = [info substringWithRange:NSMakeRange(1, 2)];
    NSString *content = [info substringWithRange:NSMakeRange(4, info.length-5)];
    if ([item isEqualToString:@"ti"]) {
        _title = content;
    } else if ([item isEqualToString:@"al"]) {
        _albume = content;
    } else if ([item isEqualToString:@"ar"]) {
        _author = content;
    } else if ([item isEqualToString:@"by"]) {
        _byEditor = content;
    }
}

- (void)showAllInfo
{
    for (JYLrcItem *item in _allLrcItems) {
        printf("%s\n", [[item description] UTF8String]);
    }
}

- (NSString *)getLrcByTime:(float)second
{
    /*
     1
     3\5\8\9\11\15...\100
     */
#if 0
    for (int i=0; i<_allLrcItems.count; i++) {
        if ([_allLrcItems[i] time] > second) {
            return [_allLrcItems[i-(i!=0)] lrc];
        }
    }
    return [[_allLrcItems lastObject] lrc];
#else
    int index = (int)_allLrcItems.count - 1;
    for (int i=0; i<_allLrcItems.count; i++) {
        if ([_allLrcItems[i] time] > second) {
            index = i - (i!=0);
            break;
        }
    }
    return [_allLrcItems[index] lrc];
#endif
}

- (void)showSongInfo
{
    if (_title) {
        printf("ti:%s\n", [_title UTF8String]);
    }
    if (_author) {
        printf("ar:%s\n", [_author UTF8String]);
    }
    if (_albume) {
        printf("al:%s\n", [_albume UTF8String]);
    }
    if (_byEditor) {
        printf("by:%s\n", [_byEditor UTF8String]);
    }
}

@end

--------------------------------------------------------------------------------------------

#import <Foundation/Foundation.h>
#import "JYLrcParser.h"

#define PATH @"/Users/qianfeng001/Desktop/wenzhe/RAIN/十五天/day15/歌词文件/蓝莲花.lrc"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        JYLrcParser *parser = [[JYLrcParser alloc] initWithFile:PATH];
        //[parser showAllInfo];
        //NSString *str = [parser getLrcByTime:10];
        //printf("%s\n", [str UTF8String]);
        
        int i = 0;
        NSString *last = nil;
        while (i < 100) {
            NSString *str = [parser getLrcByTime:i];
            if (last != str) {
                last = str;
                system("clear");
                [parser showSongInfo];
                printf("%s\n", [str UTF8String]);
            }
            i++;
            sleep(1);
        }
        
    }
    return 0;
}

时间: 2024-10-04 15:35:45

歌词解析的相关文章

浅谈动感歌词-歌词解析篇

1引言 要解析动感歌词文件,首先就要清楚动感歌词的文件内容,当然歌词的文件内容,我们已经在分析篇的文章里面介绍过了,这里将不再做详细的介绍,当我们可以把歌词成功解析出来后,再结合歌词生成篇,一个简单的歌词格式转换工具也就出来了. 2歌词解析 歌词解析,其实就是把文件里面的标签内容.歌词时间和歌词内容解析出来,当然,为了后期拓展其它的动感歌词格式,我们这里要好好设计一番. 2.1实体类 2.1.1歌词读取器 主要用来约束动感歌词读取器要实现的方法,可用于拓展实现其它的动感歌词格式. 2.1.2歌词

歌词解析总结

前言 目前常用歌词文件有3种 LRC QRC KRC 其中LRC是最常用的歌词文件,千千静听.酷我音乐都是用LRC做歌词解析的.它的格式非常简单.解析容易但是,歌词的精度只能控制到一行. QRC是QQ音乐的歌词文件.其精度可以控制到每个字.它是无加密的. KRC是酷狗播放器专用歌词文件,它通过了压缩处理并且加密.它也能精确控制到每一个字,同时还绑定了歌曲的信息,酷狗播放器打开时能够自动下载歌曲 LRC歌词解析 开头的歌曲信息可能会有2种展现形式 [00:02.37]三十而立 [00:03.12]

OC3_歌词解析

// // LrcManager.h // OC3_歌词解析 // // Created by zhangxueming on 15/6/15. // Copyright (c) 2015年 zhangxueming. All rights reserved. // #import <Foundation/Foundation.h> #import "LrcItem.h" #define FilePath @"/Users/zhangxueming/Desktop

小喵iOS开发成长记:歌词解析

(海豹暹罗镇楼) 研究因由 小喵最近开始研究音乐播放器,实现了一些简单地播放功能后,想添加歌词,但是发现不知道如何着手. 小喵:“猿哥,猿哥,碰到大难题了,播放器的歌词弄不出来了”. 程序猿:“这个啊,其实挺简单的”. 小喵:“但是没有一点灵感呀”. 程序猿:“你可以打印下歌词,看下歌词里面的一些规律”. 小喵:“你是说这样的吗? [00:08.460]I'm hurting baby\n[00:10.450]I'm broken down \n都是以[]开始,\n这样结束吗?” 程序猿:“是的

Objective-C歌词解析

#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { FILE* fp1;//定义文件指针用于读文件 char* fp2;//用来判断是否歌词读完 char s[80];//暂存歌词 long int time2=0; long int time=0;//用来计算时间,精度为秒,不够完善,望高人指点 int a=1;//起判断作用 fp1=fopen("/Users/qingyun/De

OC lrc歌词解析

#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) {     FILE* fp1;//定义文件指针用于读文件     char* fp2;//用来判断是否歌词读完     char s[80];//暂存歌词     long int time2=0;     long int time=0;//用来计算时间,精度为秒,不够完善,望高人指点     int a=1;//起判断作用     fp1=f

ios歌词解析

好不容易吧歌词解出来了,分享给大家. 首先我定义了一个方法,把歌词的名字传进去,返回一个字典,key是以":"分割的时间戳,值是当前行的歌词. 1 -(NSMutableDictionary*)musicLrc:(NSString*)musicName 2 { 3 4 // 初始化一个字典 5 NSMutableDictionary *musicLrcDictionary=[[NSMutableDictionary alloc]initWithCapacity:20]; 6 // 加载

酷狗.Krc加密歌词解析

1 function KrcToLrc(filename: string): string; 2 function ZDecompressStr2(const S: TBytes): UTF8String; 3 var 4 BIn, BOut: TBytes; 5 begin 6 BIn := S; 7 ZDecompress(BIn, BOut); 8 Result := TEncoding.UTF8.GetString(BOut); 9 end; 10 11 const 12 miarry:

看看如何用C语言解析LRC格式的歌词(上)

嗯,本该昨晚写的,结果因为系统出了点问题,所以便拖到了今天早上.好了,不废话了. 经常听歌的,必然都见过歌词吧.当然,我们这里要说的歌词格式是以LRC为后缀的歌词.此外,还有QRC,KRC格式的歌词.但相对来说,LRC格式歌词更为常见.我们先来看看LRC格式的歌词究竟长什么样: 好了,我们该怎么解读这种格式的歌词呢?推荐看百度百科对它的介绍,在此就不废话了. 相信写过音乐播放的或者想要写音乐播放器的都会涉及到歌词文件的解析吧.自然,使用高级语言可能更为方便一些.比如,我们可以用正则匹配的方式获得