2010-12-14 11 views
9

Sie können das Video mit AVFoundation oder UIImagePickerController aufnehmen. Aber ich kann das Video nicht von einer bestimmten Sekunde auf eine andere bestimmte Zeit/Zeit zuschneiden. Kann mir jemand helfen.So kürzen Sie das Video mit AVFoundation

Danke, Siva Krishna.

+0

diese Frage gefunden, während der Suche nach etwas ein vorhandenes Video zu trimmen. Trimmen von aufgenommenen Videos ist relativ einfach. Aber es scheint mir zu entgehen, dass das Trim-Fenster erscheint. Ich hoffe meine Antwort unten hilft. –

Antwort

18

können Sie haben die UIImagePickerController

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; 

Leider Trimmen aktivieren, nachdem Sie wieder von der imagePickerController bekommen, sind Sie gezwungen, das Video manuell zu konvertieren.

-(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

Danke für die Quelle. Wenn ich "* sourceTypes" als "UIImagePickerControllerSourceTypeCamera" verwende, bekomme ich "* start and * end time". Aber wenn ich "* sourceTypes" als "UIImagePickerControllerSourceTypeSavedPhotosAlbum" verwende, bekomme ich keine "Anfangs- und Endzeit". Was ist das Problem? Wie kann ich die "Start- und Endzeit" bekommen? – SKK

+0

Haben Sie ihnen die Möglichkeit gegeben, das Video zu "schneiden"? Der Abschnitt, der den Anfang und das Ende der Bearbeitung füllt, ist der Ausschnitt. Wenn Sie das Video nicht abschneiden, bleiben diese Werte gleich Null, was wiederum bedeutet, dass der Ausschnitt übersprungen werden sollte und das gesamte Video verwendet werden sollte. –

+0

Bitte beachten Sie das Protokoll hier http://pastebin.com/uMU1k61T. Ich erlaube dem Benutzer, die Bilder aus dem Miniaturbild auszuwählen. Kein Problem, wenn ich das "Camera recorded video" bearbeite und das Problem passiert, wenn ich versuche, die Frames aus den geladenen Videos aus dem Album auszuwählen. – SKK

0

Sie sollten KUTTypeMovie in der SetMediaTypes-Array hinzufügen und es wird funktionieren.

2

Swift-Version von oben

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

danke frnd diese Methode hat wie erwartet funktioniert ... –

Verwandte Themen