swift 调用了两次初始化,导致应用程序崩溃,并出现错误“AVPlayerItem无法与AVPlayer的多个示例关联”

tyky79it  于 2023-06-21  发布在  Swift
关注(0)|答案(1)|浏览(77)

我有一个NavigationStack,它由三个视图组成:视频选择器、上传进度视图和视频预览视图。上传后,我将AVPlayerItem传递到预览视图。这将显示视频。下面是相关代码:

@main
struct CaptionsApp: App {
  @StateObject private var model = MyModel()

  var body: some Scene {
    WindowGroup {
      NavigationStack(path: $model.path) {
        VideoSelectorView(model: model)
          .navigationDestination(for: VideoDestination.self) { destination in
            switch destination {
            case .uploading:
              MyUploadView(model: model)
            case .transcribed(let playerItem):
              VideoPreviewView(playerItem: playerItem)
            }
          }
      }
    }
  }
}

struct VideoPreviewView: View {
  private var player: AVPlayer?

  init(playerItem: AVPlayerItem) {
    let player = AVPlayer(
      playerItem: playerItem
    )
    player.actionAtItemEnd = .none
    self.player = player
  }

  var body: some View {
    VideoPlayer(player: player)
      .onAppear {
        player.play()
      }
  }
}

不幸的是,当它导航到VideoPreviewView时,它崩溃并显示错误:

An AVPlayerItem cannot be associated with more than one instance of AVPlayer

我检查了init()被调用了两次。我不知道为什么会这样。导航路径仅添加一次。模型中唯一改变的@Published值是导航路径。我该怎么解决这个问题?

y0u0uwnf

y0u0uwnf1#

不要假设视图的init将被调用多少次。SwiftUI可以随意调用它们。参见this post
您应该以一种方式编写init,无论它被调用多少次。在这种情况下,您可以直接传入AVPlayer,而不是创建一个新的。

struct VideoPreviewView: View {
  private var player: AVPlayer

  init(player: AVPlayer) {
    self.player = player
    player.actionAtItemEnd = .none
  }
}

在交换机中初始化播放器。

case .transcribed(let playerItem):
  VideoPreviewView(player: AVPlayer(playerItem: playItem))

相关问题