我写了两种方法
- 一个产生音频的
- 另一个将音频添加到视频中
我使用 'AVAssetExportSession' 来做这些事情并在 AVAssetExportSession 类的 'exportAsynchronouslyWithCompletionHandler' 中执行一些操作
这是生成音频的代码
AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition
presetName:AVAssetExportPresetAppleM4A];
NSString *outputUrl = [NSString stringWithFormat:@"%@/Video/%@",userDocumentsPath,@"finalAudio.m4a"];
//Specifing the output file where we want to store our fianl asset
_assetExport.outputFileType = AVFileTypeAppleM4A;
NSURL *finalUrl = [[NSURL alloc] initFileURLWithPath:outputUrl isDirectory:NO];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:finalUrl.path];
//deleting file if it exists
if (fileExists)
{
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:finalUrl.path error:NULL];
}
_assetExport.outputURL = finalUrl;
_assetExport.shouldOptimizeForNetworkUse = YES;
_assetExport.audioMix = audioMix;
__block ICImageToVideo *temp = self;
[_assetExport exportAsynchronouslyWithCompletionHandler:
^(void )
{
NSString *documentsPath = nil;
NSArray *filePaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if ([filePaths count] > 0)
{
documentsPath = [filePaths objectAtIndex:0];
}
NSString *audioPath = [NSString stringWithFormat:@"%@/Video/%@",documentsPath,@"finalAudio.m4a"];
NSURL *finalAudio = [[NSURL alloc] initFileURLWithPath:audioPath isDirectory:NO];
temp.audioUrl = finalAudio;
[temp addAudioToVideo];
[finalAudio release];
[_assetExport release];
}];
并且将音频添加到视频的代码是:
- (void)addAudioToVideo
{
NSString *userDocumentsPath = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if ([paths count] > 0)
{
userDocumentsPath = [paths objectAtIndex:0];
}
NSURL *videoUrl = [[NSURL alloc] initFileURLWithPath:self.videoUrl] ;
// NSString* audio = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"mp3"];
// NSURL *audioUrl = [[NSURL alloc] initFileURLWithPath:audio];
if (self.audioUrl || videoUrl)
{
NSLog(@"Found the URLs!");
}
//Used to denote an audoi/video asset taken from the url
//https://developer.apple.com/library/mac/#documentation/AVFoundation/Reference/AVURLAsset_Class/Reference/Reference.html
AVURLAsset* audioAsset = [[AVURLAsset alloc] initWithURL:self.audioUrl options:nil];
AVURLAsset* videoAsset = [[AVURLAsset alloc] initWithURL:videoUrl options:nil];
//Used to denote a set of AVCompositionMutableTrack 's to create a custom combination from combining them
//https://developer.apple.com/library/mac/#documentation/AVFoundation/Reference/AVMutableComposition_Class/Reference/Reference.html
AVMutableComposition* mixComposition = [AVMutableComposition composition];
//Used to allow us to make a low level composition of tracks
//https://developer.apple.com/library/ios/#DOCUMENTATION/AVFoundation/Reference/AVMutableCompositionTrack_Class/Reference/Reference.html
AVMutableCompositionTrack *compositionCommentaryTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
preferredTrackID:kCMPersistentTrackID_Invalid];
//Here we insert a custom asset into a track of our mutable track composition at the specified time
[compositionCommentaryTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration )
ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]
atTime:kCMTimeZero error:nil];
NSLog(@"Audio Duration : %f",CMTimeGetSeconds(audioAsset.duration));
NSLog(@"Video Duration : %f",CMTimeGetSeconds(videoAsset.duration));
int difference = CMTimeCompare(videoAsset.duration, audioAsset.duration);
NSLog(@"Difference = %d",difference);
//We create another mutable composition track to hold the video that we need to insert into our final asset
AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
atTime:kCMTimeZero error:nil];
AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition
presetName:AVAssetExportPresetPassthrough];
NSString *outputUrl = [NSString stringWithFormat:@"%@/Video/%@",userDocumentsPath,@"final.mov"];
//Specifing the output file where we want to store our fianl asset
_assetExport.outputFileType = @"com.apple.quicktime-movie";
NSLog(@"file type %@",_assetExport.outputFileType);
NSURL *finalUrl = [[NSURL alloc] initFileURLWithPath:outputUrl isDirectory:NO];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:finalUrl.path];
//deleting file if it exists
if (fileExists)
{
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:finalUrl.path error:NULL];
}
_assetExport.outputURL = finalUrl;
_assetExport.shouldOptimizeForNetworkUse = YES;
__block ICImageToVideo *temp = self;
[_assetExport exportAsynchronouslyWithCompletionHandler:
^(void )
{
NSString *documentsPath = nil;
NSArray *filePaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if ([filePaths count] > 0)
{
documentsPath = [filePaths objectAtIndex:0];
}
NSString *videopath = [NSString stringWithFormat:@"%@/Video/%@",documentsPath,@"final.mov"];
NSLog(@"videoPAth: %@",videopath);
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:temp.videoUrl];
//deleting file if it exists
if (fileExists)
{
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:temp.videoUrl error:NULL];
NSURL* tempSrcURL = [[NSURL alloc] initFileURLWithPath:videopath];
NSURL* sourceUrl = tempSrcURL;
//[tempSrcURL release]; //[NEW LEAK FIXED]
//NSURL *sourceUrl = [[NSURL alloc] initFileURLWithPath:videopath];
NSURL* tempDestURL = [[NSURL alloc] initFileURLWithPath:temp.videoUrl];
NSURL* destinationUrl = tempDestURL;
//[tempDestURL release]; //[NEW LEAK FIXED]
//NSURL *destinationUrl = [[NSURL alloc]initFileURLWithPath:self.videoUrl];
[fileManager moveItemAtURL:sourceUrl toURL:destinationUrl error:nil];
[tempSrcURL release]; //[NEW LEAK FIXED]
[tempDestURL release]; //[NEW LEAK FIXED]
}
[temp.delegate didProgressVideoGenereation:1];
[temp.delegate didFinishPreparingVideoWithUrl:self.videoUrl];
[_assetExport release];
}];
[audioAsset release];
[videoAsset release];
[videoUrl release];
[finalUrl release];
}
我似乎在两个/一个块中都出现了泄漏,并且我未能使用泄漏工具或静态分析器确定问题所在。
任何的意见都将会有帮助 。