您好我正在尝试使用AVMutableComposition合并视频。 我遇到的问题是AVAsset tracksWithMediaTypes方法返回一个空数组,应用程序崩溃。
有人可以指出我做错了什么。 感谢
这是我到目前为止所做的:
-(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];
}
以下是错误的屏幕截图:
答案 0 :(得分:0)
嗯,错误就在那里“索引0超出空数组的界限”。
这意味着您拥有空的视频资产数组。因此,通过NSFileManager
获取视频资产存在问题。去检查数组filePathsArray
,它有什么问题。
答案 1 :(得分:0)
首先检查视频是否存在于特定路径并正常运行。
就我而言,视频存在于路径中,但无法运行。 这主要是因为视频在该路径上没有正确写入。 希望它有所帮助。
答案 2 :(得分:0)
请检查您的文件持续时间应该为零。
答案 3 :(得分:0)
不确定这是否解决了您的问题。但是在我尝试从URL加载AVAsset但是获得没有轨道的资产之前我遇到过这个问题。为我修复的是在创建NSURL时添加“isDirectory:NO”:
NSURL *url = [NSURL fileURLWithPath:filePathsArray[j] isDirectory:NO];