PHPicker选相册视频后,TrimVideoViewController中AVFoundation无法播放求助
PHPicker选视频后AVFoundation无法播放的解决方案
问题背景
我有两个ViewController:GetStartedViewController(根视图控制器)和TrimVideoViewController。在根控制器中通过PHPicker选取视频后,将URL传入第二个控制器的AVFoundation组件,但视频完全无法播放。尝试过将视频复制到其他目录、寻找第三方框架(大多仅支持HTTP链接)均未解决问题。
具体解决步骤
1. 确保视频URL的访问权限有效
PHPicker返回的是临时沙盒URL,跨ViewController传递时容易丢失访问权限。正确做法是传递PHPickerResult的NSItemProvider,在目标VC中重新加载可访问的本地文件:
// GetStartedViewController中传递数据 if let result = picker.selectedItems.first { let trimVC = TrimVideoViewController() trimVC.videoItemProvider = result.itemProvider navigationController?.pushViewController(trimVC, animated: true) } // TrimVideoViewController中加载视频 class TrimVideoViewController: UIViewController { var videoItemProvider: NSItemProvider! private var player: AVPlayer? private var playerLayer: AVPlayerLayer? @IBOutlet weak var videoView: UIView! override func viewDidLoad() { super.viewDidLoad() loadVideoFromItemProvider() } private func loadVideoFromItemProvider() { guard videoItemProvider.hasItemConformingToTypeIdentifier(UTType.movie.identifier) else { return } videoItemProvider.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier) { [weak self] url, error in guard let self = self, let url = url else { return } DispatchQueue.main.async { self.setupPlayer(with: url) } } } private func setupPlayer(with url: URL) { self.player = AVPlayer(url: url) self.playerLayer = AVPlayerLayer(player: self.player) self.playerLayer?.frame = self.videoView.bounds self.playerLayer?.videoGravity = .resizeAspectFill self.videoView.layer.addSublayer(self.playerLayer!) self.player?.play() } }
2. 避免AVPlayer/AVPlayerLayer被提前释放
必须将player和playerLayer声明为ViewController的成员属性,不能用局部变量,否则会被ARC自动释放,导致视频无法播放。
3. 验证视频文件的可用性
可以通过AVAsset检查视频是否能正常加载:
private func validateVideo(url: URL) { let asset = AVAsset(url: url) asset.loadValuesAsynchronously(forKeys: ["duration"]) { var error: NSError? switch asset.statusOfValue(forKey: "duration", error: &error) { case .loaded: print("视频有效,时长:\(asset.duration.seconds)秒") case .failed: print("视频加载失败:\(error?.localizedDescription ?? "未知错误")") default: break } } }
4. 确认权限配置
在Info.plist中添加相册访问权限描述,避免权限不足导致无法读取视频:
<key>NSPhotoLibraryUsageDescription</key> <string>需要访问相册以选择和播放视频</string>
内容的提问来源于stack exchange,提问作者SunnySideUp
相关产品推荐
相关产品推荐

