Hey Isarathg is a classic use case for iOS devices. Which does not allow you to directly access the assets of the photo album using the path value. To cross-check my answer, just check FileExistsAtPath for your file, as shown below:
println(NSFileManager.defaultManager().fileExistsAtPath( urlvalue.path!)) O/P you will get => False
I also finished this issue a couple of days ago. After reading all the iOS documentation. What do I understand? "We can only access PhotoAlbum objects if and only if we have a PHImageManager open session." To cross-check this expression, please try the 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 to access the video using the path. It worked fine. You can also successfully copy all the video files to our local application directory using the relative video path in the photo album.
If you need, I can send you my implementation for this. But not sure if this is correct or not. But for me this is normal.
The second and most effective solution I have found is using
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 this helps.