简体   繁体   English

我们如何将视频文件从库复制到文档目录?

[英]How can we copy a video file from library to documents directory?

Is it possible to copy a video file located at iOS photo library to our application's documents directory? 是否可以将位于iOS照片库的视频文件复制到我们应用程序的文档目录中? I tried it using uiimagepickercontroller from where we get the NSUrl of the video file, then converting it into NSData and then writing it into the file. 我尝试使用uiimagepickercontroller从中获取视频文件的NSUrl,然后将其转换为NSData,然后将其写入文件。 But unfortunately it is not working. 但不幸的是它没有用。 I there any alternate method? 我还有其他方法吗?

My intention is to load the video to OpenCV CvCapture. 我的目的是将视频加载到OpenCV CvCapture。

Hey Isarathg this is classic use case of IOS devices. 嘿Isarathg这是IOS设备的经典用例。 Which don't let you access any Photo Album assets directly using path value. 哪个版本不允许您直接使用路径值访问任何相册资产。 To cross check my answer please just check FileExistsAtPath for your file like below -: 要交叉检查我的答案,请检查FileExistsAtPath以获取您的文件,如下所示:

println(NSFileManager.defaultManager().fileExistsAtPath( urlvalue.path!))

O/P you will get => False

I also end up with this issue couple of days back After reading the whole IOS documentation. 几天后我也回到了这个问题。阅读完整的IOS文档后。 What I have figured it out "We can only access PhotoAlbum Assets if and only if we have PHImageManager session open". 我已经弄明白了“当且仅当我们打开PHImageManager会话时,我们才能访问PhotoAlbum资产”。 To cross check this statement please try below code -: 要交叉检查此声明,请尝试以下代码 - :

var currentVideofetch: PHFetchResult!
required init(coder aDecoder: NSCoder) {
    let options = PHFetchOptions()
    options.sortDescriptors = [
        NSSortDescriptor(key: "creationDate", ascending: true)
    ]
    currentVideofetch = PHAsset.fetchAssetsWithMediaType(.Video, options: options)
    super.init(coder: aDecoder)
}
func checkImageExists(){
let asset = self.currentVideofetch.objectAtIndex(1) as? PHAsset
}
if let checkedAsset = asset {
        PHImageManager.defaultManager().requestAVAssetForVideo(checkedAsset, options: nil, resultHandler: {[weak self](result: AVAsset!, audioMix: AVAudioMix!, info: [NSObject : AnyObject]!) in
            println(NSFileManager.defaultManager().fileExistsAtPath(self.urlvalue.path!))
            })
    }
O/P you will get => True

After opening the PHImageManager session and then when i tried accessing the video with the path. 打开PHImageManager会话后,当我尝试使用路径访问视频时。 It worked fine. 它工作正常。 Also able to successfully copy all videos files to our local app directory using the relative path of videos in Photo Album. 还可以使用相册中视频的相对路径将所有视频文件成功复制到我们的本地应用程序目录。

If you need i can send you my implementation for this. 如果你需要我可以发送给你我的实现。 But not sure if it is correct way or not. 但不确定它是否正确。 But working fine for me. 但对我来说工作正常。

Second and most effective solution i found is using 我发现的第二个也是最有效的解决方案就是使

AVAssetExportSession AVAssetExportSession

It works like a charm. 它就像一个魅力。 My implementation is as follows -: 我的实现如下 - :

func importVideoToAppDir(videoURL: NSURL, videoFinalPath: NSURL, handler: ((NSURL?) -> Void)?) {

    var assetDuration:  CMTime!
    var asset: AVAsset!

    asset = AVAsset.assetWithURL(videoURL) as! AVAsset
    assetDuration = asset!.duration
    if (DirOperations.DeleteIfExists(videoTempPath) &&  DirOperations.DeleteIfExists(videoFinalPath)) {
        let startTime = kCMTimeZero
        let assetDurationSeconds = CMTimeGetSeconds(self.asset!.duration)
        var range: CMTimeRange!
        if assetDurationSeconds > Float64(maxDuration) {
            let stopTime = CMTimeMakeWithSeconds(Float64(maxDuration), 1)
            range = CMTimeRangeFromTimeToTime(startTime, stopTime)
            } else {
                let stopTime = CMTimeMakeWithSeconds(assetDurationSeconds, 1)
                range = CMTimeRangeFromTimeToTime(startTime, stopTime)
            }
            var exporter :AVAssetExportSession = AVAssetExportSession(asset: self.asset, presetName: AVAssetExportPresetHighestQuality)
            exporter.outputURL = videoFinalPath
            exporter.outputFileType = AVFileTypeQuickTimeMovie
            exporter.timeRange = range
            exporter.exportAsynchronouslyWithCompletionHandler { () -> Void in
                switch exporter.status {
                    case  AVAssetExportSessionStatus.Failed:
                    println("failed import video: \(exporter.error)")
                    handler?(nil)
                    case AVAssetExportSessionStatus.Cancelled:
                    println("cancelled import video: \(exporter.error)")
                    handler?(nil)
                    default:
                    println("completed import video")
                    println(videoFinalPath)
                    handler?(videoFinalPath)

                }
            }
    }
}

   func DeleteIfExists(path: NSURL) -> Bool {
        var deleted = true
        var error: NSError?
        if (NSFileManager.defaultManager().fileExistsAtPath(path.path!)) {
            deleted = NSFileManager.defaultManager().removeItemAtPath(path.path!, error: &error)
        }
        return deleted
    }

Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM