如何下载并保存音频文件然后快速播放?
Posted
技术标签:
【中文标题】如何下载并保存音频文件然后快速播放?【英文标题】:How to download and save an audio file and then play it in swift? 【发布时间】:2019-05-17 22:04:20 【问题描述】:我正在尝试从 Internet 下载音频文件并将其保存到手机上。这是下载功能:
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()
然后,在我关闭并打开应用程序后,我使用以下函数检索 url 并使用 AVPlayer 播放它:
func getUrl2()
if let audioUrl = downloadUrl
// then lets create your document folder url
let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
destinationUrl = documentsDirectoryURL.appendingPathComponent(audioUrl.lastPathComponent)
if let u = self.destinationUrl
let player = AVPlayer(url: u)
print(u)
print("Bouta play")
print(CMTimeGetSeconds(player.currentItem!.duration))
player.play()
不断打印出来的持续时间是“nan”。有没有办法检查音频文件是否真的在下载?或者下载后检索文件是否有问题?提前致谢。
【问题讨论】:
【参考方案1】:首先,您必须使用以下逻辑检查 URL 是否为空:
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
【讨论】:
嘿,你检查我的答案了吗? 如果duration
无法解决,(audioPlayer?.duration ?? 0)
会不会给出除以零的错误?以上是关于如何下载并保存音频文件然后快速播放?的主要内容,如果未能解决你的问题,请参考以下文章
当从 uri 播放视频或音频时,它是流式传输还是完全下载并播放?