I'm using the UIImagePicker to pick only videos from my library and I set my media type to:
imagePicker.mediaTypes = [kUTTypeMovie as String]
I noticed that when the library is presented, even though I expect only videos, if there is a live photo in the library with a Bounce
or Loop
effect, it shows up also. If I take that same photo and switch it's effect to Live
or Long Exposure
it will no longer show up in the library. If I switch it back to Bounce
or Loop
it reappears.
I've tried both the .photoLibrary
and the .savedPhotosAlbum
and the same thing happens.
The reason I ask is because I want to keep them out of the library and I only want videos of xxx secs or more to be picked.
- Why do these effect types show up in the image picker library even though I'm picking video only?
- Why does only
Loop
andBounce
appear butLong Exposure
andLive
doesn't? - How do I keep them out?
Maybe this would be a separate question but since it pertains to the same Live
and Bounce
photo issue I added it. I noticed that if I put a url that was derived from a Live
or Bounce
photo inside an AVPlayer, if I go to the background and come back there is a brief freeze when the app is back in the foreground, and it only happens with those 2 effects (which shouldn't be available). When the app goes to the background I remove the AVPlayerLayer correctly using this method Remove AVPlayerLayer but it's still briefly frozen (app is unresponsive) in the foreground when a url from those to effect types are initialized inside the player.
code:
import MobileCoreServices
import AVFoundation
class ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate{
var playerItem: AVPlayerItem?
var player: AVPlayer?
var playerLayer: AVPlayerLayer?
var currentPlayTime: CMTime?
let imagePicker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
imagePickerController.delegate = self
NotificationCenter.default.addObserver(self, selector: #selector(appHasEnteredBackground), name: Notification.Name.UIApplicationWillResignActive, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(appWillEnterForeground), name: Notification.Name.UIApplicationWillEnterForeground, object: nil)
}
override func viewDidLayoutSubviews() {
// I have a UIView Outlet for the AVPlayerLayer named viewForPlayerLayer.
guard let playerLayer = playerLayer else { return }
playerLayer.videoGravity = .resizeAspectFill
viewForPlayerLayer.layer.insertSublayer(playerLayer, at: 0)
playerLayer.frame = viewForPlayerLayer.bounds
playerLayer.masksToBounds = true
}
@IBAction fileprivate func showLibraryButtonTapped(_ sender: UIButton) {
imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary // .savedPhotosAlbum also tried
imagePicker.mediaTypes = [kUTTypeMovie as String]
imagePicker.videoMaximumDuration = 60
present(imagePicker, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let url = info[UIImagePickerControllerMediaURL] as? URL{
let asset = AVAsset(url: url)
playerItem = AVPlayerItem(asset: asset)
player = AVPlayer(playerItem: playerItem!)
playerLayer = AVPlayerLayer(player: player)
player?.play()
}
imagePicker.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
imagePicker.dismiss(animated: true, completion: nil)
}
@objc fileprivate func appHasEnteredBackground() {
currentPlayTime = player.currentTime()
if player.isPlaying{
player.pause()
}
playerLayer = nil
}
@objc fileprivate func appWillEnterForeground(){
if let player = player, let currentPlayTime = currentPlayTime{
playerLayer = AVPlayerLayer(player: player)
player.seek(to: currentPlayTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)
}
}
}