首页 > 解决方案 > 如何在 Swift 4 中将 HTTP 基本身份验证传递给 AVAudioPlayer

问题描述

我正在尝试通过AVAudioPlayerSwift 4 加载远程 MP3。到目前为止,一切都很好。

现在,我正在尝试加载我们的安全 URL,它对 URL 使用基本身份验证。

我所拥有的是:

    let username = "my_username"
    let password = "my_password"
    let loginString = String(format: "%@:%@", username, password)
    let loginData = loginString.data(using: String.Encoding.utf8)!
    let base64LoginString = loginData.base64EncodedString()

    // create the request
    let url = URL(string: "https://audio.my_domain.com/\(hashKey)/my_file.mp3")!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")

    guard let audioPlayer = try? AVAudioPlayer(contentsOf: request) else {
        self.endPlayback()
        return
    }

当然,我得到的错误是:

无法将“URLRequest”类型的值转换为预期的参数类型“URL”

我对此并不感到惊讶,因为 aURL不是URLRequest对象。所以,我的问题是。如何将 URL 流加载到AVAudioPlayer使用基本 HTTP 身份验证中?

我似乎无法找到这样做的任何地方。也许这是不可能的?

标签: swiftswift4avaudioplayer

解决方案


首先,AVAudioPlayer 并不意味着通过网络播放音频

除非您正在播放从网络流中捕获的音频或需要非常低的 I/O 延迟,否则请使用此类进行音频播放。

您需要Data在播放之前将完整的 mp3 文件下载到本地文件或对象中,或者使用AVPlayer替代(旨在能够通过网络播放音频)。

为了创建一个AVPlayer,通过网络播放音频必须首先创建一个AVURLAsset

let asset = AVURLAsset(url: URL(string: "https://example.com/file.mp3")!)

至少有两种方法可以通过 使用基本身份验证AVURLAsset

  1. 使用 AVURLAssetHTTPHeaderFieldsKey设置自定义标头。请注意,此密钥未记录在案。

  2. 将凭证添加到 shared URLCredentialStorage

    let credential = URLCredential(
        user: "username",
        password: "password", 
        persistence: .forSession
    )
    let protectionSpace = URLProtectionSpace(
        host: "example.com",
        port: 443,
        protocol: "https",
        realm: nil,
        authenticationMethod: NSURLAuthenticationMethodHTTPBasic
    )
    URLCredentialStorage.shared.setDefaultCredential(credential, for: protectionSpace)
    

然后你可以AVPlayerItem用你的资产创建一个,最后是一个 AVPlayer:

let playerItem = AVPlayerItem(asset: asset)
let player = AVPlayer(playerItem: playerItem)

推荐阅读