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

Xcode12中AVPlayer无法播放照片库视频的问题求助

解决AVPlayer播放相册视频失败的问题

我仔细看了你的代码和问题描述,这里有几个关键问题导致视频无法正常播放,咱们一步步来解决:

1. 必须配置相册访问权限

iOS 10及以后,访问用户相册必须在Info.plist中添加权限描述,否则不仅弹不出相册选择器,还可能直接崩溃。需要添加以下键(至少包含第一个):

  • NSPhotoLibraryUsageDescription:说明你的App为什么需要访问相册,比如"需要访问相册选择视频进行播放"
  • 若需支持iOS 14+的写入操作,额外添加NSPhotoLibraryAddUsageDescription

2. 替换过时的API获取视频URL

你代码中使用的UIImagePickerControllerReferenceURL在iOS 11之后就被弃用了,而且assets-library://类型的URL已经不再推荐使用,应该直接获取本地文件URL:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    // 直接获取视频的本地文件URL
    guard let videoURL = info[.mediaURL] as? URL else {
        print("无法获取视频URL")
        picker.dismiss(animated: true)
        return
    }
    print(videoURL)
    videoPickerController.dismiss(animated: true) {
        // 延迟播放确保视图已更新
        self.PlayVideo(inView: self.MasterPreviewView, pathToVideo: videoURL)
    }
}

3. 修复AVPlayer的生命周期和播放逻辑问题

你的PlayVideo方法有两个致命问题:

  • 局部变量的player和playerLayerAV在方法执行完后会被ARC销毁,导致视频刚要播放就停止
  • 同时使用AVPlayerViewController和AVPlayerLayer是重复操作,没必要保留前者

首先在类中添加属性来持有播放器和图层:

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    // 新增属性持有播放器和图层
    private var player: AVPlayer?
    private var playerLayer: AVPlayerLayer?
    // ... 其他原有代码
}

然后修改PlayVideo方法:

private func PlayVideo(inView parentView : UIView, pathToVideo urlPath : URL) {
    // 先移除之前的图层,避免重复添加
    playerLayer?.removeFromSuperlayer()
    
    // 初始化播放器和图层
    player = AVPlayer(url: urlPath)
    playerLayer = AVPlayerLayer(player: player)
    
    guard let playerLayer = playerLayer else { return }
    
    // 设置图层适配父视图,保持视频比例
    playerLayer.frame = parentView.bounds
    playerLayer.videoGravity = .resizeAspect
    parentView.layer.addSublayer(playerLayer)
    
    // 添加监听,确保图层在父视图尺寸变化时更新
    NotificationCenter.default.addObserver(self, selector: #selector(updatePlayerLayerFrame), name: UIViewController.viewDidLayoutSubviewsNotification, object: nil)
    
    player?.play()
    player?.rate = 0.5
}

// 新增方法更新图层尺寸
@objc private func updatePlayerLayerFrame() {
    playerLayer?.frame = MasterPreviewView.bounds
}

另外,viewDidLoad中你硬编码的assets-library://URL需要替换成真实的本地测试URL,或者直接注释掉这部分,通过按钮选择视频来测试。

4. 补充:规范相册选择器配置

你的VideoPicker方法中,mediaTypes可以用系统常量更规范:

import MobileCoreServices // 别忘了导入这个框架

internal func VideoPicker(){
    videoPickerController.sourceType = .photoLibrary
    videoPickerController.mediaTypes = [kUTTypeMovie as String]
    videoPickerController.allowsEditing = true
    present(videoPickerController, animated: true, completion: nil)
}

按照这些步骤修改后,应该就能正常播放相册中的视频了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:47:56