私はAVQueuePlayerオブジェクトを使って単純なオーディオプレイリストを持っています。キューは、カスタムUITableViewCellオブジェクト、PlayableAudioCellを含むUITableViewを反復処理することによって設定されます。これらのオブジェクトには、AVPlayerItemプロパティaudioTrackがあり、これをAVQueueplayerのキューに挿入します。AVPlayerItemのコピーを何らかの形で生成する代わりに、参照にアクセスする代わりに
AVPlayerItemDidPlayToEndTimeオブザーバーをアイテムの再生と終了時にこれらのトラックに追加して削除して、作成した音楽プレーヤーのラベルを更新できるようにしたいとします。
何らかの理由で、キューが2トラックより長い場合、キュー内の3番目のトラックはオブザーバを追加しません。それを適用する関数はトラックのコピーに渡され、トラックのコピーは渡されません。トラックはPlayableAudioCellオブジェクトに保存されました。
これはどうなっているのか理解できませんが、セルのオーディオトラックを参照する代わりに、トラックのコピーをどこかに作成する必要があります。私は、オーディオトラックのメモリ位置のプリントステートメントから私がいると言うことができます。
私のアプリのレイアウトに関するちょっとした説明... tableViewControllerという1つのビューがあり、ユーザーはセルを選択してトラックを再生できます。また、FooterViewがポップアップして再生トラック情報(ラベル、継続時間、トラックスライダ)を表示できるようにするSplitViewControllerがあります。操作の
注文:
ユーザーを押すが、テーブルビュー
AudioQueuePlayerのキュー内のセルで再生を押したトラックと、それは
TableViewControllerのデリゲート以下のすべてのトラックが移入されます(FooterViewController)がそれを委任された再生メソッドと呼びます。
AVPオブザーバーが最初の再生アイテムに追加されます。
トラックが終了すると、セレクターがオブザーバーから呼び出されます。このセレクタ内で、現在のトラックのオブザーバが削除され、次のトラックにAVPlayerItemDidPlayToEndTimeオブザーバを追加するコードが追加されます。
このコードのいずれかがcurrentlySelectedAudioCellのaudiotrackプロパティを参照するとは対照的に、私は、細胞またはaudiotrackのコピーのコピーにアクセスするよう飛び出していますか?
私は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()
}
}
}