ios - 从mp3文件下载仅几秒钟

时间:2017-03-15 15:59:18

标签: ios download mp3 nsurlsession

我需要下载一个mp3文件,但我只需要歌曲的前20秒(如果歌曲少于20秒,则需要整首歌曲)。
这是我下载整首歌的方式:

    func downloadSong(audioUrl: URL) {

    let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    let destinationUrl = documentsDirectoryURL.appendingPathComponent(audioUrl.lastPathComponent)

    URLSession.shared.downloadTask(with: audioUrl, completionHandler: { (location, response, error) -> Void in
        guard let location = location, error == nil else { return }
        do {

            try FileManager.default.moveItem(at: location, to: destinationUrl)
            // song available in destinationUrl

        } catch let error as NSError {

        }
    }).resume()
}

有没有办法在20秒后停止下载? 我知道我可以下载整首歌然后剪下来,但我想要更高效,特别是如果这首歌很长。

4 个答案:

答案 0 :(得分:7)

  MP3文件分为小块 - 帧。每个框架都有   恒定时间长度0.026秒。但是一帧的大小(以字节为单位)   根据比特率而变化。例如。对于128kbps,它(通常)为417   字节数和192kbps 626字节。每帧的前4个字节是   帧头,其余是音频数据。

引自here

每个帧都可以播放。因此,对于20秒的数据,您需要大约770 frames(20/0.026)。  因此,首先下载770帧,然后取消下载任务。然后播放下载的帧。

或按大小,首先下载128kbps文件的数据313.5 KB(计算为:(417 Bytes*770)/1024)。你将获得20秒的数据。

答案 1 :(得分:2)

您必须将音频文件剪切为20秒,然后才能下载。

答案 2 :(得分:2)

在我的一个申请中,我也面临过这样的挑战。经过搜索,我终于得出结论,这是不可能的。下载mp3文件时,其内部algorithm具有根据帧的作用。 因此,我们无法预测任何关于我们下载的音频的秒数或分钟数。

此外,您可以参考此链接。

Download last 30 seconds of an mp3

答案 3 :(得分:1)

从我的观点来看,这绝对是可能的,只有很少的假设:

  • 服务器应支持Content-Range标题
  • 你需要一些内部mp3结构的知识(或好的库)

这个想法:

通过在范围内请求此计数从服务器下载500 kb。那你有两个选择:

  1. 快速和肮脏 - 交叉手指并直接向玩家提供这些数据,看看会发生什么:)
  2. 将接收到的数据提供给支持mp3的库(或手动解析标头)。在元数据中修补文件长度,然后尝试这次播放肯定