2017-10-18 22 views
0

私はAVQueuePlayerオブジェクトを使って単純なオーディオプレイリストを持っています。キューは、カスタムUITableViewCellオブジェクト、PlayableAudioCellを含むUITableViewを反復処理することによって設定されます。これらのオブジェクトには、AVPlayerItemプロパティaudioTrackがあり、これをAVQueueplayerのキューに挿入します。AVPlayerItemのコピーを何らかの形で生成する代わりに、参照にアクセスする代わりに

AVPlayerItemDidPlayToEndTimeオブザーバーをアイテムの再生と終了時にこれらのトラックに追加して削除して、作成した音楽プレーヤーのラベルを更新できるようにしたいとします。

何らかの理由で、キューが2トラックより長い場合、キュー内の3番目のトラックはオブザーバを追加しません。それを適用する関数はトラックのコピーに渡され、トラックのコピーは渡されません。トラックはPlayableAudioCellオブジェクトに保存されました。

これはどうなっているのか理解できませんが、セルのオーディオトラックを参照する代わりに、トラックのコピーをどこかに作成する必要があります。私は、オーディオトラックのメモリ位置のプリントステートメントから私がいると言うことができます。

私のアプリのレイアウトに関するちょっとした説明... tableViewControllerという1つのビューがあり、ユーザーはセルを選択してトラックを再生できます。また、FooterViewがポップアップして再生トラック情報(ラベル、継続時間、トラックスライダ)を表示できるようにするSplitViewControllerがあります。操作の

注文:

  1. ユーザーを押すが、テーブルビュー

  2. AudioQueuePlayerのキュー内のセルで再生を押したトラックと、それは

  3. TableViewControllerのデリゲート以下のすべてのトラックが移入されます(FooterViewController)がそれを委任された再生メソッドと呼びます。

  4. AVPオブザーバーが最初の再生アイテムに追加されます。

  5. トラックが終了すると、セレクターがオブザーバーから呼び出されます。このセレクタ内で、現在のトラックのオブザーバが削除され、次のトラックに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() 

     } 
    } 
} 

答えて

0

どうやらAVQueuePlayerそのキュー内のアイテムの再生が終了するたびにAVPlayerItemを削除します。私のロジックは、キューのインデックスとテーブルビューのセルの配列を一致させようとしていましたが、数回の繰り返しを経てインデックスがオフになり、オブザーバーは正しいプレイアイテムに追加されませんでした。 AVQlayerをAVPlayerとAVPlayerItemの配列に置き換えることで修正されました。

関連する問題