问题描述
这是我第一次在此网站上寻求帮助。我搜索了整个Internet,尝试了很多事情,甚至阅读了文档:),但找不到解决该问题的方法。
我的任务是从需要证书的存储库中播放视频。如果我使用简单的AVPlayer设置而不设置AVAssetResourceLoaderDelegate:
controller.player = AVPlayer(url: urlFromUnprotectedplace)
播放器可以完美打开不受保护的存储中的网址并播放视频。但是在尝试从受保护的文件夹播放视频时,会出现错误:“此服务器的证书无效” 。通过设置resourceLoader委托可以解决此问题:
let asset = AVURLAsset(url: customSchemeUrl)
asset.resourceLoader.setDelegate(myDelegate,queue: .main)
let item = AVPlayerItem(asset: asset)
controller.player = AVPlayer(playerItem: item)
和委托方法本身:
func resourceLoader(
_ resourceLoader: AVAssetResourceLoader,shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest
) -> Bool {
guard let url = url else {
logger.log("nil url")
return false
}
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("bytes=0-",forHTTPHeaderField: "Range")
let sessionTask = urlSession?.dataTask(with: request) { [weak self] data,response,error in
if let error = error {
self?.logger.log(error.localizedDescription)
return
}
loadingRequest.contentinformationRequest?.contentType = AVFileType.mp4.rawValue
loadingRequest.contentinformationRequest?.isByterangeAccessSupported = true
loadingRequest.response = response
if let data = data {
loadingRequest.contentinformationRequest?.contentLength = Int64(data.count)
loadingRequest.dataRequest?.respond(with: data)
}
loadingRequest.finishLoading()
}
sessionTask?.resume()
return true
}
数据和响应到来,错误为nil。数据大小正确。响应包含状态206。播放器的项目具有其状态的观察者,但没有人显示任何错误-播放器只是黑色,而下载轮却在旋转。
但是我走得更远。有这样一个项目:https://github.com/2ZGroupSolutionsArticles/Article_EZ002 我用他的代表代替了我的代表-行为相同。但它也可以将下载的数据保存到本地文件中。因此,如果在保存完成后尝试播放此文件-一切正常,就可以播放。
我的SwiftUI播放器:
final class MyVideoPlayer: UIViewControllerRepresentable {
private let controller = AVPlayerViewController()
private var playerItemObserver: MyPlayerItemStateObserver?
private var resourceLoaderDelegate: EugeneResourceLoaderDelegate?
private var playingStarted = false
init(url: URL?) {
guard let url = url else { return }
resourceLoaderDelegate = EugeneResourceLoaderDelegate(withURL: url)
resourceLoaderDelegate?.completion = downloadCompletion()
controller.player = createPlayer()
}
func makeUIViewController(context: Context) -> AVPlayerViewController {
controller
}
func updateUIViewController(_ uiViewController: AVPlayerViewController,context: Context) {}
func play() -> some View {
playingStarted = true
controller.player?.play()
return self
}
}
extension MyVideoPlayer {
private func createPlayer() -> AVPlayer? {
guard
let delegate = resourceLoaderDelegate,let streamingUrl = delegate.streamingAssetURL
else {
return nil
}
let asset = AVURLAsset(url: streamingUrl)
asset.resourceLoader.setDelegate(delegate,queue: .main)
playerItemObserver = MyPlayerItemStateObserver(asset: asset,logger: logger)
if let item = playerItemObserver?.item {
return AVPlayer(playerItem: item)
}
return nil
}
private func downloadCompletion() -> (URL?) -> Void {
{ [weak self] localFileURL in
guard let self = self else { return }
guard let localFileURL = localFileURL else {
print("Failed to download media file.")
return
}
print("Media file saved to: \(localFileURL)")
let status = self.controller.player?.timeControlStatus
if self.playingStarted && status?.rawValue == 1 {
self.controller.player = AVPlayer(url: localFileURL)
self.controller.player?.play()
}
}
}
}
我认为我已经没有主意了。我将不胜感激。
已更新。在重新创建播放器的状态及其currentItem来播放本地文件之前,我将其打印出来,我得到了:
player?.reasonForWaitingToPlay - AVPlayerWaitingWhileEvaluatingBufferingRateReason
player?.currentItem?.isPlaybackBufferEmpty - true
player?.currentItem?.duration - value: 0
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)