2010-12-14 11 views
9

Iam è in grado di registrare il video utilizzando AVFoundation o UIImagePickerController. Ma non sono in grado di tagliare il video da un particolare secondo ad un altro particolare durata/tempo. Qualcuno può aiutarmi.Come tagliare il video utilizzando AVFoundation

Grazie, Siva Krishna.

+0

Trovato questa domanda mentre alla ricerca di qualcosa di tagliare un video esistente. Ritagliare i video catturati è relativamente semplice. Ma far apparire quella finestra Trim sembra sfuggirmi. Spero che la mia risposta qui sotto aiuti. –

risposta

18

Si può avere l'abilitazione UIImagePickerController rifilatura

UIImagePickerController *videoRecorder = [[UIImagePickerController alloc]init];   
     NSArray *sourceTypes = [UIImagePickerController availableMediaTypesForSourceType:videoRecorder.sourceType]; 
     NSLog(@"Available types for source as camera = %@", sourceTypes); 
     if (![sourceTypes containsObject:(NSString*)kUTTypeMovie]) { 
      UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil 
                  message:@"Device Not Supported for video Recording."                  delegate:self 
                cancelButtonTitle:@"Yes" 
                otherButtonTitles:@"No",nil]; 
      [alert show]; 
      [alert release]; 
      return; 
     } 
     videoRecorder.allowsEditing = YES; 

Purtroppo dopo si torna dalla imagePickerController, si è costretti a convertire il video manualmente.

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{ 
    if ([self.popoverLibraryBrowser isPopoverVisible]) 
    { 
     [self.popoverLibraryBrowser dismissPopoverAnimated:YES]; 
    } 
    NSString *type = [info objectForKey:UIImagePickerControllerMediaType]; 
    if ([type isEqualToString:(NSString *)kUTTypeVideo] || 
     [type isEqualToString:(NSString *)kUTTypeMovie]) { // movie != video 
     NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL]; 


     NSNumber *start = [info objectForKey:@"_UIImagePickerControllerVideoEditingStart"]; 
     NSNumber *end = [info objectForKey:@"_UIImagePickerControllerVideoEditingEnd"]; 

     // if start and end are nil then clipping was not used. 
     // You should use the entire video. 


     int startMilliseconds = ([start doubleValue] * 1000); 
     int endMilliseconds = ([end doubleValue] * 1000); 

     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     NSString *documentsDirectory = [paths objectAtIndex:0]; 

     NSFileManager *manager = [NSFileManager defaultManager]; 

     NSString *outputURL = [documentsDirectory stringByAppendingPathComponent:@"output"] ; 
     [manager createDirectoryAtPath:outputURL withIntermediateDirectories:YES attributes:nil error:nil]; 

     outputURL = [outputURL stringByAppendingPathComponent:@"output.mp4"]; 
     // Remove Existing File 
     [manager removeItemAtPath:outputURL error:nil]; 


     //[self loadAssetFromFile:videoURL]; 

     [self.recorder dismissModalViewControllerAnimated:YES]; 

     AVURLAsset *videoAsset = [AVURLAsset URLAssetWithURL:videoURL options:nil]; 


     AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:videoAsset presetName:AVAssetExportPresetHighestQuality]; 
     exportSession.outputURL = [NSURL fileURLWithPath:outputURL]; 
     exportSession.outputFileType = AVFileTypeQuickTimeMovie; 
     CMTimeRange timeRange = CMTimeRangeMake(CMTimeMake(startMilliseconds, 1000), CMTimeMake(endMilliseconds - startMilliseconds, 1000)); 
     exportSession.timeRange = timeRange; 

     [exportSession exportAsynchronouslyWithCompletionHandler:^{ 
      switch (exportSession.status) { 
       case AVAssetExportSessionStatusCompleted: 
        // Custom method to import the Exported Video 
        [self loadAssetFromFile:exportSession.outputURL]; 
        break; 
       case AVAssetExportSessionStatusFailed: 
        // 
        NSLog(@"Failed:%@",exportSession.error); 
        break; 
       case AVAssetExportSessionStatusCancelled: 
        // 
        NSLog(@"Canceled:%@",exportSession.error); 
        break; 
       default: 
        break; 
      } 
     }]; 



     //NSData *videoData = [NSData dataWithContentsOfURL:videoURL]; 
     //NSString *videoStoragePath;//Set your video storage path to this variable 
     //[videoData writeToFile:videoStoragePath atomically:YES]; 
     //You can store the path of the saved video file in sqlite/coredata here. 
    } 
} 
+0

Grazie per la fonte. Quando uso "* sourceTypes" come "UIImagePickerControllerSourceTypeCamera", sto ricevendo "* start e * end time". Ma quando uso "* sourceTypes" come "UIImagePickerControllerSourceTypeSavedPhotosAlbum", non ricevo il tempo di "inizio e fine". Qual è il problema? Come posso ottenere il tempo "inizio e fine"? – SKK

+0

Hai dato loro la possibilità di "ritagliare" il video? La parte che popola l'inizio e la fine del montaggio è il ritaglio. Se non si ritaglia il video, questi valori vengono lasciati nulli, il che a sua volta significa che il ritaglio deve essere saltato e l'intero video deve essere utilizzato. –

+0

Fare riferimento al registro qui http://pastebin.com/uMU1k61T. Sto permettendo all'utente di selezionare i fotogrammi dalla miniatura. Nessun problema, se modifico il "Video registrato dalla videocamera" e il problema si verifica quando provo a selezionare i frame dai video caricati dall'album. – SKK

0

si dovrebbe aggiungere kUTTypeMovie nella matrice setMediaTypes e funzionerà.

2

versione Swift di sopra

import UIKit 
import AVFoundation 
import MobileCoreServices 

func pickVideo(){ 
    if UIImagePickerController.isSourceTypeAvailable(.Camera) { 
     let videoRecorder = UIImagePickerController() 
     videoRecorder.sourceType = .Camera 
     videoRecorder.mediaTypes = [kUTTypeMovie as String] 
     videoRecorder.allowsEditing = true 
     videoRecorder.delegate = self 

     presentViewController(videoRecorder, animated: true, completion: nil) 
    } 
} 


func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { 
    picker.dismissViewControllerAnimated(true, completion: nil) 
    let manager = NSFileManager.defaultManager() 

    guard let documentDirectory = try? manager.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true) else {return} 
    guard let mediaType = info[UIImagePickerControllerMediaType] as? String else {return} 
    guard let url = info[UIImagePickerControllerMediaURL] as? NSURL else {return} 

    if mediaType == kUTTypeMovie as String || mediaType == kUTTypeVideo as String { 
     let asset = AVAsset(URL: url) 
     let length = Float(asset.duration.value)/Float(asset.duration.timescale) 
     print("video length: \(length) seconds") 

     let start = info["_UIImagePickerControllerVideoEditingStart"] as? Float 
     let end = info["_UIImagePickerControllerVideoEditingEnd"] as? Float 


     var outputURL = documentDirectory.URLByAppendingPathComponent("output") 


     do { 
      try manager.createDirectoryAtURL(outputURL, withIntermediateDirectories: true, attributes: nil) 
      outputURL = outputURL.URLByAppendingPathComponent("output.mp4") 
     }catch let error { 
      print(error) 
     } 

     //Remove existing file 
     _ = try? manager.removeItemAtURL(outputURL) 


     guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality) else {return} 
     exportSession.outputURL = outputURL 
     exportSession.outputFileType = AVFileTypeMPEG4 

     let startTime = CMTime(seconds: Double(start ?? 0), preferredTimescale: 1000) 
     let endTime = CMTime(seconds: Double(end ?? length), preferredTimescale: 1000) 
     let timeRange = CMTimeRange(start: startTime, end: endTime) 

     exportSession.timeRange = timeRange 
     exportSession.exportAsynchronouslyWithCompletionHandler{ 
      switch exportSession.status { 
      case .Completed: 
       print("exported at \(outputURL)") 

      case .Failed: 
       print("failed \(exportSession.error)") 

      case .Cancelled: 
       print("cancelled \(exportSession.error)") 

      default: break 
      } 
     } 
    } 
} 
+0

grazie questo metodo ha funzionato come previsto ... –

Problemi correlati