[英]Using AVAudioPlayer fail to play .m4a by Swift 4
I use Alamofire to download the iTunes search Api's trial music. 我使用Alamofire下载iTunes搜索Api的试用音乐。
And when I download finished, I want to play the music. 当我完成下载后,我想播放音乐。
I try to fix it, but it also no sounds to play. 我尝试修复它,但也没有声音播放。
How to solve this problem? 如何解决这个问题呢?
Thanks. 谢谢。
import UIKit
import AVFoundation
import Alamofire
import CryptoSwift
class FirstViewController: UIViewController {
let urlString = "https://audio-ssl.itunes.apple.com/apple-assets-us-std-000001/AudioPreview18/v4/9c/db/54/9cdb54b3-5c52-3063-b1ad-abe42955edb5/mzaf_520282131402737225.plus.aac.p.m4a"
override func viewDidLoad() {
super.viewDidLoad()
let destination: DownloadRequest.DownloadFileDestination = { _, _ in
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileName = self.urlString.md5()
let fileURL = documentsURL.appendingPathComponent("\(fileName).m4a")
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
Alamofire.download(urlString, to: destination).response { response in
if response.error == nil {
var audioPlayer: AVAudioPlayer!
do {
audioPlayer = try AVAudioPlayer(contentsOf: response.destinationURL!)
audioPlayer.prepareToPlay()
audioPlayer.play()
} catch {
print("Error:", error.localizedDescription)
}
}
}
}
}
The problem is caused by the fact that audioPlayer
is a local variable, therefore it gets deallocated when you leave the scope of completion closure. 问题是由于
audioPlayer
是局部变量,因此,当您离开完成关闭范围时,它会被释放。 Because audioPlayer
isn't retained anywhere else, the moment you leave the closure's scope, audioPlayer
reference count is equal to 0
, which causes ARC to deallocate it. 因为
audioPlayer
不会保留在其他任何地方,所以当您离开闭包的作用域时, audioPlayer
引用计数就等于0
,这将导致ARC取消分配它。
Also, you use force unwrapping operator - !
另外,您可以使用强制展开运算符-
!
- a lot, which is: -很多,这是:
1) incorrect 1)不正确
2) unsafe 2)不安全
Use either if let
construct or guard
statement if let
构造或guard
语句使用
What you need to to is store the player as instance variable of your FirstViewController
class. 您需要将播放器存储为
FirstViewController
类的实例变量。
class FirstViewController: UIViewController {
let urlString = "https://audio-ssl.itunes.apple.com/apple-assets-us-std-000001/AudioPreview18/v4/9c/db/54/9cdb54b3-5c52-3063-b1ad-abe42955edb5/mzaf_520282131402737225.plus.aac.p.m4a"
var audioPlayer : AVAudioPlayer?
override func viewDidLoad() {
super.viewDidLoad()
// (...)
Alamofire.download(urlString, to: destination).response { [weak self] (response) in
if response.error == nil {
guard let url = response.destinationURL else { return }
do {
self?.audioPlayer = try AVAudioPlayer(contentsOf: url)
self?.audioPlayer?.prepareToPlay()
self?.audioPlayer?.play()
} catch {
print("Error:", error.localizedDescription)
}
}
}
}
}
Just move audioPlayer to controller 只需将audioPlayer移至控制器
class FirstViewController: UIViewController {
let urlString = "https://audio-ssl.itunes.apple.com/apple-assets-us-std-000001/AudioPreview18/v4/9c/db/54/9cdb54b3-5c52-3063-b1ad-abe42955edb5/mzaf_520282131402737225.plus.aac.p.m4a"
var audioPlayer: AVAudioPlayer?
//Downloading code......
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.