2010-12-14 13 views
9

Mogę nagrać wideo przy użyciu AVFoundation lub UIImagePickerController. Ale nie jestem w stanie przyciąć filmu z jednej konkretnej sekundy do innego określonego czasu/czasu. Czy ktoś może mi pomóc.Jak przyciąć wideo za pomocą AVFoundation

Dzięki, Śiwa Kryszna.

+0

Znalazłem to pytanie, patrząc na coś do wykończenia istniejący film. Przycinanie przechwyconych filmów jest stosunkowo proste. Ale pojawienie się okna Trim wydaje mi się nie na miejscu. Mam nadzieję, że moja odpowiedź poniżej pomoże. –

Odpowiedz

18

Można mieć UIImagePickerController umożliwiają przycinanie

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; 

Niestety po powrocie z imagePickerController, jesteś zmuszony ręcznie konwertować wideo.

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

Dzięki za źródło. Kiedy używam "* sourceTypes" jako "UIImagePickerControllerSourceTypeCamera", otrzymuję "* czas rozpoczęcia i * zakończenia". Ale kiedy używam "* sourceTypes" jako "UIImagePickerControllerSourceTypeSavedPhotosAlbum", nie otrzymuję czasu "rozpoczęcia i zakończenia". Jaki jest problem? Jak mogę uzyskać czas "rozpoczęcia i zakończenia"? – SKK

+0

Czy dałeś im możliwość "Klipowania" wideo? Część, która wypełnia początek i koniec edycji, jest wycinkiem. Jeśli nie klip wideo, te wartości są zerowe, co z kolei oznacza, że ​​wycinek należy pominąć i cały film powinien być używany. –

+0

Proszę odnieść się do dziennika tutaj http://pastebin.com/uMU1k61T. Pozwalam użytkownikowi wybrać klatki z miniatury. Nie ma problemu, jeśli edytuję "nagrane wideo z kamery", a problem pojawi się, gdy spróbuję wybrać klatki z filmów załadowanych z albumu. – SKK

0

powinieneś dodać kUTTypeMovie do tablicy setMediaTypes i zadziała.

2

Swift wersja powyżej

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

dzięki frnd ta metoda działała zgodnie z oczekiwaniami ... –

Powiązane problemy