मैं एक एवीएमटेबल कॉम्पोजिशन, एक AVMutableVideoComposition और आईओवी 4.3 पर एक AVVideoCompositionCoreAnimationTool का उपयोग कर पोर्ट्रेट-मोड वीडियो (निर्यात पर) में एक कैलियर को सेंकने की कोशिश कर रहा हूं। यह सब परिदृश्य में काम करता है। अगर मैं पोर्ट्रेट में वीडियो कैप्चर करता हूं, हालांकि, AVVideoCompositionCoreAnimationTool वीडियो ट्रैक पर ट्रांसफॉर्म को अनदेखा कर रहा है। पोर्ट्रेट-मोड वीडियो के लिए, मैं मूल संपत्ति वीडियो ट्रैक से पसंदीदा ट्रान्सफॉर्म मान को AVMutableCompositionTrack.preferredTransform सेट कर रहा हूं। जब तक मैं AVVideoCompositionCoreAnimationTool का उपयोग नहीं करता, यह काम करता है, और वीडियो पोर्ट्रेट मोड में आता है। जैसे ही मैं एक AVVideoCompositionCoreAnimationTool और CALayer जोड़ता हूं, हालांकि, फ़ाइल परिदृश्य में बाहर आती है। (कैलियर सही ढंग से दिखाई देता है, लेकिन इसके पीछे वाला वीडियो इसके पक्ष में है, और फ़ाइल का पहलू अनुपात बंद है)। मैंने CALAYer में परिवर्तन लागू करने और ACVideoComposition में एक रूपांतरण स्थापित करने का प्रयास किया है। इनमें से कोई भी उत्पादित फ़ाइल का अभिविन्यास नहीं बदलता है (यह अभी भी 480x369 है, 360x480 नहीं)। AVVideoCompositionCoreAnimationTool के साथ पोर्ट्रेट-मोड वीडियो प्रस्तुत करने का कोई तरीका है?AVVideoCompositionCoreAnimationTool और CALayer पोर्ट्रेट मोड में?
सबसे पहले मैं एक शीर्षक के साथ एक AVMutableComposition और AVMutableVideoComposition
AVMutableComposition *composition = [AVMutableComposition composition];
AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVURLAsset *videoAsset = [AVURLAsset URLAssetWithURL:url options:nil];
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, [videoAsset duration]);
AVAssetTrack *clipVideoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
CGSize videoSize = CGSizeApplyAffineTransform(clipVideoTrack.naturalSize, clipVideoTrack.preferredTransform);
videoSize.width = fabs(videoSize.width);
videoSize.height = fabs(videoSize.height);
CMTime titleDuration = CMTimeMakeWithSeconds(5, 600);
CMTimeRange titleRange = CMTimeRangeMake(kCMTimeZero, titleDuration);
[compositionVideoTrack insertTimeRange:titleRange ofTrack:nil atTime:kCMTimeZero error:nil];
[compositionVideoTrack insertTimeRange:timeRange ofTrack:clipVideoTrack atTime:titleDuration error:nil];
compositionVideoTrack.preferredTransform = clipVideoTrack.preferredTransform;
AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
AVMutableVideoCompositionInstruction *passThroughInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
passThroughInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, [composition duration]);
AVAssetTrack *videoTrack = [[composition tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVMutableVideoCompositionLayerInstruction *passThroughLayer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
passThroughInstruction.layerInstructions = [NSArray arrayWithObject:passThroughLayer];
videoComposition.instructions = [NSArray arrayWithObject:passThroughInstruction];
videoComposition.frameDuration = CMTimeMake(1, 30);
videoComposition.renderSize = videoSize;
videoComposition.renderScale = 1.0;
और एक CALayer की स्थापना
CALayer *animationLayer = [CALayer layer];
animationLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height);
CATextLayer *titleLayer = [CATextLayer layer];
titleLayer.string = [effect valueForKey:@"title"];
titleLayer.font = [effect valueForKey:@"font"];
titleLayer.fontSize = 30;
titleLayer.alignmentMode = kCAAlignmentCenter;
titleLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height/6);
[animationLayer addSublayer:titleLayer];
titleLayer.anchorPoint = CGPointMake(0.5, 0.5);
titleLayer.position = CGPointMake(CGRectGetMidX(layer.bounds), CGRectGetMidY(layer.bounds));
CABasicAnimation *fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
fadeAnimation.fromValue = [NSNumber numberWithFloat:1.0];
fadeAnimation.toValue = [NSNumber numberWithFloat:0.0];
fadeAnimation.additive = NO;
fadeAnimation.removedOnCompletion = NO;
fadeAnimation.beginTime = 3.5;
fadeAnimation.duration = 1.0;
fadeAnimation.fillMode = kCAFillModeBoth;
[titleLayer addAnimation:fadeAnimation forKey:nil];
अंत में मैं AVMutableVideoComposition
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height);
parentLayer.anchorPoint = CGPointMake(0, 0);
parentLayer.position = CGPointMake(0, 0);
videoLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height);
[parentLayer addSublayer:videoLayer];
videoLayer.anchorPoint = CGPointMake(0.5, 0.5);
videoLayer.position = CGPointMake(CGRectGetMidX(parentLayer.bounds), CGRectGetMidY(parentLayer.bounds));
[parentLayer addSublayer:layer];
animationLayer.anchorPoint = CGPointMake(0.5, 0.5);
animationLayer.position = CGPointMake(CGRectGetMidX(parentLayer.bounds), CGRectGetMidY(parentLayer.bounds));
videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
और निर्यात करने के लिए CALayer जोड़ने!
AVAssetExportSession *exportSession = [[[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetMediumQuality] autorelease];
exportSession.videoComposition = videoComposition;
NSURL *segmentFileURL = //some local URL
exportSession.outputFileType = @"com.apple.quicktime-movie";
exportSession.outputURL = segmentFileURL;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
switch ([exportSession status]) {
case AVAssetExportSessionStatusFailed:
Log(@"Export failed: %@", [exportSession error]);
break;
case AVAssetExportSessionStatusCancelled:
Log(@"Export canceled");
break;
case AVAssetExportSessionStatusCompleted:
Log(@"Export done");
break;
}
}];
इस कोड को लैंडस्केप मोड में काम करता है, और यह भी चित्र में अगर मैं लाइन videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
मुझे एक ही समस्या है। क्या आपको इसका समाधान मिला? –
हां, हालांकि मुझे पोर्ट्रेट मोड रचनाओं के साथ-साथ अन्य समस्याओं का एक गुच्छा सामना करना पड़ा। यह चाल AVMutableVideoCompositionLayerInstruction पर ट्रांसफॉर्म सेट करने के लिए है। हालांकि, सही परिवर्तन संपत्ति के पसंदीदा परिवर्तन नहीं है। पसंदीदा परिवर्तन के साथ शुरू करें, और अतिरिक्त अनुवाद और फ्लिप लागू करें। आपको कुछ ऐसा मिल जाएगा जो काम करता है (फ्रेम आकार के फ़ंक्शन के रूप में)। दुर्भाग्यवश प्रत्येक अभिविन्यास के लिए सही परिवर्तन अलग है। असल में, रचना में एक बग है, और हम निर्यात परत को पोजिशन करके इसके आसपास काम कर रहे हैं। मैं इसे काम करने के लिए मिला था। – wombat57