我在iOS应用中使用AVCaptureConnection捕获视频。之后,我在视频中添加一些图像作为CALayers。一切都运行正常,但在添加图像后,在结果视频的最后得到一个黑框。在此没有影响实际音频/视频的帧。对于音频我正在提取它并改变它的音高然后使用AVMutableComposition添加它。这是我正在使用的代码。请帮助我解决我的错误或者我需要添加其他内容。
cmp = [AVMutableComposition composition];
AVMutableCompositionTrack *videoComposition = [cmp addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *audioComposition = [cmp addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *sourceVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVAssetTrack *sourceAudioTrack = [[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
[videoComposition insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:sourceVideoTrack atTime:kCMTimeZero error:nil] ;
[audioComposition insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:sourceAudioTrack atTime:kCMTimeZero error:nil];
animComp = [AVMutableVideoComposition videoComposition];
animComp.renderSize = CGSizeMake(320, 320);
animComp.frameDuration = CMTimeMake(1,30);
animComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
// to gather the audio part of the video
NSArray *tracksToDuck = [cmp tracksWithMediaType:AVMediaTypeAudio];
NSMutableArray *trackMixArray = [NSMutableArray array];
for (NSInteger i = 0; i < [tracksToDuck count]; i++) {
AVMutableAudioMixInputParameters *trackMix = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:[tracksToDuck objectAtIndex:i]];
[trackMix setVolume:5 atTime:kCMTimeZero];
[trackMixArray addObject:trackMix];
}
audioMix = [AVMutableAudioMix audioMix];
audioMix.inputParameters = trackMixArray;
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [asset duration]);
AVMutableVideoCompositionLayerInstruction *layerVideoInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoComposition];
[layerVideoInstruction setOpacity:1.0 atTime:kCMTimeZero];
instruction.layerInstructions = [NSArray arrayWithObject:layerVideoInstruction] ;
animComp.instructions = [NSArray arrayWithObject:instruction];
[self exportMovie:self];
这是我导出视频的方法
-(IBAction) exportMovie:(id)sender{
//successCheck = NO;
NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *tempPath = [docPaths objectAtIndex:0];
//NSLog(@"Temp Path: %@",tempPath);
NSString *fileName = [NSString stringWithFormat:@"%@/Final.MP4",tempPath];
NSFileManager *fileManager = [NSFileManager defaultManager] ;
if([fileManager fileExistsAtPath:fileName ]){
NSError *ferror = nil ;
[fileManager removeItemAtPath:fileName error:&ferror];
}
NSURL *exportURL = [NSURL fileURLWithPath:fileName];
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:cmp presetName:AVAssetExportPresetMediumQuality] ;
exporter.outputURL = exportURL;
exporter.videoComposition = animComp;
//exporter.audioMix = audioMix;
exporter.outputFileType = AVFileTypeQuickTimeMovie;
[exporter exportAsynchronouslyWithCompletionHandler:^(void){
switch (exporter.status) {
case AVAssetExportSessionStatusFailed:{
NSLog(@"Fail");
break;
}
case AVAssetExportSessionStatusCompleted:{
NSLog(@"Success video");
});
break;
}
default:
break;
}
}];
NSLog(@"outside");
}
答案 0 :(得分:4)
有一个exportsession属性给出时间范围, 尝试给时间范围少于实际时间(少几纳秒)
答案 1 :(得分:2)
感谢khushboo。我有同样的问题。 作为我的考验。只有10.7 sys版本有这个问题。 10.8没有。 通过设置导出会话的时间范围解决了这个问题。
答案 2 :(得分:1)
只想为有我特定问题的人写这篇。
我正在拍摄视频,并尝试通过AVMutableComposition
并通过scaleTimeRange
缩放音频和视频组件的时间范围来加快/降低视频速度
将时间范围缩放为2倍速或3倍速有时会导致视频的最后几帧变黑。幸运的是,@ Khushboo的答案也解决了我的问题。
但是,我没有将导出器的timeRange减少几纳秒,而是使它与合成的持续时间相同,最终效果很好。
exporter?.timeRange = CMTimeRangeMake(start: CMTime.zero, duration: composition.duration)
希望这会有所帮助!
答案 3 :(得分:1)
您可以从AVAssetTrack获得真实的视频时长。 AVAsset的持续时间有时比AVAssetTrack的持续时间长。
像这样检查持续时间。
print(asset.duration.seconds.description)
print(videoTrack.timeRange.duration.description)
因此您可以更改此行。
[videoComposition insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:sourceVideoTrack atTime:kCMTimeZero error:nil] ;
要这样。
[videoComposition insertTimeRange:sourceVideoTrack.timeRange, ofTrack:sourceVideoTrack atTime:kCMTimeZero error:nil] ;
快速5
videoComposition.insertTimeRange(sourceVideoTrack.timeRange, of: sourceVideoTrack, at: CMTime.zero)
然后您将避免出现最后一个黑框:)
希望这可以帮助仍然遭受痛苦的人。