2010-12-14 64 views
9

Iam能够使用AVFoundation或UIImagePickerController记录视频。但我无法将视频从一秒钟调整到另一段时间。谁能帮我。如何使用AVFoundation修剪视频

谢谢, 西瓦克里希纳。

+0

斯威夫特版本发现了这个问题。修剪捕捉的视频相对简单。但让修剪窗口出现似乎没有我。我希望我的回答如下。 – 2011-08-21 22:37:32

回答

18

你可以拥有的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; 

你从imagePickerController回来后,不幸的是,你不得不视频手动转换。

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

感谢您的来源。当我使用“* sourceTypes”作为“UIImagePickerControllerSourceTypeCamera”时,我得到“*开始和*结束时间”。但是当我使用“* sourceTypes”作为“UIImagePickerControllerSourceTypeSavedPhotosAlbum”时,我没有得到“开始和结束”时间。问题是什么?我如何获得“开始和结束”时间? – SKK 2013-09-30 11:45:59

+0

你有没有给他们“剪辑”视频的能力?填充编辑开始和结束的部分是裁剪。如果你不剪辑视频,那么这些值保留为零,这意味着剪辑应该被跳过并且应该使用整个视频。 – 2013-09-30 16:44:04

+0

请参阅这里的日志http://pastebin.com/uMU1k61T。我允许用户从缩略图中选择帧。没问题,如果我编辑“相机录制的视频”,并且当我尝试从专辑中加载的视频中选择帧时问题就会发生。 – SKK 2013-10-01 09:47:29

0

你应该在setMediaTypes数组中添加kUTTypeMovie,它会起作用。而寻找的东西修剪现有的视频

2

以上

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

谢谢frnd此方法按预期工作... – 2016-03-01 06:31:59