Swift 4中如何为AVAudioPlayer添加HTTP基础认证
解决Swift 4中AVAudioPlayer加载带HTTP基础认证的远程MP3问题
你遇到的问题很典型——AVAudioPlayer的contentsOf:初始化方法只接受URL或Data类型,没法直接传入URLRequest来处理HTTP基础认证。不过有两种靠谱的解决办法,你可以根据自己的需求选择:
方案1:先下载带认证的音频数据,再初始化AVAudioPlayer
这种方式适合音频文件体积较小的场景,先通过URLSession发起带认证的请求获取音频数据,再用Data来初始化AVAudioPlayer。
let username = "my_username" let password = "my_password" let loginString = String(format: "%@:%@", username, password) // 生成Base64编码的认证字符串 guard let loginData = loginString.data(using: .utf8) else { self.endPlayback() return } let base64LoginString = loginData.base64EncodedString() // 构造请求(注意:加载音频一般用GET方法,除非你的服务器明确要求POST) guard let url = URL(string: "https://audio.my_domain.com/\(hashKey)/my_file.mp3") else { self.endPlayback() return } var request = URLRequest(url: url) request.httpMethod = "GET" request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization") // 发起异步请求下载音频数据 let task = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in guard let self = self else { return } // 处理请求错误 if let error = error { print("音频下载失败:\(error.localizedDescription)") self.endPlayback() return } // 确保获取到有效数据 guard let audioData = data else { print("未获取到音频数据") self.endPlayback() return } // 回到主线程初始化播放器(UI/音频操作必须在主线程) DispatchQueue.main.async { do { let audioPlayer = try AVAudioPlayer(data: audioData) // 可选:设置播放器代理,监听播放完成、错误等事件 audioPlayer.delegate = self audioPlayer.prepareToPlay() audioPlayer.play() } catch { print("播放器初始化失败:\(error.localizedDescription)") self.endPlayback() } } } task.resume()
方案2:用AVPlayer替代AVAudioPlayer(推荐流媒体场景)
如果你的音频文件较大,或者想要实现流媒体播放(无需等待全部下载完成即可开始播放),AVPlayer是更好的选择——它支持直接传入带认证的URLRequest,原生处理认证逻辑。
let username = "my_username" let password = "my_password" let loginString = String(format: "%@:%@", username, password) guard let loginData = loginString.data(using: .utf8) else { self.endPlayback() return } let base64LoginString = loginData.base64EncodedString() guard let url = URL(string: "https://audio.my_domain.com/\(hashKey)/my_file.mp3") else { self.endPlayback() return } // 方式1:用URLRequest初始化AVPlayerItem var request = URLRequest(url: url) request.httpMethod = "GET" request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization") let playerItem = AVPlayerItem(urlRequest: request) // 方式2:直接传入URL和headers字典(更简洁) // let playerItem = AVPlayerItem(url: url, headers: ["Authorization": "Basic \(base64LoginString)"]) // 初始化AVPlayer并开始播放 let avPlayer = AVPlayer(playerItem: playerItem) avPlayer.play() // 可选:监听播放完成事件 NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying(_:)), name: .AVPlayerItemDidPlayToEndTime, object: avPlayer.currentItem)
额外说明
AVAudioPlayer的设计定位是处理本地文件或无需复杂请求逻辑的远程音频,它内部不会解析URLRequest中的认证信息,因此无法直接通过URLRequest初始化。而AVPlayer则是为流媒体场景设计的,支持自定义请求头、认证等复杂网络逻辑,功能更强大。
内容的提问来源于stack exchange,提问作者CodeLikeBeaker
相关产品推荐
相关产品推荐

