歌詞處理-時間、歌詞截取 - (Obj-C)

歌詞.lrc文件實際存放的就是二進制的字符串
歌詞.lrc文件的解析實際就是二進制字符串解析

內(nèi)部格式大致為:

[03:02.00][01:05.00]這晚夜沒有吻別

主要由兩部分組成: 時間部分歌詞部分
兩個時間戳代表同一句歌詞會在兩個時間下顯示

歌詞解析:

1.先抽取一個歌詞模型類(存放每一句歌詞)
2.聲明屬性:時間(每句的起始時間) 和 歌詞(每一句)
3.創(chuàng)建一個工具類,專門用作解析歌詞,供外界直接調(diào)用

3.1 讀取歌詞字符串
3.2 分隔字符串為一個存放每一句歌詞的數(shù)組(包含時間和歌詞)
3.3 遍歷存放歌詞的數(shù)組,根據(jù)時間格式使用正則表達式過濾字符串,得到一個存放NSTextCheckingResult對象的數(shù)組
3.4 截取時間和歌詞,遍歷存放歌詞(含時間和歌詞)的數(shù)組:
      3.4.1 遍歷存放NSTextCheckingResult對象的數(shù)組,通過range屬性獲得時間(因為每句歌詞可能含多個時間戳)
      3.4.2 通過range屬性,截取歌詞
3.5 給歌詞模型屬性賦值
3.6 將得到的歌詞模型對象添加到可變數(shù)組
3.7 將存放歌詞模型對象的數(shù)組重新排序
  • 時間截取:
1. 每句歌詞可能含多個時間戳,所以在遍歷歌詞數(shù)組時,使用正則表達式過濾歌詞,會得到一個存放NSTextCheckingResult對象的數(shù)組,這里需要使用到NSTextCheckingResult的range屬性,再次遍歷存放NSTextCheckingResult對象的數(shù)組,通過range屬性截取時間字符串
2. 截取的是時間字符串,為了便于使用,這里將字符串轉(zhuǎn)為NSTimeInterval格式再進行存儲(歌詞模型中也是直接使用NSTimeInterval聲明的)
  • 歌詞截取:
參考_歌詞內(nèi)部格式示例_,一句歌詞可能會有多個時間戳,根據(jù)正則表達式獲取到存放時間的數(shù)組,取出數(shù)組中最后一個元素,也就是每句歌詞中最后的一個時間戳:
用最后的時間戳的local + length才是全部時間部分的長度,也就得到了后面歌詞的索引
  • 示例代碼:

歌詞模型類(只是聲明了屬性,并未提供方法):

#import <Foundation/Foundation.h>

@interface JSLyricModel : NSObject

// 該句歌詞的初始時間
@property (nonatomic,assign) NSTimeInterval initialTime;
// 該句歌詞
@property (nonatomic,copy) NSString *content;


@end

歌詞解析工具類:

#import "JSLyricManager.h"
#import "NSDateFormatter+Shared.h"
#import "JSLyricModel.h"

@implementation JSLyricManager

+ (NSArray<JSLyricModel *> *)parserLyricWithFileName:(NSString *)fileName{
    
    // 取出歌詞字符串
    NSString *filePath = [[NSBundle mainBundle]pathForResource:fileName ofType:nil];
    NSString *lyricStr = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
    
    // 分隔字符串
    NSArray *lyricArr = [lyricStr componentsSeparatedByString:@"\n"];
    
    
    /*      正則表達式過濾字符串:
     [00:19.00]曲:河合奈保子 詞:向雪懷
     [02:19.00][00:23.00]仍然倚在失眠夜望天邊星宿
     */
    NSString *regularExpressionString = @"\\[[0-9]{2}:[0-9]{2}.[0-9]{2}\\]";
    NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:regularExpressionString options:0 error:nil];
    
    // 存放歌詞對象的臨時可變數(shù)組
    NSMutableArray *tempMarr = [NSMutableArray array];
    
    //遍歷歌詞數(shù)組,取出每一句歌詞
    for (NSString *element in lyricArr) {
        
        // 正則表達式遍歷
        NSArray<NSTextCheckingResult *> *textCheckingResult = [regularExpression matchesInString:element options:0 range:NSMakeRange(0, element.length)];
        
        // 2.截取歌詞內(nèi)容
        NSTextCheckingResult *lastTimeString = textCheckingResult.lastObject;// 取出得到數(shù)組中的最后一個時間元素,用來獲取range
        
        // 截取歌詞 (一句歌詞可能會有多個時間戳,取到最后一個時間戳,用自己的local + length才是全部時間部分的長度,也就得到了后面歌詞的索引)
        NSString *lyricContent = [element substringFromIndex:lastTimeString.range.length + lastTimeString.range.location];
        
        // 同一句歌詞可能多處顯示,所以返回值是一個數(shù)組,遍歷取出每一個起始時間字符串
        for (NSTextCheckingResult *result in textCheckingResult) {

            // 1. 截取時間字符串
            NSString *lyricSubString = [element substringWithRange:NSMakeRange(result.range.location, result.range.length)];
            
            // 截取玩后設(shè)置每一句歌詞的起始時間
            NSTimeInterval currentLyricInitialTime = [self timeIntervalWithTimeString:lyricSubString];
            
            // 創(chuàng)建歌詞模型
            JSLyricModel *model = [[JSLyricModel alloc]init];
            // 模型賦值
            model.initialTime = currentLyricInitialTime;// 給歌詞模型的歌詞初試時間賦值
            model.content = lyricContent;               // 給歌詞模型的歌詞內(nèi)容賦值
            
            // 添加到臨時可變數(shù)組
            [tempMarr addObject:model];
            
        }
        
    }
    
    // 歌詞起始時間排序
    NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"initialTime" ascending:YES];
    NSArray *lyricModelArr = [tempMarr sortedArrayUsingDescriptors:@[descriptor]];
    
    
    // 進行解析
    return lyricModelArr;
}

// 將時間字符串轉(zhuǎn)換為NSTimerInterval類型,方便外面直接判斷
+ (NSTimeInterval)timeIntervalWithTimeString:(NSString *)timeString{
    
    // 時間字符串 --> 日期對象 NSDate  --> 計算對應(yīng)的時間間隔
    NSDateFormatter *dateFormatter = [NSDateFormatter sharedManager];
    // 設(shè)置格式
    dateFormatter.dateFormat = @"[mm:ss.SS]";
    // 創(chuàng)建初始時間對象 用來計算時間間隔
    NSDate *initialDate = [dateFormatter dateFromString:@"[00:00.00]"];
    // 將字符串轉(zhuǎn)換為NSDate
    NSDate *targetDate = [dateFormatter dateFromString:timeString];
    
    // 計算時間間隔
    return [targetDate timeIntervalSinceDate:initialDate];
    
}


@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,706評論 18 399
  • 前言 要解析 lrc 格式的歌詞, 首先需要知道什么是 lrc 歌詞, 還需要知道 lrc 歌詞的規(guī)范. 在這里先...
    李國安閱讀 5,674評論 8 14
  • 從三月份找實習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,803評論 11 349
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,568評論 19 139
  • Sorry Sorry 鎖骨旁邊 藍色英文紋身 戴著口罩的你 高冷的讓我窒息 然而你的眼神 那么迷人 我只敢用余光...
    停停不能停閱讀 260評論 0 2

友情鏈接更多精彩內(nèi)容