iOS关于MP3音频文件合并和MOV音频文件合并

来源:互联网 发布:海尔电视软件删除 编辑:程序博客网 时间:2024/05/13 07:50

最近项目中,需要将音频文件进行合并,在开发中,遇到了一些坑,在这里将这些问题整理记录一下。

  • 将若干.mp3文件合并,可以MP3文件转成NSData,然后再进行拼接处理,这样就可以合成一段完整的MP3文件。
#import "ViewController.h"#define kCachesPath [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]#define MUSIC                    [kCachesPath stringByAppendingPathComponent:@"Music"]#define COMBINPATH         [MUSIC stringByAppendingPathComponent:@"combine.mp3"]@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    NSFileManager *fileManager = [NSFileManager defaultManager];    if (![fileManager fileExistsAtPath:MUSIC]) {        [fileManager createDirectoryAtPath:MUSIC withIntermediateDirectories:YES attributes:nil error:nil];    }   //音频文件路径    NSString *path1 = [[NSBundle mainBundle] pathForResource:@"1" ofType:@"mp3"];    NSString *path2 = [[NSBundle mainBundle] pathForResource:@"2" ofType:@"mp3"];    NSString *path3 = [[NSBundle mainBundle] pathForResource:@"3" ofType:@"mp3"];    //音频数据    NSData *sound1Data = [[NSData alloc] initWithContentsOfFile: path1];    NSData *sound2Data = [[NSData alloc] initWithContentsOfFile: path2];    NSData *sound3Data = [[NSData alloc] initWithContentsOfFile: path3];    //合并音频    NSMutableData *soundData = [NSMutableData alloc];    [soundData appendData:sound1Data];    [soundData appendData:sound2Data];    [soundData appendData:sound3Data];    NSLog(@"%lu",(unsigned long)soundData.length);    //保存音频    [soundData writeToFile:COMBINPATH atomically:YES];    NSLog(@"%@",COMBINPATH);}@end
  • 将若干.mov文件合并,将MOV文件转成NSData,然后再进行拼接处理,最后生成的文件是有问题的,文件的大小只有最开始的那一段。
#import "ViewController.h"#define kCachesPath [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]#define MUSIC                    [kCachesPath stringByAppendingPathComponent:@"Music"]#define COMBINPATH         [MUSIC stringByAppendingPathComponent:@"combine.mov"]@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    NSFileManager *fileManager = [NSFileManager defaultManager];    if (![fileManager fileExistsAtPath:MUSIC]) {        [fileManager createDirectoryAtPath:MUSIC withIntermediateDirectories:YES attributes:nil error:nil];    }    //mov文件路径    NSString *path4 = [[NSBundle mainBundle] pathForResource:@"4" ofType:@"mov"];    NSString *path5 = [[NSBundle mainBundle] pathForResource:@"5" ofType:@"mov"];    NSString *path6 = [[NSBundle mainBundle] pathForResource:@"6" ofType:@"mov"];    //mov数据    NSData *sound4Data = [[NSData alloc] initWithContentsOfFile: path4];    NSData *sound5Data = [[NSData alloc] initWithContentsOfFile: path5];    NSData *sound6Data = [[NSData alloc] initWithContentsOfFile: path6];    //合并    NSMutableData *soundData = [NSMutableData alloc];    [soundData appendData:sound4Data];    [soundData appendData:sound5Data];    [soundData appendData:sound6Data];    NSLog(@"%lu",(unsigned long)soundData.length); // 这时候的数据长度是3个拼接起来的,完全没有问题,但是,写入沙盒的文件还是原来一段的大小,这很费解。 后来,换了另一种方式。(知道原因的大家可以留言)    //保存音频    [soundData writeToFile:COMBINPATH atomically:YES];    NSLog(@"%@",COMBINPATH);}@end
  • 使用AVFoundation下的AVAssetExportSessio 将mov文件进行拼接
#import "ViewController.h"#define kCachesPath [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]#define MUSIC                    [kCachesPath stringByAppendingPathComponent:@"Music"]#define COMBIN_FILEFULLPATH         [MUSIC stringByAppendingPathComponent:@"combine.mov"]@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    NSFileManager *fileManager = [NSFileManager defaultManager];    if (![fileManager fileExistsAtPath:MUSIC]) {        [fileManager createDirectoryAtPath:MUSIC withIntermediateDirectories:YES attributes:nil error:nil];    } NSString *firstPath = [[NSBundle mainBundle] pathForResource:@"first" ofType:@"mov"]; NSURL *firstUrl = [NSURL fileURLWithPath:firstPath]; NSString *secondPath = [[NSBundle mainBundle] pathForResource:@"second" ofType:@"mov"]; NSURL *secondUrl = [NSURL fileURLWithPath:secondPath]; NSDictionary *optDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];    // 音频采集    AVURLAsset  *firstAsset = [AVURLAsset URLAssetWithURL:firstUrl options:optDict];   AVURLAsset  *secondAsset = [AVURLAsset URLAssetWithURL:secondUrl options:optDict];    // 获取音频采集通道    NSArray<AVAssetTrack *> *videoTracks = [firstAsset tracksWithMediaType:AVMediaTypeAudio];    AVAssetTrack *assetVideoTrack = nil;    if (videoTracks.count != 0) {        assetVideoTrack = videoTracks.firstObject;    }    // 创建可变的音视频组合    AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];    // 音频通道 这里的mediaType传入的是文件类型,因为我们即将插入的文件类型是音频,这里要选择AVMediaTypeAudio    AVMutableCompositionTrack *firstTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio                                                                        preferredTrackID:kCMPersistentTrackID_Invalid];    // 把采集轨道数据加入到可变轨道中    [firstTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, firstAsset.duration)                        ofTrack:assetVideoTrack atTime:kCMTimeZero error:nil];     [firstTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, secondAsset.duration)                        ofTrack:assetVideoTrack atTime:firstAsset.duration error:nil];    if ([[NSFileManager defaultManager] fileExistsAtPath:COMBIN_FILEFULLPATH]) {        [[NSFileManager defaultManager] removeItemAtPath:COMBIN_FILEFULLPATH error:nil];    }    NSURL *url = [NSURL fileURLWithPath:COMBIN_FILEFULLPATH];    // 创建输出    AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition                                                                   presetName:AVAssetExportPresetPassthrough];    exporter.outputURL=url;    exporter.outputFileType = AVFileTypeQuickTimeMovie;    exporter.shouldOptimizeForNetworkUse = YES;    [exporter exportAsynchronouslyWithCompletionHandler:^{        if (AVAssetExportSessionStatusCompleted == exporter.status) {            NSLog(@"---------- sucesss");            NSLog(@"--> %@",COMBIN_FILEFULLPATH);        }else {            NSLog(@"-- exportSession->error : %@",exporter.error);        }    }];}@end
0 0