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

SwiftUI 4.0中如何通过PhotosPickerItem的item identifier加载选中视频

解决SwiftUI 4 PhotosPicker无法处理视频的问题

你当前的代码用loadTransferable(type: Data.self)加载视频,这种方式不仅内存占用高,而且没法直接对接AVPlayer。另外,PhotosPickerItem的itemIdentifier是系统内部标识,不能直接用来构造可访问的视频URL,正确的做法是通过加载视频的本地临时URL来实现播放。

核心修改点

  • 替换加载类型为URL:视频文件体积通常较大,加载成Data会占用大量内存,直接加载为本地URL更高效,也符合AVPlayer的使用需求。
  • 更新AVPlayer实例:获取到视频URL后,创建新的AVPlayer并赋值给@State变量,触发UI自动更新。
  • 优化错误处理:避免使用fatalError导致崩溃,改用打印错误信息的方式排查问题。

修改后的完整代码

import SwiftUI
import PhotosUI
import AVKit

struct PlayVideoView: View {
    @State private var selectedItem: [PhotosPickerItem] = []
    @State private var player: AVPlayer? = AVPlayer(url: URL(string: "https://swiftanytime-content.s3.ap-south-1.amazonaws.com/SwiftUI-Beginner/Video-Player/iMacAdvertisement.mp4")!)

    var body: some View {
        PhotosPicker(selection: $selectedItem,
                     maxSelectionCount: 1,
                     matching: .any(of: [.images,.videos])) {
            Image(systemName: "photo")
                .resizable()
                .foregroundColor(.blue)
                .frame(width: 24, height: 24)
                .padding(.top, 5.0)
        }
        .onChange(of: selectedItem) { newMedia in
            Task {
                guard let item = selectedItem.first else {
                    return
                }
                // 加载视频的本地临时URL
                do {
                    if let videoURL = try await item.loadTransferable(type: URL.self) {
                        // 创建新的AVPlayer实例并赋值
                        player = AVPlayer(url: videoURL)
                        // 可选:自动播放选中的视频
                        player?.play()
                    } else {
                        print("无法获取视频URL")
                    }
                } catch {
                    print("加载视频失败: \(error.localizedDescription)")
                }
            }
        }
        // 处理player为空的情况
        if let player = player {
            VideoPlayer(player: player)
                .frame(width: 400, height: 300, alignment: .center)
        } else {
            Text("未选中视频")
                .frame(width: 400, height: 300)
        }
    }
}

struct PlayVideoView_Previews: PreviewProvider {
    static var previews: some View {
        PlayVideoView()
    }
}

补充说明

  • 临时URL生命周期:通过loadTransferable(type: URL.self)获取的URL是系统沙盒内的临时文件路径,只要你持有该URL并在使用,系统会自动保留文件,无需手动清理。
  • 视频格式支持:代码中matching: .any(of: [.images,.videos])已经包含所有系统支持的视频类型(如mov、mp4等),无需额外配置。
  • 权限配置:确保在Info.plist中添加NSPhotoLibraryUsageDescription权限描述,否则无法访问系统相册内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:55:25