ios - 检查 mp3 是否可以在 swift 中播放

标签 ios objective-c swift mp3 avaudioplayer

我正在尝试下载并播放远程 mp3。

基本上:

  1. 用户点击 mp3,
  2. 在后台开始下载
  3. 然后,如果可能的话,就会开始播放。

一切都工作得很好 - 下载是由 AFHTTPRequestOperation 执行的,它将 mp3 直接下载到文件中,并且每隔 1000 字节左右我就会得到进度更新。

The problem is I don't know exactly when to start playback via AVAudioPlayer.

AVAudioPlayer 可以播放未完成的 mp3,但如果没有足够的数据,它会触发 fatalError (EXC_BREAKPOINT) 并且我的应用程序崩溃

  • it doesn't even return an error.

我事先知道 mp3 的持续时间,从中我可以确定大约。下载播放的秒数,例如 - (sizeDownloaded/totalSize)*duration,但这很愚蠢,有时会失败(我猜测是由于文件开头有 ID3 标签)文件,它可以包含巨大的图像(我的近似值是没有意义的)。

我当前的代码:

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
        }
    }
})

那么,是否有一些可靠的方法来确定文件是否可以播放?

我知道提高播放开始的限制会有所帮助,但这似乎并不正确。 “等到下载完成”不是答案......:)

非常感谢!

最佳答案

了解 mp3 文件的比特率可以让您估计需要多少文件才能安全地开始播放,但谁知道如果文件在播放后发生更改,AVAudioPlayer 会做什么打开了吗?

如果您在播放完毕后不需要保留mp3,您可以从只能播放本地文件的AVAudioPlayer切换到AVPlayer它还可以播放从互联网流式传输的文件:

 var url = NSURL(string:"http://YOUR_URL")
 player = AVPlayer(URL:url)
 player.play()

一旦有足够的数据可用于持续播放,它将立即播放。

如果您想保留 AVPlayer 正在播放的流字节,事情会变得更加复杂,但可以通过 AVAssetResourceLoader 来实现,详细信息请参见 this blog post

更新 如果您想在后台下载多个文件,那就这么做吧!您仍然可以通过 AVAssetResourceLoader 将数据交给 AVPlayerAVPlayer 将决定何时有足够的数据用于播放(这就是您的意思可以玩吗?)

关于ios - 检查 mp3 是否可以在 swift 中播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30263089/

相关文章:

ios - 如何描画CGPath?

ios - 关闭删除多个 View

ios - 了解 iOS 中的收据验证和收据刷新

ios - 出现键盘时如何使 View Controller 滚动到文本字段

objective-c - 在后台执行任务

swift - 以编程方式将约束添加到 Storyboard 上的现有 View

ios - 根据 bool 属性更新mapView图钉颜色

ios - Xcode 使用了错误的本地化

ios - Rx swift : How to add gesture to UILabel?

ios - 父类和子类的 Realm 过滤器