Taras Tomchuk
Taras Tomchuk

Reputation: 331

Automatically playing next audio file from collection view

I'm building audio book app. I have play button inside my collection view cell where users see list of all mp3 files. When user presses this button (play button) - I'm sending data of track to my player class and music file starts to play. I'm using global variables to send track details to my player.

Here's my code:

extension ChapterDetailsViewController: AliaCellDelegate {

    func playAlia(cell: AliaCell) {
         NotificationCenter.default.post(name: NSNotification.Name(rawValue: "playAudio"), object: nil)
  }
}

I need to implement such functionality: When track comes to an end - automatically play next file from same list. For this, I have this method inside my player class, that informs me, when it has finished playing:

func playerDidFinishPlaying(note: NSNotification) { 
     print("Finished playing")
}

But I don't know how to call func playAlia(cell: AliaCell) inside func playerDidFinishPlaying(note: NSNotification) in my player class and pass details of the next track from my collection view.

For now I have created only: NotificationCenter.default.addObserver(self, selector: #selector(playNext), name: NSNotification.Name(rawValue: "playNext"), object: nil) but what should I do next?

Upvotes: 0

Views: 696

Answers (1)

Peter Pajchl
Peter Pajchl

Reputation: 2709

A simple solution is to keep track of existing track within your source model. The example makes plenty of assumptions and is not it not complete.

struct Track {
    let url: URL
    let title: String
    let artist: String
}    

class AudioPlayer: UIViewController {
    var currentTrackIndex: Int = 0
    let tracks: [Track] = [Track(), Track(), Track()]
    let player: AVPlayer()

    // table view delegate for row selection
    override func tableView(_ tableView: UITableView, 
     didSelectRowAt indexPath: IndexPath) {
        // assuming single section
        currentTrackIndex = indexPath.row
        playTrack(at: currentTrackIndex)
    }

    func playTrack(at index: Int) {
        let nextTrack = tracks[index]
        let nextItem = AVPlayerItem(url: nextTrack.url)
        player.replaceCurrentItem(with: nextItem)
    }

    func playerDidFinishPlaying(note: NSNotification) { 
        // add logic to handle out of bounds index for array 
        currentTrackIndex += 1
        playTrack(at: currentTrackIndex)
    }

}

Upvotes: 1

Related Questions