I'm trying to download & play remote mp3s.
Basically:
- User clicks the mp3,
- Download starts on background
- and then, when it's possible, the playback starts.
Everything works almost fine - the download is performed by AFHTTPRequestOperation
which is downloading the mp3 directly into a file and I get progress updates every 1000 Bytes or so.
The problem is I don't know exactly when to start playback via
AVAudioPlayer
.
AVAudioPlayer
can play unfinished mp3, but if there's not enough data it fires fatalError (EXC_BREAKPOINT) and my app crashes
- it doesn't even return an error.
I know in advance the duration of the mp3 from which I can determine approx. how many seconds of playback are downloaded like - (sizeDownloaded/totalSize)*duration
, but that's just silly and sometimes it fails (I'm guessing thanks to the fact that there's ID3 Tag in the beginning of the file and it can contain huge images my approximation is pointless).
My current code:
op.setDownloadProgressBlock({bytesRead, totalBytesRead, totalBytesExpectedToRead in
let approxBytesForOneSecond = totalBytesExpectedToRead/Int64(downloadableItem.length)
let approxSecondsDownloaded = totalBytesRead/approxBytesForOneSecond
if approxSecondsDownloaded > kMinimumSecondsDownloadedForPlay { //min. secs = 5
var error: NSError?
self.player = AVAudioPlayer(contentsOfURL: url, error: &error) // This is the line where I sometimes get EXC_Breakpoint. The reason for this is that the mp3 is not playable yet ...
if (error != nil) {
// Error initializing item - never called
} else {
// Item initialized OK -> Play
}
}
})
So, is there's some solid way of finding out whether the file is playable or not?
I know that raising the limit for playback start would help, it just doesn't seem to be right. And "wait until download is finished" is not an answer... :)
Thanks a lot!