iOS下载并播放mp3文件

问题描述 投票:3回答:1

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

我可以下载它,保存到本地存储中,然后播放。

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

当前,我使用TCBlobDownload进行下载,将其保存后再进行AVAudioPlay播放。

ios objective-c swift avplayer avaudioplayer
1个回答
0
投票

只要继续下载,只要有足够的数据,就可以使用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进行此操作,请参考this

© www.soinside.com 2019 - 2024. All rights reserved.