2012-12-29 15 views
7

के साथ विफल रहता है मैं छोटे वीडियो क्लिप रिकॉर्ड कर रहा हूं (लगभग एक सेकंड या तो, दोनों अलग-अलग ओरिएंटेशन के साथ सामने और पीछे के कैमरे के साथ)। और फिर AVAssetExportSession का उपयोग करके उन्हें मर्ज करने का प्रयास करें। मैं मूल रूप से उचित परिवर्तन और ऑडियो & वीडियो ट्रैक के साथ एक रचना और एक वीडियो संयोजन बनाते हैं।exportAsynchronouslyWithCompletionHandler कई वीडियो फ़ाइलों (कोड = -11820)

समस्या यह है कि आईओएस 5 पर यह विफल रहता है यदि आपके पास 4 से अधिक वीडियो क्लिप हैं और आईओएस 6 पर सीमा 16 क्लिप लगती है।

यह मेरे लिए वास्तव में परेशान लगता है। AVAssetExport सत्र कुछ अजीब कर रहा है या क्या इसमें क्लिप की संख्या पर कुछ अनियंत्रित सीमा है जिसे इसे पारित किया जा सकता है? यहाँ मेरी कोड से कुछ अंश इस प्रकार हैं:

-(void)exportVideo 
{ 
    AVMutableComposition *composition = video.composition; 
    AVMutableVideoComposition *videoComposition = video.videoComposition; 
    NSString * presetName = AVAssetExportPresetMediumQuality; 

    AVAssetExportSession *_assetExport = [[AVAssetExportSession alloc] initWithAsset:composition presetName:presetName]; 
    self.exportSession = _assetExport; 

    videoComposition.renderSize = CGSizeMake(640, 480); 
    _assetExport.videoComposition = videoComposition; 

    NSString *exportPath = [NSTemporaryDirectory() stringByAppendingPathComponent: @"export.mov"]; 
    NSURL *exportUrl = [NSURL fileURLWithPath:exportPath]; 

    // Delete the currently exported files if it exists 
    if([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) 
     [[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil]; 

    _assetExport.outputFileType = AVFileTypeQuickTimeMovie; 
    _assetExport.outputURL = exportUrl; 
    _assetExport.shouldOptimizeForNetworkUse = YES; 

    [_assetExport exportAsynchronouslyWithCompletionHandler:^{ 
     switch (_assetExport.status) 
     { 
      case AVAssetExportSessionStatusCompleted: 
       NSLog(@"Completed exporting!"); 
       break; 
      case AVAssetExportSessionStatusFailed: 
       NSLog(@"Failed:%@", _assetExport.error.description); 
       break; 
      case AVAssetExportSessionStatusCancelled: 
       NSLog(@"Canceled:%@", _assetExport.error); 
       break; 
      default: 
       break; 
     } 
    }]; 
} 

यहाँ और है कि कैसे रचनाओं बना रहे हैं:

-(void)setVideoAndExport 
{ 
    video = nil; 
    video = [[VideoComposition alloc] initVideoTracks]; 

    CMTime localTimeline = kCMTimeZero; 

    // Create the composition of all videofiles 
    for (NSURL *url in outputFileUrlArray) { 
     AVAsset *asset = [[AVURLAsset alloc]initWithURL:url options:nil]; 
     [video setVideo:url at:localTimeline]; 
     localTimeline = CMTimeAdd(localTimeline, asset.duration); // Increment the timeline 
    } 
    [self exportVideo]; 
} 

और यहाँ VideoComposition वर्ग के मांस है:

-(id)initVideoTracks 
{ 
    if((self = [super init])) 
    { 
     composition = [[AVMutableComposition alloc] init]; 
     addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
     mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
     instructions = [[NSMutableArray alloc] init]; 
     videoComposition = [AVMutableVideoComposition videoComposition]; 
    } 
    return self; 
} 


-(void)setVideo:(NSURL*) url at:(CMTime)to 
{ 
    asset = [[AVURLAsset alloc]initWithURL:url options:nil]; 

    AVAssetTrack *assetTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 

    AVMutableCompositionTrack *compositionTrackVideo = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
    [compositionTrackVideo insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack: assetTrack atTime:to error:nil]; 

    AVMutableCompositionTrack *compositionTrackAudio = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
    [compositionTrackAudio insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack:[[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:to error:nil]; 

    mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeAdd(to, asset.duration)); 

    AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionTrackVideo]; 

    [layerInstruction setTransform: assetTrack.preferredTransform atTime: kCMTimeZero]; 
    [layerInstruction setOpacity:0.0 atTime:CMTimeAdd(to, asset.duration)]; 
    [instructions addObject:layerInstruction]; 

    mainInstruction.layerInstructions = instructions; 
    videoComposition.instructions = [NSArray arrayWithObject:mainInstruction]; 
    videoComposition.frameDuration = CMTimeMake(1, 30); 
} 

उत्तर

2

मैं भी सामना करना पड़ा इसी तरह की समस्या। मैंने संरचना में परिसंपत्तियों को सम्मिलित करके इसे ठीक करने में कामयाब रहा है, म्यूटेबल ट्रैक में ट्रैक नहीं किया है। तो, बजाय इस लाइन की "SetVideo" के लिए अपने कोड में:

[compositionTrackVideo insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack: assetTrack atTime:to error:nil]; 

इस प्रयास करें:

[self insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofAsset:asset atTime:to error:nil] 
+1

अच्छा, मुझे लगता है कि मुझे इसे आजमाने की ज़रूरत है। मैंने पहले से ही प्रत्येक रिकॉर्डिंग (पृष्ठभूमि में) के बाद एक रचना करके समस्या को बाधित कर दिया है, इसलिए दो से अधिक वीडियो वास्तव में कभी भी मिश्रित नहीं होते हैं। – Karvapallo

+0

मैं वास्तव में यह काम नहीं कर सका। शायद इस दृष्टिकोण के साथ परिवर्तनों को अलग-अलग लागू किया जाना चाहिए (या वे काम नहीं करेंगे)। क्या आपके पास कुछ उदाहरण कोड मौजूद होगा? – Karvapallo

+0

हाल ही में हमारे प्रोजेक्ट में बनाए गए कोड को AVCompositionTrackSegment का उपयोग करके पुनः लिखा गया था। हम ट्रैक सेगमेंट की एक सरणी बनाते हैं, उन्हें सत्यापित करते हैं और AVMutableCompositionTrack के सेगमेंट गुणों को असाइन करते हैं। हम बहुत समय खींच रहे हैं/संपीड़न (वीडियो की गति बदल रहे हैं) और यह विधि अधिक सटीक संरचना प्रदान करती है। – Jeepston

7

ठीक है, मैं भी एप्पल इस मुद्दे के बारे से संपर्क किया और वे एक प्रतिक्रिया दी:

"यह एक ज्ञात स्थिति है। आप AVFoundation में डीकोडर सीमा सेट को मार रहे हैं।"

उन्होंने मुझे इस मुद्दे पर एक बग रिपोर्ट दर्ज करने के लिए भी कहा, क्योंकि AVAssetExportSession अगर अस्पष्ट और भ्रामक है तो त्रुटि संदेश देता है। तो मैंने इस तथ्य के बारे में शिकायत करने के लिए सेब को एक बग रिपोर्ट दायर की कि त्रुटि संदेश खराब है।

तो AVAssetExportSession में इन सीमाओं की पुष्टि की गई है। आईओएस 5 में डीकोडर सीमा 4 है और आईओएस 6 में इसे 16 तक बढ़ाया गया था। यहां मुख्य मुद्दा यह है कि AVAssetExportSession द्वारा रिपोर्ट की गई त्रुटि खराब है क्योंकि यह केवल रिपोर्ट करता है: 11820 वास्तव में हमें यह बताते हुए "निर्यात पूर्ण नहीं कर सकता" एक सीमा मारा।