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

为何设置UIImagePicker.mediaTypes为[kUTTypeMovie]会包含带Bounce/Loop效果的Live Photos?

解决UIImagePicker选取视频时包含带Bounce/Loop特效Live Photo的问题

嘿,这个坑我之前踩过!其实问题出在苹果对带特效的Live Photo的处理上——当你给Live Photo设置Bounce或Loop效果时,系统会自动生成一个对应的小型视频轨道关联到这个图片资产里,导致UIImagePicker的kUTTypeMovie过滤规则把它误判成视频了。而切换到Live或Long Exposure效果时,这个关联的视频轨道会被移除,所以就不会被列出来了。

下面给你两个可行的解决方案,根据你的iOS版本支持需求来选:

方案1:兼容iOS 13及以下,手动过滤带特效的Live Photo

我们可以借助Photos框架,在用户选择资产后,检查对应的PHAsset属性,把带Bounce/Loop特效的Live Photo排除掉:

首先导入Photos框架,然后在UIImagePicker的回调里处理:

import Photos

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    picker.dismiss(animated: true)
    
    // 先获取选中的媒体URL
    guard let mediaURL = info[.mediaURL] as? URL else {
        print("无法获取媒体URL")
        return
    }
    
    // 通过URL找到对应的PHAsset
    let fetchOptions = PHFetchOptions()
    let fetchResult = PHAsset.fetchAssets(withALAssetURLs: [mediaURL], options: fetchOptions)
    
    guard let targetAsset = fetchResult.firstObject else {
        // 正常处理视频
        handleSelectedVideo(url: mediaURL)
        return
    }
    
    // 判断是否是带Bounce/Loop特效的Live Photo
    let isFilteredLivePhoto = targetAsset.mediaType == .image 
        && targetAsset.mediaSubtypes.contains(.photoLive)
        && (targetAsset.effectivePlaybackStyle == .loop || targetAsset.effectivePlaybackStyle == .bounce)
    
    if isFilteredLivePhoto {
        // 这里可以提示用户,或者直接跳过处理
        print("这是带特效的Live Photo,不是视频哦")
        return
    }
    
    // 处理真正的视频文件
    handleSelectedVideo(url: mediaURL)
}

// 自定义的视频处理方法
func handleSelectedVideo(url: URL) {
    // 你的视频逻辑代码
}

核心是effectivePlaybackStyle这个属性,它能直接获取Live Photo当前的播放特效类型,精准过滤掉我们不需要的资产。

方案2:iOS 14+推荐,用PHPicker替代UIImagePicker

苹果在iOS14推出的PHPicker是更现代的媒体选择器,它的过滤逻辑更精准,不需要手动处理就能自动排除带特效的Live Photo:

先导入PhotosUI框架,然后实现选择器:

import PhotosUI

func showVideoPicker() {
    var pickerConfig = PHPickerConfiguration()
    // 设置只允许选择视频
    pickerConfig.filter = .videos
    pickerConfig.selectionLimit = 1 // 可根据需求调整选择数量
    
    let picker = PHPickerViewController(configuration: pickerConfig)
    picker.delegate = self
    present(picker, animated: true)
}

// PHPicker的回调方法
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    picker.dismiss(animated: true)
    
    guard let selectedResult = results.first else { return }
    
    // 加载选中的视频URL
    selectedResult.itemProvider.loadObject(ofClass: URL.self) { [weak self] result, error in
        guard let self = self, let videoURL = result as? URL, error == nil else {
            print("加载视频失败")
            return
        }
        
        // 处理视频
        self.handleSelectedVideo(url: videoURL)
    }
}

PHPicker会自动把带Bounce/Loop特效的Live Photo归类为图片资产,不会被.videos过滤器选中,用起来更省心,而且现在iOS14及以上的用户占比很高,推荐优先采用这个方案。

内容的提问来源于stack exchange,提问作者Lance Samaria

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:46:49