You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift:如何让UIImagePickerController仅展示特定时长以内的视频

嘿,这个需求我之前做项目的时候刚好碰到过!系统自带的UIImagePickerController本身并没有直接提供按视频时长筛选的配置项,不过咱们有两种靠谱的方案来实现:一种是提前用PhotoKit筛选出符合时长要求的视频,做个自定义选择界面;另一种是用系统picker,等用户选完再校验时长。下面给你详细拆解:

方案一:用PhotoKit预筛选(推荐,体验更流畅)

这种方式能让用户在选择界面就只看到符合时长的视频,避免选完才发现不符合的尴尬。步骤如下:

  1. 先导入PhotoKit框架
    在你的ViewController顶部加上:
import Photos
  1. 申请相册访问权限
    这是必须的,先处理权限逻辑:
func requestPhotoPermission() {
    PHPhotoLibrary.requestAuthorization { status in
        DispatchQueue.main.async {
            switch status {
            case .authorized:
                // 权限通过,开始获取符合条件的视频
                self.fetchShortVideos(maxDuration: 10) // 这里设置你要的最大时长,比如10秒
            case .denied, .restricted:
                // 提示用户开启权限
                let alert = UIAlertController(title: "需要相册权限", message: "请在设置中开启相册权限以选择视频", preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "知道了", style: .default))
                self.present(alert, animated: true)
            default:
                break
            }
        }
    }
}
  1. 筛选符合时长的视频资产
    用PHFetchOptions设置过滤条件,只拉取时长小于指定值的视频:
func fetchShortVideos(maxDuration: TimeInterval) {
    let fetchOptions = PHFetchOptions()
    // 设置过滤条件:时长小于maxDuration秒
    fetchOptions.predicate = NSPredicate(format: "duration < %f", maxDuration)
    // 指定只获取视频类型
    fetchOptions.mediaTypes = [.video]
    // 按创建时间倒序排列,最新的在前
    fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
    
    // 获取符合条件的视频资产
    let videoAssets = PHAsset.fetchAssets(with: fetchOptions)
    
    // 接下来你可以用这些assets来搭建自定义的选择界面,比如用UICollectionView展示缩略图
    // 举个获取缩略图的例子:
    let imageManager = PHImageManager.default()
    let targetSize = CGSize(width: 150, height: 150) // 缩略图大小
    
    videoAssets.enumerateObjects { asset, _, _ in
        imageManager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFill, options: nil) { image, _ in
            // 拿到缩略图image,加到你的数据源里
        }
    }
}
  1. 用户选中后获取视频文件
    当用户在自定义界面选中某个asset时,用PHImageManager获取视频的URL:
func getVideoURL(from asset: PHAsset, completion: @escaping (URL?) -> Void) {
    let options = PHVideoRequestOptions()
    options.isNetworkAccessAllowed = true // 允许从iCloud获取
    
    PHImageManager.default().requestAVAsset(forVideo: asset, options: options) { avAsset, _, _ in
        guard let urlAsset = avAsset as? AVURLAsset else {
            completion(nil)
            return
        }
        completion(urlAsset.url)
    }
}
方案二:系统Picker选后校验(快速实现)

如果不想自定义界面,用系统的UIImagePickerController也可以,只是需要在用户选完后检查时长:

  1. 配置并弹出系统Picker
    记得导入MobileCoreServices框架:
import MobileCoreServices

func showVideoPicker() {
    let picker = UIImagePickerController()
    picker.sourceType = .photoLibrary
    // 指定只选择视频
    picker.mediaTypes = [kUTTypeMovie as String]
    picker.delegate = self
    present(picker, animated: true)
}
  1. 实现代理方法,校验时长
    要确保你的ViewController遵守UIImagePickerControllerDelegate和UINavigationControllerDelegate协议:
extension YourViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        picker.dismiss(animated: true)
        
        // 获取视频URL
        guard let videoURL = info[.mediaURL] as? URL else { return }
        
        // 加载视频资产,获取时长
        let asset = AVAsset(url: videoURL)
        asset.loadValuesAsynchronously(forKeys: ["duration"]) {
            var error: NSError?
            let status = asset.statusOfValue(forKey: "duration", error: &error)
            
            DispatchQueue.main.async {
                switch status {
                case .loaded:
                    let duration = asset.duration.seconds
                    if duration < 10 { // 这里设置你的最大时长
                        // 符合条件,处理视频
                        self.handleSelectedVideo(url: videoURL)
                    } else {
                        // 时长过长,提示用户
                        let alert = UIAlertController(title: "视频时长过长", message: "请选择时长小于10秒的视频", preferredStyle: .alert)
                        alert.addAction(UIAlertAction(title: "重新选择", style: .default, handler: { _ in
                            self.showVideoPicker()
                        }))
                        alert.addAction(UIAlertAction(title: "取消", style: .cancel))
                        self.present(alert, animated: true)
                    }
                case .failed, .cancelled:
                    // 加载失败,提示用户
                    let alert = UIAlertController(title: "错误", message: "无法获取视频时长", preferredStyle: .alert)
                    alert.addAction(UIAlertAction(title: "确定", style: .default))
                    self.present(alert, animated: true)
                default:
                    break
                }
            }
        }
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true)
    }
}

额外注意点

  • 不管哪种方案,都要在Info.plist中添加NSPhotoLibraryUsageDescription权限描述,不然App会直接崩溃。
  • 如果要支持iCloud中的视频,记得在PHVideoRequestOptions中设置isNetworkAccessAllowed = true,并可以添加加载中的提示状态。

内容的提问来源于stack exchange,提问作者Geoff H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:42:46