iOS小技能:合并mp3格式的文件

537 阅读2分钟

这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战

引言

应用场景:收款播报类app将固定音频文件进行组合语音播报

I 使用数据流的形式合并mp3

  1. 读取aps中的播报数据,将Bundle中音频文件进行合并(如"您收到.mp3"+"1.mp3"+"元.mp3"),输出到指定目录。
2021-11-15 15:24:52.317068+0800 KNVoiceBroadcast[15798:1988826] 合成mp3文件成功/private/var/mobile/Containers/Shared/AppGroup/1F8A9BCA-5B38-4BB9-B1-EAA7B00AEA7A/Library/Sounds/1636961092.310608.mp3

  1. 修改本次推送声音标识sound,指定合并后的音频文件播报。

1.1 读取aps中的播报数据

将Bundle中音频文件进行合并(如"您收到.mp3"+"1.mp3"+"元.mp3"),输出到指定目录。

+ (NSString*) makeMp3FromExt:(double)amount{
    NSString *amountString = [self stringFromNumber:amount] ;//  将金额转换为对应的文字
    
    NSLog(@"KNApnsHelper%@: amountString->%@", NSStringFromClass([self class]), amountString);
    
    // 分解成mp3数组
    NSMutableArray *subAudioFiles = [[NSMutableArray alloc] init];
    [subAudioFiles addObject:@"tts_pre.mp3"] ;
    
    for (NSInteger i = 0, count = amountString.length; i < count; i++) {
        NSString *subString = [amountString substringWithRange:NSMakeRange(i, 1)] ;
        NSString *fileName = [self audioFileWithString:subString];
        
        if (!fileName) {
            
            [subAudioFiles removeAllObjects];
            [subAudioFiles addObject:@"tts_default.mp3"];
            
        } else {
            [subAudioFiles addObject:fileName];
        }
    }
    [subAudioFiles addObject:@"tts_yuan.mp3"];

    //    let path = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: GroupName)!.absoluteString.replacingOccurrences(of: "file://", with: "") + "Library/Sounds/"

    
    NSURL *groupURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group...."];
    
    NSString *groupPath = [groupURL path];
    
    groupPath = [groupPath stringByAppendingPathComponent:@"Library/Sounds"];
        
    
    
    return [self mergeVoice:groupPath subAudioFiles:subAudioFiles ];
    
}

将金额转换为对应的文字

+ (NSString *)stringFromNumber:(double)number {
    
    NSNumberFormatter *numFormatter = [[NSNumberFormatter alloc] init];
    numFormatter.numberStyle = NSNumberFormatterSpellOutStyle;
    NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_Hans"];
    numFormatter.locale = locale;
    
    NSString *numStr = [numFormatter stringFromNumber:[NSNumber numberWithDouble:number]];
    
    return numStr;
}


1.2 合并mp3

使用数据流的形式把MP3文件转成NSData,然后再进行拼合。

//
/**
 
 使用的AVAssetExportSession只支持合成m4a文件
 
 所以这里使用数据流的形式把MP3文件转成NSData,然后再进行拼合。

 */
+ (NSString*) mergeVoice:(NSString*)groupPath  subAudioFiles:(NSMutableArray*)subAudioFiles{
    
//    todo// clearFiles// NSLog("删除过期mp3失败")
    NSMutableData *sounds = [NSMutableData alloc];

    //合并音频

    for (NSString *obj  in subAudioFiles) {
        
        
        NSString *mp3Path1 = [[NSBundle mainBundle] pathForResource:obj ofType:nil];
        
        NSData *sound1Data = [[NSData alloc] initWithContentsOfFile: mp3Path1];
        
        NSLog(@"mp3Path1%@",mp3Path1);
        

        
        [sounds appendData:sound1Data];
            

        
    }
        
    NSString* fileName = [NSString stringWithFormat:@"%f.mp3",NSDate.date.timeIntervalSince1970];
    
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    if (![fileManager fileExistsAtPath:groupPath]) {
        
        [fileManager createDirectoryAtPath:groupPath withIntermediateDirectories:NO attributes:nil error:nil];
        
        
    }
        NSString* fileUrl =  [groupPath stringByAppendingPathComponent:fileName];

    
    //    //保存合成音频到本地: 创建Sounds文件
    
  BOOL isSucceeds  = [sounds writeToFile:fileUrl atomically:YES];
    
       [sounds writeToFile:[NSString stringWithFormat:@"/Users/mac/Desktop/%@",fileName] atomically:YES];///Users/mac/Desktop
    ///
    

    if(isSucceeds){
        NSLog(@"合成mp3文件成功%@",fileUrl);

        return fileName;//
        
    }else{
        
        NSLog(@"合成mp3文件失败%@",fileUrl);
        

        
        return nil;

    }
        // 保存网络URL到本地
    //             NSURL *saveURL = [NSURL fileURLWithPath:savePath];
    //                 AVURLAsset *audioAsset=[AVURLAsset URLAssetWithURL:saveURL options:nil];

}