iOS下载并播放mp3文件



我正在寻找如何同时下载和播放 mp3 文件的方法。

我可以下载它,保存到本地存储并在之后播放。

但是,我怎样才能同时开始下载和播放它,并在它完全下载后 - 将其保存到本地存储中。我应该使用哪些工具?

目前我使用TCBlobDownload下载,之后我保存它和AVAudioPlay播放。

您可以使用

AVAssetResourceLoader在继续下载时在有足够的数据后立即播放音频文件。

配置resourceloader的委托

var playerAsset: AVAsset!
if fileURL.pathExtension.count == 0 {
    var components = URLComponents(url: fileURL, resolvingAgainstBaseURL: false)!
    components.scheme = "fake" // make custom URL scheme
    components.path += ".mp3"
    playerAsset = AVURLAsset(url: components.url!)
    (playerAsset as! AVURLAsset).resourceLoader.setDelegate(self, queue: DispatchQueue.global())
} else {
    playerAsset = AVAsset(url: fileURL)
}
let playerItem = AVPlayerItem(asset: playerAsset)

然后,读取音频的数据并响应资源加载程序

// MARK: - AVAssetResourceLoaderDelegate methods
func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
    if let url = loadingRequest.request.url {
        var components = URLComponents(url: url, resolvingAgainstBaseURL: false)!
        components.scheme = NSURLFileScheme // replace with the real URL scheme
        components.path = String(components.path.dropLast(4))
        if let attributes = try? FileManager.default.attributesOfItem(atPath: components.url!.path),
            let fileSize = attributes[FileAttributeKey.size] as? Int64 {
            loadingRequest.contentInformationRequest?.isByteRangeAccessSupported = true
            loadingRequest.contentInformationRequest?.contentType = "audio/mpeg3"
            loadingRequest.contentInformationRequest?.contentLength = fileSize
            let requestedOffset = loadingRequest.dataRequest!.requestedOffset
            let requestedLength = loadingRequest.dataRequest!.requestedLength
            if let handle = try? FileHandle(forReadingFrom: components.url!) {
                handle.seek(toFileOffset: UInt64(requestedOffset))
                let data = handle.readData(ofLength: requestedLength)
                loadingRequest.dataRequest?.respond(with: data)
                loadingRequest.finishLoading()
                return true
            } else {
                return false
            }
        } else {
            return false
        }
    } else {
        return false
    }
}

如果你想用目标c来做到这一点,请参考这个

最新更新