Swift:使用YouTubePlayer加载Parse返回的视频URL无法播放
无法播放的核心原因
你使用的pod 'YouTubePlayer'是专属YouTube平台的播放器组件,底层依赖YouTube官方的iframe播放能力,仅支持解析包含YouTube视频ID的平台专属URL,无法兼容后端返回的普通MP4、m3u8等通用格式的视频资源URL,这就是YouTube链接可正常播放、自有后端视频无显示的直接原因。
除此之外你的代码还存在两个隐患:
- 异步回调直接操作列表cell:
PFQuery的getObjectInBackground是异步回调,回调执行时cell可能已经因为列表滚动被复用到其他行,就算播放器正常也可能出现视频加载错位的问题 - 多处强制解包无校验:直接对
parseObject、videoFile.url等可选值做强制解包,一旦后端数据为空、URL格式非法会直接触发崩溃
解决方案
方案一:仅需播放自有后端视频,无需继续播放YouTube内容
直接替换为系统原生AVPlayer即可,它支持几乎所有通用流媒体格式,改造步骤如下:
- 移除
pod 'YouTubePlayer'依赖,导入系统音视频框架
import AVFoundation
- 改造
VideoTableViewCell新增播放能力
class VideoTableViewCell: UITableViewCell { private var player: AVPlayer? private var playerLayer: AVPlayerLayer? func loadCustomVideo(url: URL) { // 清理旧播放器避免复用冲突 playerLayer?.removeFromSuperlayer() player = AVPlayer(url: url) playerLayer = AVPlayerLayer(player: player) playerLayer?.frame = contentView.bounds playerLayer?.videoGravity = .resizeAspect contentView.layer.addSublayer(playerLayer!) // 如需自动播放可加这行 player?.play() } }
- 优化原查询逻辑,处理可选值校验和线程安全
guard let cell = tableView.dequeueReusableCell(withIdentifier: "VideoTableViewCell") as? VideoTableViewCell else { return UITableViewCell() } let query = PFQuery(className:"Videos") // 记录当前cell对应行号,避免异步回调后cell复用 let originIndexPath = tableView.indexPath(for: cell) query.getObjectInBackground(withId: "83kli72i62") { [weak self] (parseObject, error) in guard let self = self, error == nil, let parseObject = parseObject, let videoFile = parseObject["Question"] as? PFFileObject, let videoUrlStr = videoFile.url, let videoUrl = URL(string: videoUrlStr), // 校验cell未被复用 let currentIndexPath = tableView.indexPath(for: cell), currentIndexPath == originIndexPath else { return } // UI操作切回主线程 DispatchQueue.main.async { cell.loadCustomVideo(url: videoUrl) } }
方案二:需同时兼容YouTube视频和自有后端视频
保留YouTubePlayer专门处理YouTube来源的视频,新增AVPlayer处理自有后端视频,根据URL来源判断调用对应播放器即可。
内容的提问来源于stack exchange,提问作者iron
相关产品推荐
相关产品推荐

