gpt4 book ai didi

ios - 以某种方式生成 AVPlayerItem 的副本而不是访问引用

转载 作者:行者123 更新时间:2023-11-30 12:04:31 25 4
gpt4 key购买 nike

我有一个使用 AVQueuePlayer 对象的简单音频播放列表。通过迭代包含自定义 UITableViewCell 对象 PlayableAudioCell 的 UITableView 来填充队列。这些对象有一个 AVPlayerItem 属性,audioTrack,我将其插入到 AVQueueplayer 的队列中。

我想在项目播放和完成时向这些轨道添加和删除 AVPlayerItemDidPlayToEndTime 观察器,以便我可以更新我创建的音乐播放器的标签。

由于某种原因,如果队列长于 2 个轨道,则队列中的第三个轨道不会将观察者添加到其中,因为应用它的函数会传递轨道的副本,而不是轨道已保存到 PlayableAudioCell 对象。

我无法理解这是如何发生的,但我必须在某处创建轨道的副本,而不是引用单元格的音轨。从音轨存储位置的打印语句中我可以看出我是。

只是对我的应用程序布局的一些解释...它包含一个 tableViewController View ,允许用户选择一个单元格并播放一首轨道。我还有一个 SplitViewController,它允许弹出 FooterView 并显示正在播放的轨道信息(标签、持续时间、轨道 slider )。

操作顺序:

  1. 用户在 TableView 中的单元格上按下播放按钮

  2. AudioQueuePlayer 的队列由按下的轨道及其下面的每个轨道填充

  3. TableViewController 的委托(delegate) (FooterViewController) 调用其委托(delegate)的播放方法

  4. AVPlayerItemDidPlayToEndTime 观察者已添加到播放的第一个项目

  5. 当跟踪结束时,观察者会调用选择器。在此选择器中,删除当前轨道的观察者,并添加将 AVPlayerItemDidPlayToEndTime 观察者添加到下一个轨道的代码。

当我访问单元格的副本或音轨的副本而不是引用 currentSelectedAudioCell 的音轨属性时,是否会弹出任何此代码?

我将省略 TableViewController 中的代码...我可以看出它在表中正确填充,并且问题必须出在 FooterViewController 的代码中:

func play(cell: PlayableAudioCell){

if let previousCell = currentlySelectedAudioCell, let prevFilename = currentlySelectedAudioCell?.chapter?.value(forKey: "Filename") as? String, let filename = cell.chapter?.value(forKey: "Filename") as? String{

if filename != prevFilename{
runningTime = 0
}
}

updateWithObserver(cell: cell)

//show footerview if it is hidden.
if(footerView.superview?.isHidden)!{
hideShowFooterView()
}

if(self.isPlaying)!{
//print("Should pause cell")
audioQueuePlayer?.pause()
switchState(state: "Pause")

playPauseRunTime(state: "Pause")

}else{
//print("Should play cell")
audioQueuePlayer?.play()
switchState(state: "Play")

playPauseRunTime(state: "Play")
}

updateFooterView()
}

func updateWithObserver(cell: PlayableAudioCell){

self.currentlySelectedAudioCell = cell
delegate?.currentlySelectedAudioCell = cell

let track = cell.audioTrack!

NotificationCenter.default.addObserver(self, selector: #selector(FooterViewController.playerItemDidReachEnd(notification:)), name: Notification.Name.AVPlayerItemDidPlayToEndTime, object: track)

}

func playerItemDidReachEnd(notification: Notification){
NotificationCenter.default.removeObserver(self, name: notification.name, object: audioQueuePlayer?.currentItem)

if didAudioPlayEntirely(){
recordAudioHistoryToFirebase(didFinish: true)
if let currentlySelectedAudioCell = delegate?.currentlySelectedAudioCell{
revealCheckMark(cell: currentlySelectedAudioCell)
}
}

runningTime = 0

//If there is just one more item in the queue, regardless of whether playAll() has been toggled...
if (audioQueuePlayer?.items().count)! <= 1 {

playPauseRunTime(state: "Pause")

audioQueuePlayer?.removeAllItems()
resetFooterViewUI()
switchState(state: "Pause")
hideShowFooterView()

audioQueuePlayer?.rate = 0.0

delegate?.currentlySelectedAudioCell = nil
currentlySelectedAudioCell = nil
delegate?.indexPathOfSelectedCell = nil
indexPathOfSelectedCell = nil

}else{

if let indexPathOfSelectedCell = indexPathOfSelectedCell{

playPauseRunTime(state: "Pause")
playPauseRunTime(state: "Play")

let row = indexPathOfSelectedCell.row + 1
let newIndexPath = IndexPath(row: row, section: 0)
self.indexPathOfSelectedCell = newIndexPath
delegate?.indexPathOfSelectedCell = newIndexPath

let newCell = self.tableView!.cellForRow(at: newIndexPath) as? PlayableAudioCell
updateWithObserver(cell: newCell!)

updateFooterView()
self.tableView!.reloadData()

}
}
}

最佳答案

显然,AVQueuePlayer 每次完成播放队列中的项目时都会删除 AVPlayerItem。我的逻辑是尝试将队列的索引与 TableView 单元格的数组相匹配,经过几次迭代后,索引将关闭,并且观察者不会添加到正确的玩家项目中。通过用 AVPlayer 和 AVPlayerItems 数组替换 AVQueuePlayer 来修复。

关于ios - 以某种方式生成 AVPlayerItem 的副本而不是访问引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46819887/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com