首页 > 解决方案 > 具有一个 AVPlayer 的多个 AVPlayerLayers 会导致冻结帧而没有玩家在模拟器中分离,但适用于设备

问题描述

当在不同的视图控制器中使用连接到一个 AVPlayer 实例的多个 AVPlayerLayer 实例时,视频会在模拟器上冻结。除非在视图控制器转换(例如 viewDidDisappear)之后变得“不可见”的每个 AVPlayerLayer 都与播放器分离。这种无需分离的方法在 iOS 设备上运行良好。

脚步:

  1. 从github.com/KaiOelfke/MultiplePlayerLayers下载示例项目
  2. 在 iOS 模拟器上运行
  3. 切换到第二个标签

预期:视频正在播放。

实际结果:视频帧被冻结。音频播放。切换标签会导致播放几帧,然后再次冻结。

  1. 在 iOS 设备上运行
  2. 切换到第二个标签
  3. 切换标签几次

该应用程序按预期运行。两个播放器视图都正常播放视频。

通过在 ViewController.viewDidDisappear() 中将播放器与 AVPlayerLayer 分离,可以修复模拟器上的不同行为。似乎,如果至少有一个附加的播放器视图被 iOS 视为“不可见”,则视频将停止在模拟器上播放。

用例是一个具有多个选项卡的应用程序,在选项卡栏顶部有一个迷你播放器栏(包括一个小视频层),类似于 Apple Music 应用程序以及模态显示的全屏播放器视图。每个选项卡都有自己的迷你播放器 AVPlayerLayer。

这是模拟器错误吗?实现多个 AVPlayerLayer 实例在视图层次结构的各个部分播放相同内容的推荐方法是什么?

// ViewController.swift
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        // as soon as the second VC becomes visible and the player view is attached the issue occurs
        VideoController.shared.attachPlayerView(playerView)
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        // detaching here solves the issue
        // VideoController.shared.detachPlayerView(playerView)
    }

// VideoController.swift
    func attachPlayerView(_ playerView: PlayerView) {
        playerView.player = player
    }

    func detachPlayerView(_ playerView: PlayerView) {
        playerView.player = nil
    }

// PlayerView.swift
    var player: AVPlayer? {
        get {
            playerLayer?.player
        }
        set {
            playerLayer?.player = newValue
        }
    }

标签: iosavfoundationios-simulatoravplayeravplayerlayer

解决方案


推荐阅读