我想按照我的方面撰写视频。用户将从库中选择视频。看看我的屏幕。有一个背景是UIView
。它的颜色是多变的。并且该视图上方有一个AVPlayer。我已根据所选视频的宽高比调整了AVPlayer
的大小。现在我想编写整个场景并将其保存到照片库。到目前为止我已经这样做了。保存的视频应该像第二张图像一样。但它没有提供随机视频。
- (IBAction)videoOutput:(id)sender
{
// 2 - Create AVMutableComposition object. This object will hold your AVMutableCompositionTrack instances.
AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];
// 3 - Video track
AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, self.videoAsset.duration) ofTrack:[[self.videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil];
// 3.1 - Create AVMutableVideoCompositionInstruction
AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, self.videoAsset.duration);
// 3.2 - Create an AVMutableVideoCompositionLayerInstruction for the video track and fix the orientation.
AVMutableVideoCompositionLayerInstruction *videolayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
AVAssetTrack *videoAssetTrack = [[self.videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
UIImageOrientation videoAssetOrientation_ = UIImageOrientationUp;
BOOL isVideoAssetPortrait_ = NO;
CGAffineTransform videoTransform = videoAssetTrack.preferredTransform;
if (videoTransform.a == 0 && videoTransform.b == 1.0 && videoTransform.c == -1.0 && videoTransform.d == 0) {
videoAssetOrientation_ = UIImageOrientationRight;
isVideoAssetPortrait_ = YES;
}
if (videoTransform.a == 0 && videoTransform.b == -1.0 && videoTransform.c == 1.0 && videoTransform.d == 0) {
videoAssetOrientation_ = UIImageOrientationLeft;
isVideoAssetPortrait_ = YES;
}
if (videoTransform.a == 1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == 1.0) {
videoAssetOrientation_ = UIImageOrientationUp;
}
if (videoTransform.a == -1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == -1.0) {
videoAssetOrientation_ = UIImageOrientationDown;
}
CGSize naturalSize;
if(isVideoAssetPortrait_){
naturalSize = CGSizeMake(videoAssetTrack.naturalSize.height, videoAssetTrack.naturalSize.width);
} else {
naturalSize = videoAssetTrack.naturalSize;
}
NSLog(@"%@",NSStringFromCGSize(naturalSize));
[videolayerInstruction setTransform:videoAssetTrack.preferredTransform atTime:kCMTimeZero];
// 3.3 - Add instructions
mainInstruction.layerInstructions = [NSArray arrayWithObjects:videolayerInstruction,nil];
AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition];
mainCompositionInst.renderSize = CGSizeMake(320, 320);
mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction];
mainCompositionInst.frameDuration = CMTimeMake(1, 30);
[self applyVideoEffectsToComposition:mainCompositionInst size:naturalSize withColor:[array objectAtIndex:colorTag]];
// 4 - Get path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *myPathDocs = [documentsDirectory stringByAppendingPathComponent:
[NSString stringWithFormat:@"FinalVideo-%d.mov",arc4random() % 1000]];
NSURL *url = [NSURL fileURLWithPath:myPathDocs];
// 5 - Create exporter
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPreset640x480];
exporter.outputURL=url;
exporter.outputFileType = AVFileTypeQuickTimeMovie;
exporter.shouldOptimizeForNetworkUse = YES;
exporter.videoComposition = mainCompositionInst;
[exporter exportAsynchronouslyWithCompletionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
[self exportDidFinish:exporter];
});
}];
}
- (void)exportDidFinish:(AVAssetExportSession*)session
{
if (session.status == AVAssetExportSessionStatusCompleted)
{
NSURL *outputURL = session.outputURL;
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:outputURL]) {
[library writeVideoAtPathToSavedPhotosAlbum:outputURL 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];
}
});
}];
}
}
}
- (UIImage *)imageWithColor:(UIColor *)color rectSize:(CGRect)imageSize {
CGRect rect = imageSize;
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
[color setFill];
UIRectFill(rect); // Fill it with your color
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
- (void)applyVideoEffectsToComposition:(AVMutableVideoComposition *)composition size:(CGSize)size withColor:(UIColor *)color
{
CGFloat temp = 1280;
CGSize videoSize = size;
CGFloat width = ((videoSize.width/videoSize.height)*temp);
CGFloat x = (temp - width)/2;
UIImage *borderImage = nil;
borderImage = [self imageWithColor:color rectSize:CGRectMake(0, 0, size.width, size.height)];
CALayer *backgroundLayer = [CALayer layer];
[backgroundLayer setContents:(id)[borderImage CGImage]];
backgroundLayer.frame = CGRectMake(0, 0, 720, 1280);
[backgroundLayer setMasksToBounds:YES];
CALayer *videoLayer = [CALayer layer];
videoLayer.frame = CGRectMake(x, 0, width-00, temp);
NSLog(@"video layer >> %@",NSStringFromCGRect(videoLayer.frame));
videoLayer.contentsGravity = kCAGravityBottomRight;
CALayer *parentLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, 720, 1280);
parentLayer.contentsGravity = kCAGravityBottomRight;
parentLayer.backgroundColor = [UIColor redColor].CGColor;
[parentLayer addSublayer:backgroundLayer];
[parentLayer addSublayer:videoLayer];
composition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
}
- (IBAction)btn_play_pressed:(id)sender
{
[self.player play];
}
- (void)btn_pressed:(id)sender
{
colorTag = [(UIButton *)sender tag];
NSLog(@" %d",colorTag);
self.backgroundView.backgroundColor = [array objectAtIndex:colorTag];
}
答案 0 :(得分:1)
我不认为你一直在设置AVMutableVideoCompositionInstruction.backgroundColor。
UIColor *redColor = [UIColor redColor];
AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, self.videoAsset.duration);
mainInstruction.backgroundColor = redColor.CGColor;
这会将背景设置为红色,您可能希望使用用户指定的颜色。