特点:
file:// URL 或 AVAsset 创建对象。示例代码:
import AVFoundationimport AVKit// 本地文件路径if let path = Bundle.main.path(forResource: "video", ofType: "mp4") { let url = URL(fileURLWithPath: path) let player = AVPlayer(url: url) let playerVC = AVPlayerViewController() playerVC.player = player self.present(playerVC, animated: true) { player.play() }}php338 Bytes© 菜鸟-创作你的创作注意点:
Bundle.main.path 或 FileManager 获取本地文件路径。特点:
https://.../video.mp4 或 HLS 流 https://.../index.m3u8。示例代码:
import AVFoundationimport AVKitif let url = URL(string: "https://www.example.com/video.mp4") { let player = AVPlayer(url: url) let playerVC = AVPlayerViewController() playerVC.player = player self.present(playerVC, animated: true) { player.play() }}php281 Bytes© 菜鸟-创作你的创作注意点:
AVPlayerItem 的 preferredForwardBufferDuration 或 automaticallyWaitsToMinimizeStalling 来控制缓冲行为。特性 | 本地文件 | 网络视频 |
|---|---|---|
URL 类型 | file:// | http(s):// |
加载速度 | 快,无缓冲 | 受网络影响,需要缓冲 |
错误处理 | 文件不存在或路径错误 | 网络超时、404、流媒体错误 |
码率适应 | 固定 | HLS 自动码率适应,普通 MP4 不适用 |
缓存 | 已经在本地 | 系统会缓存部分播放数据,或者需自定义缓存 |
播放稳定性 | 高 | 受网络稳定性影响 |
好的阿杰,我帮你写一个 Swift 封装类,支持 本地视频优先播放,如果本地没有则播放网络视频,并附带基础错误处理和缓冲设置。
import AVFoundationimport AVKitimport UIKitclass SmartAVPlayer: NSObject { private var player: AVPlayer? private var playerVC: AVPlayerViewController? private weak var parentVC: UIViewController? /// 初始化播放器 /// - Parameters: /// - localPath: 本地视频文件路径(可选) /// - networkURL: 网络视频 URL /// - parentVC: 播放器展示的父视图控制器 init(localPath: String?, networkURL: String, parentVC: UIViewController) { super.init() self.parentVC = parentVC setupPlayer(localPath: localPath, networkURL: networkURL) } /// 配置播放器 private func setupPlayer(localPath: String?, networkURL: String) { var videoURL: URL? // 优先本地文件 if let localPath = localPath, FileManager.default.fileExists(atPath: localPath) { videoURL = URL(fileURLWithPath: localPath) print("播放本地视频: \(localPath)") } else if let url = URL(string: networkURL) { videoURL = url print("播放网络视频: \(networkURL)") } else { print("无有效视频路径") return } let playerItem = AVPlayerItem(url: videoURL!) // 可选:设置缓冲策略 playerItem.preferredForwardBufferDuration = 5 // 提前缓冲 5 秒 player = AVPlayer(playerItem: playerItem) player?.automaticallyWaitsToMinimizeStalling = true playerVC = AVPlayerViewController() playerVC?.player = player } /// 展示播放器 func play() { guard let playerVC = playerVC, let parentVC = parentVC else { return } parentVC.present(playerVC, animated: true) { self.player?.play() } } /// 暂停播放 func pause() { player?.pause() } /// 停止播放并释放 func stop() { player?.pause() player = nil playerVC?.dismiss(animated: true) playerVC = nil }}php1.8 KB© 菜鸟-创作你的创作// 假设 parentVC 是当前 UIViewControllerlet localPath = Bundle.main.path(forResource: "video", ofType: "mp4")let networkURL = "https://www.example.com/video.mp4"let smartPlayer = SmartAVPlayer(localPath: localPath, networkURL: networkURL, parentVC: self)smartPlayer.play()php272 Bytes© 菜鸟-创作你的创作preferredForwardBufferDuration & automaticallyWaitsToMinimizeStalling)。pause()) 和停止 (stop()) 接口。AVPlayerViewController 展示,兼容全屏和手势控制。明白阿杰,我帮你写一个 升级版 SmartAVPlayer,实现以下功能:
import AVFoundationimport AVKitimport UIKitclass SmartAVPlayer: NSObject { private var player: AVPlayer? private var playerVC: AVPlayerViewController? private weak var parentVC: UIViewController? private var cacheDir: URL = { let urls = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask) let dir = urls[0].appendingPathComponent("VideoCache") if !FileManager.default.fileExists(atPath: dir.path) { try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true) } return dir }() /// 初始化播放器 /// - Parameters: /// - localPath: 本地视频路径(可选) /// - networkURL: 网络视频 URL /// - parentVC: 父控制器 init(localPath: String?, networkURL: String, parentVC: UIViewController) { super.init() self.parentVC = parentVC prepareVideo(localPath: localPath, networkURL: networkURL) } /// 准备视频资源 private func prepareVideo(localPath: String?, networkURL: String) { // 1. 优先本地文件 if let localPath = localPath, FileManager.default.fileExists(atPath: localPath) { setupPlayer(url: URL(fileURLWithPath: localPath)) print("播放本地视频: \(localPath)") return } // 2. 检查缓存 let cachedURL = cacheDir.appendingPathComponent(networkURL.md5 + ".mp4") if FileManager.default.fileExists(atPath: cachedURL.path) { setupPlayer(url: cachedURL) print("播放缓存视频: \(cachedURL.path)") return } // 3. 下载网络视频 guard let url = URL(string: networkURL) else { return } downloadVideo(from: url, saveTo: cachedURL) } /// 设置播放器 private func setupPlayer(url: URL) { let playerItem = AVPlayerItem(url: url) playerItem.preferredForwardBufferDuration = 5 player = AVPlayer(playerItem: playerItem) player?.automaticallyWaitsToMinimizeStalling = true playerVC = AVPlayerViewController() playerVC?.player = player } /// 下载网络视频并缓存 private func downloadVideo(from url: URL, saveTo localURL: URL) { let task = URLSession.shared.downloadTask(with: url) { tempURL, _, error in guard let tempURL = tempURL, error == nil else { print("下载失败: \(error?.localizedDescription ?? "未知错误")") return } do { try FileManager.default.moveItem(at: tempURL, to: localURL) DispatchQueue.main.async { self.setupPlayer(url: localURL) self.play() } print("视频已缓存到: \(localURL.path)") } catch { print("缓存失败: \(error.localizedDescription)") } } task.resume() } /// 播放 func play() { guard let playerVC = playerVC, let parentVC = parentVC else { return } parentVC.present(playerVC, animated: true) { self.player?.play() } } /// 暂停 func pause() { player?.pause() } /// 停止并释放 func stop() { player?.pause() player = nil playerVC?.dismiss(animated: true) playerVC = nil }}// MARK: - 简单 MD5 扩展用于生成缓存文件名import CommonCryptoextension String { var md5: String { let data = Data(self.utf8) var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH)) data.withUnsafeBytes { _ = CC_MD5($0.baseAddress, CC_LONG(data.count), &digest) } return digest.map { String(format: "%02x", $0) }.joined() }}php3.52 KB© 菜鸟-创作你的创作let localPath = Bundle.main.path(forResource: "video", ofType: "mp4")let networkURL = "https://www.example.com/video.mp4" // 或者 HLS .m3u8let smartPlayer = SmartAVPlayer(localPath: localPath, networkURL: networkURL, parentVC: self)smartPlayer.play()php252 Bytes© 菜鸟-创作你的创作Caches/VideoCache,下次直接播放本地缓存。https://www.52runoob.com/archives/5748
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。