4
votes

I'm trying to play mp3 from Data file I downloaded with Alamofire. The song is fine, I can play it with AVAudioPlayer(data: Data). How should I play the same Data file with AVPlayer? I could not find how to create PlayerItem from Data or AVAsset from Data. Also, I've the url for the song path, but that URL does not work with AVPlayer somehow. Music is just not playing.

func startSong(withIndex: Int) {
    if let item = getItem(atIndex: withIndex) {
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            print("AVAudioSession Category Playback OK")
            do {
                try AVAudioSession.sharedInstance().setActive(true)
                print("AVAudioSession is Active")
            } catch let error as NSError {
                print(error.localizedDescription)
            }
            let playerItem = item
            self.player = AVPlayer(playerItem: playerItem)
        } catch let error as NSError {
            print(error.localizedDescription)
        }
    }
}

func getItem(atIndex: Int) -> AVPlayerItem? {

    var item: AVPlayerItem

    var url: URL

    let song = playlist.getSong(index: atIndex)

    if PlaylistsService.sharedService.isFileDownloaded(inPath: SongPath.Offline(id: (song?.getID())!).path()) {
        url = URL(fileURLWithPath: SongPath.Offline(id: (song?.getID())!).path())
    } else if PlaylistsService.sharedService.isFileDownloaded(inPath: SongPath.Temp(id: (song?.getID())!).path()) {
        url = URL(fileURLWithPath: SongPath.Temp(id: (song?.getID())!).path())
    } else {
        self.downloadSong(song: song!)
        url = URL(fileURLWithPath: SongPath.Temp(id: (song?.getID())!).path())
    }

    item = AVPlayerItem(url: url)

    return item
}

@IBAction func playPause(_ sender: UIButton) {
    sender.isSelected = !sender.isSelected
    if sender.isSelected {
        print("Play")
        self.player.play()
    } else {
        print("Pause")
        self.player.pause()
    }
}
1
Put a breakpoint on self.player.play(). Does that line actually execute?matt
Yes it does. prntscr.com/d4njv4sphynx
Okay, at the point where you say self.player.play(), you could try logging some further info about the state of the player. What is its currentTime? What is its currentItem? If it has an item, what is that item's status? What is that item's asset?matt
It prints kinda correct info: prntscr.com/d4nnmmsphynx
Where you're logging the status, log instead the status.rawValue. That will give us a value in the console that we can actually read. We really would like to know if there's a status issue with this thing.matt

1 Answers

4
votes

Just found out that AVPlayerItem cannot create object from URL that points to Data file. You need to have URL with file extension ".mp3" for instance. Everything is working now when I've added the extension to path for downloading and playback.