ios开发学习--歌词处理--解析lrc文件
我觉得要想解析lrc 首先大家应该了解一下lrc文件的结构,大家可以去看一下**百科 我这里粗略的写一下;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // 2 // LyricsAnalysis.h 3 // 08-10-MusicPlayer 4 // 5 // Created by Ibokan on 15/8/21. 6 // Copyright (c) 2015年 Crazy凡. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 11 @interface LyricsAnalysis : NSObject 12 @property (nonatomic,strong)NSString *ar;//演唱 13 @property (nonatomic,strong)NSString *ti;//歌曲名 14 @property (nonatomic,strong)NSString *al;//专辑名 15 @property (nonatomic,strong)NSString *by;//歌词作者 16 @property (nonatomic,strong)NSString *t_time;//歌曲总时长 17 @property (nonatomic,strong)NSMutableArray *lrcArrayTime;//时间数组 18 @property (nonatomic,strong)NSMutableArray *lrcArrayStr;//歌词数组 19 20 - (instancetype)init; 21 - (instancetype)initWithFileName:(NSString *)name ofType:(NSString *)type; 22 - (instancetype)initWithFilePath:(NSString *)filePath; 23 - (void)lyricsAnalysisWithFileName:(NSString *)name ofType:(NSString *)type; 24 - (void)lyricsAnalysisWithFilePath:(NSString *)filePath; 25 @end
以上是.h头文件源码
以下是.m源文件源码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // 2 // LyricsAnalysis.m 3 // 08-10-MusicPlayer 4 // 5 // Created by Ibokan on 15/8/21. 6 // Copyright (c) 2015年 Crazy凡. All rights reserved. 7 // 8 9 #import "LyricsAnalysis.h" 10 11 12 @interface LyricsAnalysis () 13 @property double offset;//歌词时间调整变量 14 @end 15 @implementation LyricsAnalysis 16 17 //初始化 18 - (instancetype)init 19 { 20 self = [super init]; 21 if (self) { 22 self.ar = [[NSString alloc]init]; 23 self.ti = [[NSString alloc]init]; 24 self.by = [[NSString alloc]init]; 25 self.al = [[NSString alloc]init]; 26 self.offset = 0; 27 self.t_time = [[NSString alloc]init];//歌曲总时长单位(s) 28 self.lrcArrayStr = [[NSMutableArray alloc]init];//歌词数组初始化 29 self.lrcArrayTime = [[NSMutableArray alloc]init];//时间数组初始化 30 } 31 return self; 32 } 33 //带文件名的初始化 34 - (instancetype)initWithFileName:(NSString *)name ofType:(NSString *)type 35 { 36 self = [self init]; 37 [self lyricsAnalysisWithFileName:name ofType:type]; 38 return self; 39 } 40 //带文件路径的初始化 41 - (instancetype)initWithFilePath:(NSString *)filePath 42 { 43 self = [self init]; 44 [self lyricsAnalysisWithFilePath:filePath]; 45 return self; 46 } 47 //处理文件名歌词 48 - (void)lyricsAnalysisWithFileName:(NSString *)name ofType:(NSString *)type 49 { 50 [self lyricsAnalysisWithFilePath:[[NSBundle mainBundle] pathForResource:name ofType:type]];//构建filepath 51 } 52 //处理文件路径 53 - (void)lyricsAnalysisWithFilePath:(NSString *)filePath 54 { 55 NSString *strlrc = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; 56 NSMutableArray * arraylrc = [[NSMutableArray alloc] initWithArray:[strlrc componentsSeparatedByString:@"\n"]]; 57 NSArray *StrToInt = [NSArray arrayWithObjects:@"ar",@"ti",@"al",@"by",@"of",@"t_",nil];//NSString switch 配置 58 BOOL flag = YES; 59 while(flag) 60 { 61 NSString *temp = arraylrc[0]; 62 switch ((int)[StrToInt indexOfObject:[temp substringWithRange:NSMakeRange(1, 2)]]) 63 { 64 case 0:self.ar = [[temp substringFromIndex:4]stringByReplacingOccurrencesOfString:@"]" withString:@"\0"];break; 65 case 1:self.ti = [[temp substringFromIndex:4]stringByReplacingOccurrencesOfString:@"]" withString:@"\0"];break; 66 case 2:self.al = [[temp substringFromIndex:4]stringByReplacingOccurrencesOfString:@"]" withString:@"\0"];break; 67 case 3:self.by = [[temp substringFromIndex:4]stringByReplacingOccurrencesOfString:@"]" withString:@"\0"];break; 68 case 4:self.offset = [[[temp substringFromIndex:8] stringByReplacingOccurrencesOfString:@"]" withString:@"\0"] doubleValue];break; 69 case 5:self.t_time = [[temp substringFromIndex:9] stringByReplacingOccurrencesOfString:@")]" withString:@"\0"];break; 70 default:flag = NO; break; 71 } 72 flag?[arraylrc removeObjectAtIndex:0]:nil;//判断是否需要移除已经被读取的信息(是歌词则不移除) 73 }// lrc时间的格式分3种:[mm:ss.SS]、[mm:ss:SS]、[mm:ss];第一种是标准形式,后面两种存在但是不标准;先把时间字符串按照“:”拆分,生成{mm ss.SS}、{mm ss SS}、{mm ss};对于1、3,直接取doubleValue即可;注意分钟*60;对于第二种情况需要单独处理SS(毫秒)位; 74 for (NSString *str in arraylrc) { 75 NSArray * ArrayTemp = [str componentsSeparatedByString:@"]"];//分割每一句歌词 76 for(int j = 0 ; j < ArrayTemp.count -1 ;j++) 77 { 78 NSArray * Arraytime = [[ArrayTemp[j] substringFromIndex:1] componentsSeparatedByString:@":"];//分割时间字符串 79 double timedouble = [Arraytime[0] doubleValue]*60.0 + [Arraytime[1] doubleValue];//处理分钟和秒 80 timedouble += Arraytime.count > 2 ? [[[NSString alloc]initWithFormat:@"0.%@",Arraytime[2]] doubleValue]:0;//处理毫秒位 81 timedouble += (self.offset / 1000.0);//时间调整 82 timedouble = timedouble > 0 ? timedouble : 0;//避免因为时间调整导致的时间<0 83 int i = 0; 84 while (i < self.lrcArrayTime.count && [self.lrcArrayTime[i++] doubleValue] < timedouble);//查找当前歌词的插入位置 85 [self.lrcArrayTime insertObject:[[NSString alloc]initWithFormat:@"%lf",timedouble] atIndex:i];//插入时间数组 86 [self.lrcArrayStr insertObject:ArrayTemp[ArrayTemp.count-1] atIndex:i];//插入歌词数组 87 } 88 } 89 } 90 @end
知识点:
1、[[NSBundle mainBundle] pathForResource:name ofType:type]]
//路径构建,传进的name 和 type 参数需要做 路径构建
switch ((int)[StrToInt indexOfObject:[temp substringWithRange:NSMakeRange(1, 2)]])
substringFromIndex//截取
stringByReplacingOccurrencesOfString:@"]" withString:@"\0"//替换
NSMutableArray * arraylrc = [[NSMutableArray alloc] initWithArray:[strlrc componentsSeparatedByString:@"\n"]];//分割
大量的字符串 处理函数 大家自多看吧,毕竟很常用也很重要
4、三元式的读取
条件?a:b; 满足条件返回a 不满足条件返回b 如果a b 是表达式 则会自动执行表达式
新增部分:
代码的第58行,替换成:BOOL flag = arraylrc.count > 0 ? YES : NO; //防止错误路径或者歌词文件为空导致的概率性崩溃;
代码的第89行,插入:self.lrcArrayTime.count == 0 ? [self.lrcArrayTime insertObject:@"0" atIndex:0],[self.lrcArrayStr insertObject:@"未找到歌词!" atIndex:0]:nil; //又是一个三元式,没办法喜欢他, 和上面作用一样,不一样的是插入了一句提示语,找不到歌词。
此处编辑于:15-09-23 12时
注意:以上部分未在下面的源文件中更新
代码中的细节,基本都做了注释,不懂得可以留言,我会尽可能的答复;