ios - 从 mp3 文件下载只需几秒钟

ios - download only few seconds from mp3 file

我需要下载 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 秒后停止下载? 我知道我可以下载整首歌然后剪下来,但我想更有效率,尤其是当歌曲很长的时候。

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

我在我的一个应用程序中也遇到过这样的挑战。之后,搜索了很多我终于得出结论这是不可能的。由于下载 mp3 文件有其自己的内部 algorithm,它根据帧工作。 因此,我们无法预测我们下载了多少秒或分钟的音频。

另外,你可以参考这个link。

Download last 30 seconds of an mp3

MP3 file is divided into a small blocks - frames. Each frame has constant time length 0.026 sec. But size of one frame (in Bytes) varies according to bitrate. Eg. for 128kbps it is (normally) 417 Bytes and for 192kbps 626 Bytes. The first 4 Bytes of each frame is frame header and the rest is audio data.

引自here.

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

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

在我看来,这绝对是可能的,只需几个假设:

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

想法:

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

  1. fast-and-dirty - 交叉手指并将此数据直接提供给玩家,看看会发生什么:)
  2. 将接收到的数据提供给支持 mp3 的库(或手动解析 header)。元数据中的补丁文件长度然后尝试播放它这次肯定