为啥 imagePickerController.mediaTypes = [kUTTypeMovie as String] 包括实时照片作为反弹或循环效果作为视频?
Posted
技术标签:
【中文标题】为啥 imagePickerController.mediaTypes = [kUTTypeMovie as String] 包括实时照片作为反弹或循环效果作为视频?【英文标题】:Why is imagePickerController.mediaTypes = [kUTTypeMovie as String] including Live Photos as Bounce or Loop Effect as Video?为什么 imagePickerController.mediaTypes = [kUTTypeMovie as String] 包括实时照片作为反弹或循环效果作为视频? 【发布时间】:2018-03-21 18:06:13 【问题描述】:我正在使用 UIImagePicker 仅从我的库中挑选视频,并将媒体类型设置为:
imagePicker.mediaTypes = [kUTTypeMovie as String]
我注意到,当显示库时,即使我只希望看到视频,如果库中有 Bounce
或 Loop
效果的实时照片,它也会显示出来。如果我拍摄同一张照片并将其效果切换为Live
或Long Exposure
,它将不再出现在图书馆中。如果我将其切换回Bounce
或Loop
,它会重新出现。
.photoLibrary
和.savedPhotosAlbum
我都试过了,结果还是一样。
我问的原因是因为我想把它们排除在图书馆之外,我只想挑选 xxx 秒或更长的视频。
-
即使我只选择视频,为什么这些效果类型会显示在图像选择器库中?
为什么只出现
Loop
和Bounce
而Long Exposure
和Live
没有出现?
如何让它们远离?
也许这将是一个单独的问题,但由于它与 Live
和 Bounce
相同的照片问题我添加了它。我注意到,如果我将源自Live
或Bounce
照片的 url 放入 AVPlayer 中,如果我转到后台并返回,当应用程序返回前台时会出现短暂的冻结,并且仅发生在这 2 种效果(不应该可用)中。当应用程序进入后台时,我使用此方法Remove AVPlayerLayer 正确删除了 AVPlayerLayer,但当在播放器内部初始化来自这些效果类型的 url 时,它仍然在前台短暂冻结(应用程序无响应)。
代码:
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)
【问题讨论】:
@matt 嗨,这里有 2 个问题。 1. 如果这些实际上是照片,并且我只为视频选择 [kUTTypeMovie as String],为什么它们会出现在库中? 2. 如果我选择反弹或循环效果,它们会显示为视频,但如果我选择实时或长时间曝光,它们不会显示为视频。似乎即使它们是照片,Live and Bounce 效果也会将它们转换为视频 一如既往地感谢您的帮助! 【参考方案1】:如果您要求显示视频,则无法阻止循环/反弹实时照片视频出现在选择器中,因为它们是视频。但是,如果用户选择一个,您可以在委托方法中检测到一个。为此,UIImagePickerControllerMediaType
的粒度不够细。相反,获取照片库授权并获取由UIImagePickerControllerPHAsset
键返回的 PHAsset,并检查其playbackStyle
。这将得出您想要的区别。
https://developer.apple.com/documentation/photos/phasset.playbackstyle
.videoLooping
是反弹或缩放实时照片。
【讨论】:
谢谢,我认为 [kUTTypeMovie as String] 可以防止任何不是视频的内容。如果使用这两种类型初始化,您能否回答有关 AVPlayer 从后台返回时冻结的问题? 如果我理解正确,如果 AVPlayer 的 url 是 Live 或 Bounce 类型的照片,那么我应该使用 AVQueuePlayer 而不是使用 AVPlayer? 我有你的 ios 10 书,我还没有升级到 11。看来我必须这样做。谢谢你的一切:) 我已经听从了您的建议,并且能够阻止用户在 didFinishPickingMediaWithInfo 中选择实时照片。令我困惑的是,当我打开 YouTube 的 iOS 应用程序时,当我按下视频图标进行录制时,我只看到库中的电影,没有显示任何实时照片。他们是如何阻止图书馆展示除电影之外的任何东西的?除非他们使用不同于 [kUTTypeMovie as String] 的东西? 你的意思是自定义的东西还是其他的 api?以上是关于为啥 imagePickerController.mediaTypes = [kUTTypeMovie as String] 包括实时照片作为反弹或循环效果作为视频?的主要内容,如果未能解决你的问题,请参考以下文章
Swift 3 - 无法覆盖'imagePickerController'
如何使用 ImagePickerController 直接显示“相机胶卷”
无法获取 UIImage 以匹配自定义 ImagePickerController 预览