如何将视频文件保存到文档目录中

时间:2011-08-02 17:49:40

标签: ios objective-c iphone video

我正在使用以下代码捕获视频:

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];
}

但我需要从相册中检索该文件并需要存储到文档目录中吗?

9 个答案:

答案 0 :(得分:30)

将视频保存到文档目录如下:

- (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];
}

答案 1 :(得分:10)

如果有人在将来需要它,这是快速代码:

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)

}

答案 2 :(得分: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];
}

答案 3 :(得分: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);
    }
}

}

//当您必须检查app文档目录中是否存在相同的视频并且您不想创建它的多个副本时,请进行一些更改,如下所示

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类型属性。

答案 4 :(得分: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]) ;
            }
        }
    }
}

它对我有用。

答案 5 :(得分: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];

希望这个帮助

答案 6 :(得分: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)

答案 7 :(得分:0)

Swift 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"

答案 8 :(得分: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")
        }
    }
}