如何下载并保存音频文件然后快速播放?

时间:2019-05-17 22:04:20

标签: ios swift xcode avplayer

我正在尝试从Internet下载音频文件并将其保存到手机上。这是下载功能:


httpModule.request({
    url: "http://api.rideuta.com/SIRI/SIRI.svc/VehicleMonitor/ByRoute?route=3&onwardcalls=true&usertoken=UTBPQBLBFV7",
    method: "GET"
}).then((res) => {
    // Argument (response) is HttpResponse
    console.log(res);
}, (e) => {
    console.log(e);
});

I'm just trying to get basic data to return or display.

然后,在我关闭并打开该应用程序之后,我使用以下函数来检索该网址并使用AVPlayer播放该网址:

func download() {
    if let audioUrl = downloadUrl {

        // then lets create your document folder url
        let documentsDirectoryURL =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

        // lets create your destination file url
        let destinationUrl = documentsDirectoryURL.appendingPathComponent(audioUrl.lastPathComponent)
        print(destinationUrl)

        // to check if it exists before downloading it
        if FileManager.default.fileExists(atPath: destinationUrl.path) {
            print("The file already exists at path")

            // if the file doesn't exist
        } else {

            // you can use NSURLSession.sharedSession to download the data asynchronously
            URLSession.shared.downloadTask(with: audioUrl, completionHandler: { (location, response, error) -> Void in
                guard let location = location, error == nil else { return }
                do {
                    // after downloading your file you need to move it to your destination url
                    try FileManager.default.moveItem(at: location, to: destinationUrl)
                    print("File moved to documents folder")
                } catch let error as NSError {
                    print(error.localizedDescription)
                }
            }).resume()
        }
    }
}

持续打印的持续时间为“ nan”。有没有办法检查音频文件是否正在下载?还是在下载后检索文件会出现问题?预先感谢。

1 个答案:

答案 0 :(得分:0)

首先,您需要使用以下逻辑检查网址是否为空:

if !link.isEmpty{
        checkBookFileExists(withLink: link){ [weak self] downloadedURL in
            guard let self = self else{
                return
            }
            play(url: downloadedURL)
        }
    }

然后checkBookFileExists函数将检查文件是否已经保存,然后再次下载:

    func checkBookFileExists(withLink link: String, completion: @escaping ((_ filePath: URL)->Void)){
    let urlString = link.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
    if let url  = URL.init(string: urlString ?? ""){
        let fileManager = FileManager.default
        if let documentDirectory = try? fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create: false){

            let filePath = documentDirectory.appendingPathComponent(url.lastPathComponent, isDirectory: false)

            do {
                if try filePath.checkResourceIsReachable() {
                    print("file exist")
                    completion(filePath)

                } else {
                    print("file doesnt exist")
                    downloadFile(withUrl: url, andFilePath: filePath, completion: completion)
                }
            } catch {
                print("file doesnt exist")
                downloadFile(withUrl: url, andFilePath: filePath, completion: completion)
            }
        }else{
             print("file doesnt exist")
        }
    }else{
            print("file doesnt exist")
    }
}

然后,如果该文件不存在,则将使用以下功能下载该文件:

func downloadFile(withUrl url: URL, andFilePath filePath: URL, completion: @escaping ((_ filePath: URL)->Void)){
    DispatchQueue.global(qos: .background).async {
        do {
            let data = try Data.init(contentsOf: url)
            try data.write(to: filePath, options: .atomic)
            print("saved at \(filePath.absoluteString)")
            DispatchQueue.main.async {
                completion(filePath)
            }
        } catch {
            print("an error happened while downloading or saving the file")
        }
    }
}

该功能将保存它,您可以使用:

  func play(url: URL) {
    print("playing \(url)")

    do {

        audioPlayer = try AVAudioPlayer(contentsOf: url)
        audioPlayer?.prepareToPlay()
        audioPlayer?.delegate = self
        audioPlayer?.play()
        let percentage = (audioPlayer?.currentTime ?? 0)/(audioPlayer?.duration ?? 0)
        DispatchQueue.main.async {
            // do what ever you want with that "percentage"
        }

    } catch let error {
        audioPlayer = nil
    }

}