neekeetab / CachingPlayerItem

Play and cache media content simultaneously on your iOS device
MIT License
520 stars 89 forks source link

player.play() not working #5

Closed Whotan closed 6 years ago

Whotan commented 6 years ago

The player is not playing at all, however the file is downloaded completely.

neekeetab commented 6 years ago

Hi! Sorry for a late response. I haven't been able to reproduce what you described, but my guess is that you don't keep a strong reference to the AVPlayer. If it doesn't help, please feel free to provide your code. We'll figure that out.

Whotan commented 6 years ago

Hi! nope, I keep a strong reference to the AVPlayer. Here is my code: class MusicPlayer: CachingPlayerItemDelegate {

static let sharedInstance = MusicPlayer()
public var playList = songsGetAPI()
public var index : Int = 0
var player : AVPlayer!

private init() {
    print("Music player initialized.")
}

func play(_playlist: songsGetAPI, _index : Int ) {
    self.playList = _playlist
    self.index = _index

    guard let url = URL(string :(playList.results[index]?.file_url)!) else {
        print("url creating failed : " + (playList.results[index]?.file_url)!)
        return
    }

    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        try AVAudioSession.sharedInstance().setActive(true)
        let playerItem = CachingPlayerItem(url: url)
        playerItem.delegate = self
        player = AVPlayer(playerItem:playerItem)
        player.automaticallyWaitsToMinimizeStalling = false
        player.play()

    }catch{}
}
neekeetab commented 6 years ago

I've just run your code and for me everything seems fine. Make sure that a url that you're trying to play ends with a file extension, e.g. ".mp3". Also make sure that the file located by the url is valid and can be played at all. Hope it helps.

Whotan commented 6 years ago

Thanks for your response, unfortunately the url does not end with extention, what should I do about it?

neekeetab commented 6 years ago

Appending file extension to each resource on the backend will work. If you don't have access to the server or use 3rd party APIs, you can use the same technique as i did -- construct a fake url (with custom scheme and, in your case, extra file extension) to feed to AVPlayer and then when it asks you for help with loading the resource, take provided fake url and reconstruct the real one, then download the resource using URLSession. You can achieve this with a little bit of customization of CachingPlayerItem.

Whotan commented 6 years ago

Works fine, thank you so much

neekeetab commented 6 years ago

You're welcome!

NicholasFLee commented 6 years ago

Sorry for comment in this closed-issue,I've encountered the same problem and I can't understand this answer you provided, could you explain more detail? or maybe some code will be great :D .

neekeetab commented 6 years ago

Whotan had an issue with urls that don't end with file extension not being played. The reason for this is that AVPlayerItem determines the type of the file to play from the file's url extension. That said, no url extension -- no playback. But there's a workaround -- we can provide a fake url to AVPlayerItem with a proper extension (like mp3 for an audio file) but then substitute the data requested in AVAssetResourceLoaderDelegate with the data loaded from the actual url (the one without extension). I don't have the code, but Whotan may.