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

能否将AVPlayerViewController与AVPlayerLooper搭配实现视频自动循环播放?

AVPlayerLooper结合AVPlayerViewController循环播放黑屏问题解决

需求:使用AVPlayerViewController展示视频并实现自动循环播放,尝试用AVPlayerLooper替代之前监听AVPlayerItemDidPlayToEndTime通知的方案,但运行后仅显示带控制栏的黑屏,推测播放器无内容可播放。

原问题代码

struct VideoPlayerQueuedView: UIViewControllerRepresentable {
  let videoUrl: URL
  
  func makeUIViewController(context: Context) -> AVPlayerViewController {
      let queuePlayer = AVQueuePlayer()
      let playerViewController = AVPlayerViewController()
      
      // Create an AVPlayerItem from the videoUrl
      let playerItem = AVPlayerItem(url: videoUrl)
      
      // Create an AVPlayerLooper with the queuePlayer and the playerItem as the template item
      let playerLooper = AVPlayerLooper(player: queuePlayer, templateItem: playerItem)
      
      // Set the player property of AVPlayerViewController
      playerViewController.player = queuePlayer
      
      return playerViewController
  }
  
  func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {
      // Update the video player if needed
  }
}

问题原因

  1. AVPlayerLooper被提前释放:代码中playerLooper是局部变量,makeUIViewController执行完毕后会被ARC回收,循环逻辑直接失效,播放器无法自动补充后续播放项。
  2. 未主动启动播放:创建完播放器后没有调用play()方法,播放器处于未激活状态,自然显示黑屏。

解决方案及修正代码

通过Coordinator存储AVPlayerLooper以维持其生命周期,同时主动启动播放:

struct VideoPlayerQueuedView: UIViewControllerRepresentable {
    let videoUrl: URL
    
    // 用Coordinator持有AVPlayerLooper,避免被提前回收
    class Coordinator: NSObject {
        var playerLooper: AVPlayerLooper?
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator()
    }
    
    func makeUIViewController(context: Context) -> AVPlayerViewController {
        let queuePlayer = AVQueuePlayer()
        let playerViewController = AVPlayerViewController()
        
        let playerItem = AVPlayerItem(url: videoUrl)
        // 将Looper实例存入Coordinator
        context.coordinator.playerLooper = AVPlayerLooper(player: queuePlayer, templateItem: playerItem)
        
        playerViewController.player = queuePlayer
        // 主动启动播放
        queuePlayer.play()
        
        // 可选:根据需求隐藏控制栏
        // playerViewController.showsPlaybackControls = false
        
        return playerViewController
    }
    
    func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {
        // 若需更新视频URL,可在此处停止旧播放并重新创建Looper
    }
}

关键说明

  • Coordinator的作用:利用UIViewControllerRepresentable的Coordinator持有AVPlayerLooper,保证其生命周期与视图控制器同步,不会被提前销毁。
  • 自动循环逻辑:AVPlayerLooper会自动在播放队列末尾添加模板item的副本,实现无缝循环,无需再监听播放结束通知。
  • 必须启动播放:AVPlayerViewController不会自动触发播放,必须手动调用play()方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 03:12:54