In my app, the user chooses a video from their library using the built-in UIImagePickerController
. I can retrieve the URL and play the chosen video. This works great.
However, I also want to be able to play the same video at a later time, after the user has quit and restarted the app, without the user having to reselect it with the picker. I cannot figure out a way to do this. I have tried to use both UIImagePickerControllerReferenceURL
and UIImagePickerControllerMediaURL
. They both work when I play the video immediately. I tried saving those URLs in userDefaults
, and retrieving them the next time that I run the app. I properly retrieve the URL, but the video does not play with AVPlayer. I expected this behavior for UIImagePickerControllerMediaURL
because that appears to be a temporary URL, but I did not expect this for UIImagePickerControllerReferenceURL
.
I have also tried using PHAsset.fetchAssets(withALAssetURLs: <#T##[URL]#>, options: <#T##PHFetchOptions?#>)
but this does not return any values.
How can I save a reference to the video, or the video itself for later use?
Thanks to the comments from AamirR and Max9xs on my question above, the solution that I chose to implement was to move the file from the TMP directory to the Documents directory. Then play the video from the Documents directory. This also avoids the problem of having the TMP directory fill up with videos every time that the user selects a new one using the imagePickerController.
The following code in the delegate function will move the file:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let mediaType = info[UIImagePickerControllerMediaType] as! String
if mediaType == (kUTTypeMovie as String) {
let TMPvideoURL = info[UIImagePickerControllerMediaURL] as! URL
let TMPvideoPath = TMPvideoURL.path
let manager = FileManager.default
let documentsDirectory = manager.urls(for: .documentDirectory, in: .userDomainMask).last!
let docVideoURL = documentsDirectory.appendingPathComponent("selectedLibraryVideo.mov")
let docVideoPath = docVideoURL.path
do {
if manager.fileExists(atPath: docVideoPath) {
try manager.removeItem(atPath: docVideoPath)
}
try manager.moveItem(atPath: TMPvideoPath, toPath: docVideoPath)
}
catch {
print(error)
}
}
photoLibraryPickerController?.dismiss(animated: false, completion: nil)
}
And then I can subsequently play the video through a reference to the file path in Documents folder. This works great.
let documentsDirectory = manager.urls(for: .documentDirectory, in: .userDomainMask).last!
let docVideoURL = documentsDirectory.appendingPathComponent("selectedLibraryVideo.mov")
let docVideoPath = docVideoURL.path