
हेलो, हेब्र!
वीडियो के संयोजन की समस्या को हल करने के लिए मुझे जिन परियोजनाओं की आवश्यकता थी, उनमें से एक में, विशेष रूप से, उपयोगकर्ता वीडियो को रोक सकता है, और फिर रिकॉर्डिंग जारी रख सकता है (पुनरावृत्तियों की संख्या अज्ञात थी)। इसलिए, उपलब्ध साधनों द्वारा इस समस्या को हल करने का एक तरीका खोजना आवश्यक था। बेशक, दो विकल्प मेरे पास आए, या तो एक फ़ाइल में एक बार में सब कुछ लिखने के लिए, या अलग-अलग लोगों को लिखने के लिए, और सत्र के बाद उन्हें गोंद करने के लिए। मैंने दूसरे पर रहने का फैसला किया, और इसके बारे में क्या आया, कट के नीचे पढ़ें।
वीडियो रिकॉर्ड करने के लिए, मैंने
AVCamCaptureManager का उपयोग किया, जो AVCam एप्लिकेशन पर आधारित है, कृपया हमारी पसंदीदा
साइट पर स्थित है। खैर, स्टॉप बटन दबाने के बाद मज़ा शुरू हुआ।
चरण 1. तैयारी।
इस स्तर पर, निम्नलिखित करें:
- ऑब्जेक्ट AVMutableComposition । इसके हमारे रास्ते होंगे।
AVMutableCompositionAVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];
- पटरियों के लिए निर्देशों की एक सरणी और उनके लिए एक AVMutableVideoCompositionInstruction ऑब्जेक्ट।
AVMutableVideoCompositionInstruction NSMutableArray *arrayInstruction = [[NSMutableArray alloc] init]; AVMutableVideoCompositionInstruction *MainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
- आम ऑडियो ट्रैक। IsSound वैरिएबल इंगित करता है कि यहां इसकी आवश्यकता है (कार्य के अनुसार, उपयोगकर्ता ध्वनि के साथ या बिना वीडियो रिकॉर्ड कर सकता है)।
आम ऑडियो ट्रैक AVMutableCompositionTrack *audioTrack; if(self.isSoundOn==YES) audioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
चरण 2. फाइलों को खोजें, संपत्ति बनाना, निर्देश उत्पन्न करना और यदि आवश्यक हो तो वीडियो ट्रैक को बदलना।
- हम सभी फाइलों पर चलते हैं और उनमें से प्रत्येक के लिए संपत्ति बनाते हैं। यह सब कर सकते हैं और एक लूप में किया जाना चाहिए, चर i-here फ़ाइल इंडेक्स है।
एसेट क्रिएशनमैंने i के मूल्य में वृद्धि करते हुए सभी वीडियो को टेम्पो डायरेक्टरी में रिकॉर्ड किया। तदनुसार, इन फ़ाइलों से संपत्ति बनाई जाती है।
AVAsset *currentAsset = [AVAsset assetWithURL:[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@%@%d%@", NSTemporaryDirectory(), @"Movie",i,@".mov"]]];
- लूप में, AVMutableCompositionTrack बनाया गया है, जिसमें प्रत्येक में निर्मित संपत्ति से एक समय अंतराल CMTimeRange डाला जाता है।
ट्रैक निर्माण //VIDEO TRACK AVMutableCompositionTrack *currentTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; [currentTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, currentAsset.duration) ofTrack:[[currentAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:duration error:nil];
विशेष रूप से ध्यान देना चाहिए कि वास्तव में आप सेगमेंट को कहां डालना चाहते हैं, यदि आप प्लेबैक के दौरान काली पट्टियों से बचना चाहते हैं, या इससे भी बदतर, प्लेबैक के दौरान एक वीडियो को दूसरे पर ओवरलैप कर रहे हैं। और यह भी मत पूछो कि मैं इस पर ध्यान क्यों देता हूं।
- AVMutableVideoCompositionLayerInstruction ट्रैक की एक विशिष्ट परत के लिए निर्देश बनाने के लिए उपयोग किया जाता है। यह उस में है कि एक संभावित परिवर्तन दर्ज किया गया है।
AVMutableVideoCompositionLayerInstruction AVMutableVideoCompositionLayerInstruction *currentAssetLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:currentTrack];
आउटपुट पर वीडियो (पोर्ट्रेट या लैंडस्केप) की स्थिति की सही परिभाषा के साथ, आप एक भव्य चित्र प्राप्त कर सकते हैं जिसमें क्षैतिज या ऊर्ध्वाधर वीडियो किस ट्रैक पर निर्भर करता है कि आप किस मोड में पहले जाते हैं।
- AVMediaTypeVideo की मौजूदा परिसंपत्ति के आधार पर एक ट्रैक बनाने के लिए AVAssetTrack ऑब्जेक्ट की आवश्यकता होती है।
AVAssetTrack AVAssetTrack *currentAssetTrack = [[currentAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
- अवधि मान बढ़ाएँ।
अवधि यूपीCMTime को एक अलग पोस्ट की भी आवश्यकता है।
duration=CMTimeAdd(duration, currentAsset.duration)
स्टेज 3. MainInstruction मापदंडों की स्थापना और
AVMutableVideoComposition का गठन
timeRangeवीडियो ट्रैक की कुल अवधि।
MainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, duration);
layerInstructionsयहां हमें दूसरे चरण में गठित निर्देशों की एक सरणी की आवश्यकता है।
MainInstruction.layerInstructions = arrayInstruction;
MainCompositionInstहम आवश्यक मापदंडों के साथ MainCompositionInst का एक उदाहरण बनाते हैं
AVMutableVideoComposition *MainCompositionInst = [AVMutableVideoComposition videoComposition]; MainCompositionInst.instructions = [NSArray arrayWithObject:MainInstruction]; MainCompositionInst.frameDuration = CMTimeMake(1, 30); MainCompositionInst.renderSize = CGSizeMake(320.0, 480.0);
कहाँ बचाऊं कुछ? NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *myPathDocs = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"mergeVideo-%d.mov",arc4random() % 1000]]; NSURL *url = [NSURL fileURLWithPath:myPathDocs];
स्टेज 4. AVAssetExportSession के माध्यम से प्राप्त वीडियो को
सहेजनाउच्चतम और
मध्यम प्रीसेट के बीच अंतर बहुत महत्वपूर्ण है। इसलिए, यदि आप सामाजिक नेटवर्क पर वीडियो वितरित करने की योजना बनाते हैं, तो मैं दृढ़ता से अनुशंसा करता हूं कि आप माध्यम का उपयोग करें।
हम गुणवत्ता निर्धारित करते हैं और एक सत्र बनाते हैं NSString *quality = AVAssetExportPresetHighestQuality; if(self.isHighQuality==NO) quality = AVAssetExportPresetMediumQuality; AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:quality];
सहेजें! exporter.outputURL=url; exporter.outputFileType = AVFileTypeQuickTimeMovie; exporter.videoComposition = MainCompositionInst; exporter.shouldOptimizeForNetworkUse = YES; [exporter exportAsynchronouslyWithCompletionHandler:^ { // . }];
संभावित निर्यात स्थिति:
हमारे यहाँ क्या है? switch (exporter.status) { case AVAssetExportSessionStatusCompleted: NSLog(@"Completed exporting!"); break; case AVAssetExportSessionStatusFailed: NSLog(@"Failed:%@", exporter.error.description); break; case AVAssetExportSessionStatusCancelled: NSLog(@"Canceled:%@", exporter.error); break; case AVAssetExportSessionStatusExporting: NSLog(@"Exporting!"); break; case AVAssetExportSessionStatusWaiting: NSLog(@"Waiting"); break; default: break; }
निष्कर्ष
लेख में, मैंने वीडियो के संयोजन पर ध्यान केंद्रित करने की कोशिश की, और मुझे लगता है कि इस पोस्ट से iOS के विकास में शामिल कई हब्रोस्क लोगों को मदद मिलेगी, जिन्हें भविष्य में इस तरह के कार्य का सामना करना पड़ता है। भविष्य में मैं
CMTime के बारे में अधिक बात करने की योजना बना रहा
हूं , और यह सिर्फ "समय" क्यों नहीं है। वैसे, विषय पर बहुत सारी उपयोगी जानकारी
साइट पर है । आप विधि को
रिपॉजिटरी में ही पा सकते हैं
।