2011-08-02 100 views
24

我使用下面的代碼捕獲視頻:如何保存視頻文件到文件目錄

UIImagePickerController *ipc = [[UIImagePickerController alloc] init]; 
ipc.sourceType = UIImagePickerControllerSourceTypeCamera; 
ipc.delegate = self; 
//need to handle delegates methods 
// 
ipc.allowsEditing = YES; 
ipc.videoQuality = UIImagePickerControllerQualityTypeMedium; 
ipc.videoMaximumDuration = 30.0f; // 30 seconds 
//temporary duation of 30 seconds for testing 

ipc.mediaTypes = [NSArray arrayWithObject:@"public.movie"]; 
// ipc.mediaTypes = [NSArray arrayWithObjects:@"public.movie", @"public.image", nil]; 
[self presentModalViewController:ipc animated:YES]; 
//this controller allows to record the videos 

,我可以使用保存錄制的視頻專輯下面的代碼

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{ 
    // recover video URL 
    NSURL *url = [info objectForKey:UIImagePickerControllerMediaURL]; 

    // check if video is compatible with album 
    BOOL compatible = UIVideoAtPathIsCompatibleWithSavedPhotosAlbum([url path]); 

    // save 
    if (compatible){ 
     UISaveVideoAtPathToSavedPhotosAlbum([url path], self, @selector(video:didFinishSavingWithError:contextInfo:), NULL); 
     NSLog(@"saved!!!! %@",[url path]); 
    } 
    [self dismissModalViewControllerAnimated:YES]; 
    [picker release]; 
} 

,但我需要檢索文件從相冊並需要存儲到文件目錄?

+1

你有沒有找到解決辦法,將做好每一件事? –

回答

29

保存視頻文件目錄如下:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 

    NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL]; 
    NSData *videoData = [NSData dataWithContentsOfURL:videoURL]; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *tempPath = [documentsDirectory stringByAppendingFormat:@"/vid1.mp4"]; 
    BOOL success = [videoData writeToFile:tempPath atomically:NO]; 
    [picker dismissModalViewControllerAnimated:YES]; 
} 
+2

爲什麼爲[videoData writeToFile:tempPath atomically:NO]自動設置爲NO? – zakdances

+0

我也有跟進問題。有沒有辦法保存視頻,但沒有任何壓縮?即按原樣複製視頻文件。 – Jonny

+0

這適用於我。 –

4
#pragma mark - 
#pragma mark File Names and Paths 
// Creates the path if it does not exist. 
- (void)ensurePathAt:(NSString *)path { 
    NSFileManager *fm = [NSFileManager defaultManager]; 
    if ([fm fileExistsAtPath:path] == false) { 
     [fm createDirectoryAtPath:path 
     withIntermediateDirectories:YES 
         attributes:nil 
          error:NULL]; 
    } 
} 
- (NSString *)documentPath { 
    if (! documentPath_) { 
     NSArray *searchPaths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     documentPath_ = [searchPaths objectAtIndex: 0]; 
     documentPath_=[documentPath_ stringByAppendingPathComponent:@"VideoAlbum"]; 
     [documentPath_ retain]; 
    } 
    return documentPath_; 
} 

- (NSString *)audioPath { 
    if (! AudioPath_) { 
     AudioPath_ = [[self documentPath] stringByAppendingPathComponent:@"Demo"]; 
     NSLog(@"%@",AudioPath_); 
     [AudioPath_ retain]; 
     [self ensurePathAt:AudioPath_]; 
    } 
    return AudioPath_; 
} 
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{ 
    NSString *type = [info objectForKey:UIImagePickerControllerMediaType]; 

    if ([type isEqualToString:(NSString *)kUTTypeVideo] || [type isEqualToString:(NSString *)kUTTypeMovie]) 
    { 
     NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL]; 

     NSData *videoData = [NSData dataWithContentsOfURL:videoURL]; 
     tempPath = [[self audioPath] stringByAppendingFormat:@"/%@.mp4",[NSDate date]]; 
     BOOL success = [videoData writeToFile:tempPath atomically:NO]; 

     NSLog(@"%hhd",success); 
    } 
    [[picker presentingViewController] dismissViewControllerAnimated:YES completion:nil]; 
} 
0
videoUrl = [info objectForKey:UIImagePickerControllerMediaURL]; 
urlString=[urlvideo path]; 
NSLog(@"path url %@",videoUrl); 
NSData *videoData = [NSData dataWithContentsOfURL:videoUrl]; 
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *sourcePath = [documentsDirectory stringByAppendingPathComponent:@"yourfilename.mp4"]; 

[videoData writeToFile:sourcePath atomically:YES]; 
//Below code will save video to iOS Device 
ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init]; 
[library writeVideoAtPathToSavedPhotosAlbum:videoUrl 
          completionBlock:^(NSURL *assetURL, NSError *error){/*notify of completion*/}]; 

[picker dismissViewControllerAnimated:YES completion:nil]; 

希望這有助於

2

我們可以使用的NSFileManager的moveItemAtPath:toPath:error:方法將視頻文件移動到我們的應用程序的文件目錄。它更高效。

此外,我們應該得到視頻文件的擴展名,並將其用作我們本地視頻文件名的擴展名。

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{ 
    [self dismissViewControllerAnimated:YES completion:nil] ; 

    if ([info[UIImagePickerControllerMediaType] isEqualToString:(NSString *)kUTTypeMovie]) { 
     // video 
     NSURL *url = [info[UIImagePickerControllerMediaType] ; 
     NSString *filePath = [url path] ; 
     NSString *pathExtension = [filePath pathExtension] ; 
     if ([pathExtension length] > 0) { 
      NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) ; 
      NSString *documentsDirectory = [paths objectAtIndex:0] ; 
      NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"temp.%@", pathExtension]] ; 
      NSError *error = nil ; 
      BOOL res = [[NSFileManager defaultManager] moveItemAtPath:filePath toPath:localFilePath error:&error] ; 
      if (!res) { 
       NSLog(@"%@", [error localizedDescription]) ; 
      } 
     } 
    } 
} 

它適用於我。

+0

好,對我也很好。更新雨燕4.0: 讓pathExtension = videoPath.pathExtension 如果pathExtension.isEmpty, 讓documentsDirectory = FileManager.default.urls(爲:.documentDirectory在:.userDomainMask)!。首先{ 讓LOCALFILE = documentsDirectory.appendingPathComponent( 「temp。\(pathExtension)」)。path do嘗試FileManager.default.moveItem(atPath:videoPath.path,toPath:localFile) } catch { print(「Can not move the video \(error)」) } } – Tony

3

[R & d的位,這個工作對我來說

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 

{

NSURL *url = [info objectForKey:UIImagePickerControllerMediaURL]; 
    // Save video to app document directory 

NSString *filePath = [url path]; 
NSString *pathExtension = [filePath pathExtension] ; 
if ([pathExtension length] > 0) 
{ 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) ; 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 

    NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", [filePath lastPathComponent]]]; 

    // Method last path component is used here, so that each video saved will get different name. 

    NSError *error = nil ; 
    BOOL res = [[NSFileManager defaultManager] moveItemAtPath:filePath toPath:localFilePath error:&error] ; 

    if (!res) 
    { 
     NSLog(@"%@", [error localizedDescription]) ; 
    } 
    else 
    { 
     NSLog(@"File saved at : %@",localFilePath); 
    } 
} 

}

//此外,當您需要檢查相同的視頻已經應用文檔中存在目錄,你不想創建它的多個副本,然後作出如下更改

NSURL *url = [info objectForKey:UIImagePickerControllerMediaURL]; 
NSURL *videoAsset = [info objectForKey:UIImagePickerControllerReferenceURL]; 

__weak typeof(self) weakSelf = self; 

ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 
[library assetForURL:videoAsset resultBlock:^(ALAsset *asset) 
{ 
    weakSelf.selectedFileName = [[asset defaultRepresentation] filename]; 
    NSLog(@"Video Filename %@",weakSelf.selectedFileName); 

    // Save video to doc directory 
    NSString *filePath = [url path]; 
    NSString *pathExtension = [filePath pathExtension] ; 
    if ([pathExtension length] > 0) 
    { 
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) ; 
     NSString *documentsDirectory = [paths objectAtIndex:0]; 

     NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", weakSelf.selectedFileName]]; 

     //check if same video is having its copy in app directory. 
     //so that multiple entries of same file should not happen. 

     BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:localFilePath]; 

     if (!fileExists) 
     { 
      NSError *error = nil ; 

      BOOL res = [[NSFileManager defaultManager] moveItemAtPath:filePath toPath:localFilePath error:&error] ; 

      if (!res) 
      { 
       NSLog(@"%@", [error localizedDescription]) ; 
      } 
      else 
      { 
       NSLog(@"File saved at : %@",localFilePath); 
       weakSelf.filePathURL = [NSURL URLWithString:localFilePath]; 
      } 
     } 
     else 
     { 
      NSLog(@"File exist at : %@",localFilePath); 
      weakSelf.filePathURL = [NSURL URLWithString:localFilePath]; 
     } 

    } 
} 

}

//其中weakSelf.selectedFileName & weakSelf.filePathURL分別是我班的NSString和NSURL類型的屬性。

+0

唉,我相信ALAssetsLibrary已被棄用。需要PHPhoto,methinks。 –

8

這裏是SWIFT代碼,如果有人需要它的未來:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) { 

    let videoURL = info[UIImagePickerControllerMediaURL] as! NSURL 
    let videoData = NSData(contentsOfURL: videoURL) 
    let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true) 
    let documentsDirectory: AnyObject = paths[0] 
    let dataPath = documentsDirectory.stringByAppendingPathComponent("/vid1.mp4") 

    videoData?.writeToFile(dataPath, atomically: false) 
    self.dismissViewControllerAnimated(true, completion: nil) 

} 
+0

您也可以指定paths.first,其優點是如果列表長度爲零,則不會失敗。 –

0
videoURL = info[UIImagePickerControllerMediaURL]as? NSURL 
    print(videoURL!) 

    let urlData=NSData(contentsOf: videoURL as! URL) 

    if((urlData) != nil) 
    { 
     let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) 
     let documentDirectory = path.first! as NSString 
     let fileName = "Video.MOV" 
     let PDFPathFileName = documentDirectory.appendingPathComponent(fileName as String) 

     print(PDFPathFileName) 

     DispatchQueue.main.async(execute: { 
      urlData?.write(toFile: PDFPathFileName, atomically: true) 
     }) 

     do { 
      let asset = AVURLAsset(url: videoURL as! URL , options: nil) 
      let imgGenerator = AVAssetImageGenerator(asset: asset) 
      imgGenerator.appliesPreferredTrackTransform = true 
      let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(0, 1), actualTime: nil) 
      let thumbnail = UIImage(cgImage: cgImage) 
      imgView.image = thumbnail 
      // thumbnail here 

     } catch let error { 
      print("*** Error generating thumbnail: \(error.localizedDescription)") 
     } 

    } 
    self.dismiss(animated: true, completion: nil) 
0

斯威夫特3/4

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { 
     // recover video URL 
     let url = info[UIImagePickerControllerMediaURL] as? URL 
     // check if video is compatible with album 
     let compatible: Bool = UIVideoAtPathIsCompatibleWithSavedPhotosAlbum((url?.path)!) 
     // save 
     if compatible { 
      UISaveVideoAtPathToSavedPhotosAlbum((url?.path)!, self, nil, nil) 
      print("saved!!!! \(String(describing: url?.path))") 
     } 
     dismiss(animated: true, completion: nil) 
    } 
// error 
    func video(_ videoPath: String, didFinishSavingWithError error: Error?, contextInfo: UnsafeMutableRawPointer) { 
    } 

節省例如路徑: -

"/private/var/mobile/Containers/Data/Application/EA53C844-7931-446C-800D-DA90717426BB/tmp/xxxxxx.MOV" 
0

只需要調用這個函數,併爲你:)

private func saveVideo(url:URL) { 
    DispatchQueue.global(qos: .userInitiated).async { 
     guard let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return } 
     if !FileManager.default.fileExists(atPath: documentsDirectoryURL.appendingPathComponent(url.lastPathComponent).path) { 
      URLSession.shared.downloadTask(with: url) { (location, response, error) -> Void in 
       guard let location = location else { return } 
       let destinationURL = documentsDirectoryURL.appendingPathComponent(response?.suggestedFilename ?? url.lastPathComponent) 

       do { 
        try FileManager.default.moveItem(at: location, to: destinationURL) 
        PHPhotoLibrary.requestAuthorization({ (authorizationStatus: PHAuthorizationStatus) -> Void in 
         if authorizationStatus == .authorized { 
          PHPhotoLibrary.shared().performChanges({ 
           PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: destinationURL)}) { completed, error in 
            DispatchQueue.main.async { 
             if completed { 
              self.view.makeToast(NSLocalizedString("Video Saved!", comment: "Video Saved!"), duration: 3.0, position: .center) 
             } else { 
              print(error!) 
             } 
            } 
          } 
         } 
        }) 
       } catch { print(error) } 

       }.resume() 
     } else { 
      print("File already exists at destination url") 
     } 
    } 
}