2015-09-27 8 views
8

कुछ वीडियो को एक साथ विलय करने और उन्हें एक फ़ाइल के रूप में निर्यात करने का प्रयास करने की कोशिश नहीं करता है, सबकुछ ट्यूटोरियल/उदाहरणों को देखने से सही लगता है, हालांकि मेरा AVAssetExportSession कभी पूरा नहीं होता है, और मेरी वीडियो फ़ाइल कभी निर्यात नहीं होती है , मुझे लगता है कि एक अंधेरे स्पष्ट त्रुटि के रूप में कोई मदद बहुत सराहना की जाएगी।विलय वीडियो लेकिन AVAssetExportSession कभी भी

नीचे समारोह जहां मैं पाश में वीडियो

टिप्पणी 'वीडियो' विलय एक सदस्य चर var videos = [AVAsset]() जो आबादी वाले हो जाता है (और यह मैं जाँच करता है) से पहले मर्ज कहा जाता है।

private func merge() 
{ 
    // Create AVMutableComposition to contain all AVMutableComposition tracks 
    var mix_composition = AVMutableComposition() 
    var total_time_seconds = 0.0 
    var tracks = [AVCompositionTrack]() 

    // Loop over videos and create tracks, keep incrementing total duration 
    for video in videos 
    { 
     // Create the composition track for this video 
     let track = mix_composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) 

     // Add video duration to total time 
     total_time_seconds = total_time_seconds + video.duration.seconds 

     // Add track to array of tracks 
     tracks.append(track) 

     // Add time range to track 
     do 
     { 
      try track.insertTimeRange(CMTimeRangeMake(kCMTimeZero, video.duration), ofTrack: video.tracksWithMediaType(AVMediaTypeVideo)[0], atTime: video.duration) 
     } 
     catch _ 
     { 
     } 
    } 

    // Set total time 
    let preferred_time_scale: Int32 = 600; 
    let total_time = CMTimeMakeWithSeconds(total_time_seconds, preferred_time_scale) 

    // Create main instrcution for video composition 
    let main_instruction = AVMutableVideoCompositionInstruction() 
    main_instruction.timeRange = CMTimeRangeMake(kCMTimeZero, total_time) 

    // Create array to hold instructions 
    var layer_instructions = [AVVideoCompositionLayerInstruction]() 

    // Ensure we have the same number of tracks as videos 
    if videos.count == tracks.count 
    { 
     // Loop number of videos and tracks 
     for var index = 0; index < videos.count; ++index 
     { 
      // Create compositioninstruction for each track 
      let instruction = videoCompositionInstructionForTrack(tracks[index], asset: videos[index]) 

      if(index == 0) 
      { 
       instruction.setOpacity(0.0, atTime: videos[index].duration) 
      } 

      // Add instruction to instructions array 
      layer_instructions.append(instruction) 
     } 
    } 

    // Set tack instructions to main instruction 
    main_instruction.layerInstructions = layer_instructions 
    let main_composition = AVMutableVideoComposition() 
    main_composition.instructions = [main_instruction] 
    main_composition.frameDuration = CMTimeMake(1, 30) 
    main_composition.renderSize = CGSize(width: UIScreen.mainScreen().bounds.width, height: UIScreen.mainScreen().bounds.height) 

    // Get path for Final video in the current project directory 
    let documents_url = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] 
    let final_url = documents_url.URLByAppendingPathComponent("TEST.mp4") 

    // Create AV Export Session 
    let exporter = AVAssetExportSession(asset: mix_composition, presetName: AVAssetExportPresetHighestQuality) 
    exporter!.outputURL = final_url 
    exporter!.outputFileType = AVFileTypeMPEG4 
    exporter!.shouldOptimizeForNetworkUse = true 
    exporter!.videoComposition = main_composition 

    // Perform the Export 
    exporter!.exportAsynchronouslyWithCompletionHandler() { 
     dispatch_async(dispatch_get_main_queue(), {() -> Void in 
      self.exportDidFinish(exporter!) 
     }) 
    } 
} 

नीचे exportDidFinished समारोह जो जब exportAsynchronouslyWithCompletionHandler कहा जाता है कहा जाता है पता चलता है। मैं इस समारोह के अंदर आता हूं लेकिन कुछ भी नहीं होता क्योंकि सत्र की स्थिति कभी नहीं पूरी होती है।

func exportDidFinish(session: AVAssetExportSession) 
{ 
    if session.status == AVAssetExportSessionStatus.Completed 
    { 
     let outputURL = session.outputURL 
     let library = ALAssetsLibrary() 
     if library.videoAtPathIsCompatibleWithSavedPhotosAlbum(outputURL) 
     { 
      library.writeVideoAtPathToSavedPhotosAlbum(outputURL, 
       completionBlock: { (assetURL:NSURL!, error:NSError!) -> Void in 
        if error != nil 
        { 
         let alert = UIAlertView(title: "Error", message: "Video Not Saved", delegate: nil, cancelButtonTitle: "OK") 
         alert.show() 

        } 
        else 
        { 
         let alert = UIAlertView(title: "Success", message: "Video Saved", delegate: nil, cancelButtonTitle: "OK") 
         alert.show() 
        } 
      }) 
     } 
    } 
} 

मुद्रित सत्र स्थिति से पता चला है कि यह 4 जो विफल रहा है था, इसलिए मैं session.error मुद्रित और यह मिल गया है, लेकिन मैं इसका क्या मतलब पर अनिश्चित हूँ, किसी भी मदद बहुत अच्छा होगा

Optional(Error Domain=AVFoundationErrorDomain Code=-11841 "Operation Stopped" UserInfo={NSLocalizedDescription=Operation Stopped, NSLocalizedFailureReason=The video could not be composed.}) 

उत्तर

3

यदि exportDidFinish कहा जाता है लेकिन कुछ भी नहीं होता है, तो आपके सत्र की स्थिति AVAssetExportSessionStatus.Completed नहीं है। यह AVAssetExportSessionStatus.Failed, या कुछ अन्य मूल्य हो सकता है। उन मानों की जांच करें और यदि यह विफल हो गया है तो अधिक जानकारी के लिए session.error संपत्ति जांचें।

EDIT: यदि आप एक वीडियो को दूसरे के बाद खेलना चाहते हैं, तो केवल एक AVMutableCompositionTrack बनाएं। प्रासंगिक परिवर्तनों के लिए नीचे देखें:

... 
    var mix_composition = AVMutableComposition() 

    // Create the composition track for the videos 
    let track = mix_composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) 

    //keep track of total time 
    var totalTime = kCMTimeZero 

    for video in videos 
    { 
     // Add time range to track 
     do 
     { 
      let videoTrack = video.tracksWithMediaType(AVMediaTypeVideo)[0] 
      let videoDuration = videoTrack.duration 
      let timeRange = CMTimeRangeMake(kCMTimeZero,videoDuration) 

      try track.insertTimeRange(timeRange, ofTrack: videoTrack, atTime: totalTime) 

      totalTime = CMTimeAdd(totalTime,videoDuration) 
     } 
     catch _ 
     { 
     } 
    } 

    // Create main instruction for video composition 
    let main_instruction = AVMutableVideoCompositionInstruction() 
    main_instruction.timeRange = CMTimeRangeMake(kCMTimeZero, totalTime) 

    // Create array to hold instructions 
    var layer_instructions = [AVVideoCompositionLayerInstruction]() 

    // Create layer instruction 
    let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: track) 

    // Add it to the array 
    layer_instructions.append(layerInstruction) 

    ... 

आप अपने रेंडर आकार को कुछ उचित समायोजित करना भी चाहेंगे। आपके वीडियो का आकार आपकी स्क्रीन का आकार नहीं हो सकता है।

+0

मैं वास्तव में स्थिति को मुद्रित मूल्य की जांच कैसे करूं लेकिन यह अभी कहा गया है कि "AVAssetExportSessionStatus" ' – AngryDuck

+0

प्रिंट (सत्र! .status.rawValue)। फिर प्रिंट करें (सत्र! आतंक) – jlw

+0

ठीक है तो यह स्थिति 4 थी जो असफल रहा, और मुझे यह त्रुटि मिली 'वैकल्पिक (त्रुटि डोमेन = AVFoundationErrorDomain कोड = -11841 "ऑपरेशन रोक दिया गया" UserInfo = {NSLocalizedDescription = ऑपरेशन रोक दिया गया, NSLocalizedFailureReason = वीडियो बनाया नहीं जा सका।}) ' – AngryDuck

संबंधित मुद्दे