//第一種方式
session
//asset生成必須爲文件的url,並且是本地app
AVAsset *mediaAsset = _player.currentItem.asset;異步
//AVMutableComposition 能夠進行音視頻的組合ui
AVAssetExportSession *es = [[AVAssetExportSession alloc] initWithAsset:mediaAsset presetName:AVAssetExportPresetPassthrough];url
NSString *outPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"out.mov"];spa
NSFileManager *fileManager = [NSFileManager defaultManager];.net
[fileManager removeItemAtPath:outPath error:NULL];3d
//格式的轉換orm
es.outputFileType = AVFileTypeQuickTimeMovie;視頻
es.outputURL = [[NSURL alloc] initFileURLWithPath:outPath];
es.shouldOptimizeForNetworkUse=NO;
CMTime start = CMTimeMakeWithSeconds(1.0, 600);
CMTime duration = CMTimeMakeWithSeconds(3.0, 600);
CMTimeRange range = CMTimeRangeMake(start, duration);
//音頻的時間範圍
es.timeRange = range;
NSLog(@"exporting to %@",outPath);
//異步輸出完成後調用
[es exportAsynchronouslyWithCompletionHandler:^{
NSString *status = @"" ;
if( es.status == AVAssetExportSessionStatusCompleted ) status = @"AVAssetExportSessionStatusCompleted";
else if( es.status == AVAssetExportSessionStatusFailed ) status = @"AVAssetExportSessionStatusFailed";
NSLog(@"done exporting to %@ status %d = %@ (%@)",outPath,es.status, status,[es error]);
}];
//第二種方式讀取本地到另一個地方
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *audioPath = [documentPath stringByAppendingPathComponent:[NSString stringWithFormat:@"audio"]];
NSURL *fileUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/1141.mp3",audioPath]];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:fileUrl options:nil];
NSError *error = nil;
NSArray *array=[_player.currentItem.asset tracksWithMediaType:AVMediaTypeAudio];
AVAssetTrack *track=[[_player.currentItem.asset tracksWithMediaType:AVMediaTypeAudio]firstObject];
NSLog(@"%@",_player.currentItem.asset);
assetReader=[[AVAssetReader alloc]initWithAsset:_player.currentItem.asset error:&error];
NSDictionary *readerOutputSettings=@{(id)AVFormatIDKey:@(kAudioFormatLinearPCM)};
//若是讀取失敗接下來的代碼不會執行。
AVAssetReaderTrackOutput *trackOutput=[[AVAssetReaderTrackOutput alloc]initWithTrack:track outputSettings:readerOutputSettings];
[assetReader addOutput:trackOutput];
//先判斷read爲YES
BOOL read= [assetReader startReading];
NSString *userPath = [audioPath stringByAppendingPathComponent:[NSString stringWithFormat:@"/writer1.wav"]];
NSURL *outputURL=[NSURL fileURLWithPath:userPath];
assetWriter=[[AVAssetWriter alloc]initWithURL:outputURL fileType:AVFileTypeWAVE error:nil];
AudioChannelLayout channelLayout;
memset(&channelLayout, 0, sizeof(AudioChannelLayout));
channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
//lin PCM須要設置PCM一些相關的屬性
NSDictionary *writerOutputSetting=@{(id)AVFormatIDKey:@(kAudioFormatLinearPCM),(id)AVSampleRateKey:[NSNumber numberWithFloat:44100.0],AVNumberOfChannelsKey:[NSNumber numberWithInt: 2],AVLinearPCMBitDepthKey:[NSNumber numberWithInt:16],
AVLinearPCMIsNonInterleaved:[NSNumber numberWithBool:NO],
AVLinearPCMIsFloatKey:[NSNumber numberWithBool:NO],
AVLinearPCMIsBigEndianKey:[NSNumber numberWithBool:NO],AVChannelLayoutKey:[ NSData dataWithBytes:&channelLayout length: sizeof( AudioChannelLayout ) ]};
AVAssetWriterInput *writerInput=[[AVAssetWriterInput alloc]initWithMediaType:AVMediaTypeAudio outputSettings:writerOutputSetting];
[assetWriter addInput:writerInput];
BOOL writer=[assetWriter startWriting];
dispatch_queue_t dispatchQueue=dispatch_queue_create("com/tapharmonic.WriterQueue", NULL);
[assetWriter startSessionAtSourceTime:kCMTimeZero];
[writerInput requestMediaDataWhenReadyOnQueue:dispatchQueue usingBlock:^{
bool complete=NO;
while ([writerInput isReadyForMoreMediaData]&& !complete) {
NSLog(@"%@",assetWriter.error);
CMSampleBufferRef sampleBuffer=[trackOutput copyNextSampleBuffer];
if(sampleBuffer){
BOOL result=[writerInput appendSampleBuffer:sampleBuffer];
CFRelease(sampleBuffer);
complete=!result;
}else{
[writerInput markAsFinished];
complete=YES;
}
}
if(complete){
[assetWriter finishWritingWithCompletionHandler:^{
AVAssetWriterStatus status=assetWriter.status;
NSLog(@"%@",assetWriter.error);
if(status==AVAssetWriterStatusCompleted){
NSLog(@"AVAssetWriterStatusCompleted");
}else{
NSLog(@"AVAssetWriterStatusFailed");
}
}];
}
}];
AVAssetExportSession你能夠取消這個生成操做,經過給session發送 cancelExport 消息。
失敗緣由:
· 若是導出的文件存在,或者導出的url在沙盒以外,這個導出操做會失敗。
· 來了一個電話
· 你的程序在後臺運行而且其餘的應用開始播放。
這種狀況下,你應該通知用戶export失敗,而且從新export。