您好我正在尝试使用 AVMutableComposition 将视频合并在一起。我遇到的问题是 AVAsset trackingWithMediaTypes 方法返回一个空数组并且应用程序崩溃了。
有人可以指出我做错了什么。谢谢
这是我到目前为止所拥有的:
-(void) mergeVideosAndAudio:(AVAsset *)audioAsset{
//Load Video Assets
NSError *error;
NSArray *dirFiles;
if ((dirFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[self documentsDirectory] error:&error]) == nil) {
// handle the error
};
// find all the temp files
NSArray *movFiles = [dirFiles filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self BEGINSWITH 'temp'"]];
NSLog(@"The are %i temp files",movFiles.count);
NSArray *filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:[self documentsDirectory] error:nil];
//Create the composition
AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];
// 1 - Video track
AVMutableCompositionTrack *firstTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
CMTime videoTrackDuration;
for (int j = 0; j < filePathsArray.count; j++) {
NSURL *url = [NSURL fileURLWithPath:filePathsArray[j]];
AVURLAsset *currentAsset = [[AVURLAsset alloc]initWithURL:url options:nil];
videoTrackDuration = CMTimeAdd(videoTrackDuration, currentAsset.duration);
CMTime time;
if (j == 0) {
time = kCMTimeZero;
}else{
NSURL *previousAssetURL = [NSURL fileURLWithPath:filePathsArray[j-1]];
AVURLAsset *previousAsset = [[AVURLAsset alloc]initWithURL:previousAssetURL options:nil];
time = previousAsset.duration;
}
[firstTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, currentAsset.duration) ofTrack:[[currentAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:time error:nil];
}
// 2 - Audio track
if (audioAsset!=nil){
AVMutableCompositionTrack *AudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
preferredTrackID:kCMPersistentTrackID_Invalid];
[AudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoTrackDuration)
ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:nil];
}
//3 - Get Path for merge
NSString *myPathDocs = [[self documentsDirectory] stringByAppendingPathComponent:
[NSString stringWithFormat:@"mergeVideo-%d.mov",arc4random() % 1000]];
self.fileURL = [NSURL URLWithString: myPathDocs];
// 5 - Create exporter
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition
presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL=self.fileURL;
exporter.outputFileType = AVFileTypeQuickTimeMovie;
exporter.shouldOptimizeForNetworkUse = YES;
[exporter exportAsynchronouslyWithCompletionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
[self exportDidFinish:exporter];
});
}];
}
-(void)exportDidFinish:(AVAssetExportSession*)session {
if (session.status == AVAssetExportSessionStatusCompleted) {
self.fileURL = session.outputURL;
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:self.fileURL]) {
[library writeVideoAtPathToSavedPhotosAlbum:self.fileURL completionBlock:^(NSURL *assetURL, NSError *error){
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Video Saving Failed"
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Video Saved" message:@"Saved To Photo Album"
delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
}
});
}];
}
}
[self removeTempFilesFromDocuments];
}
这是错误的屏幕截图: