具有resourceLoader委托的AVPlayer获取数据但不播放视频

如何解决具有resourceLoader委托的AVPlayer获取数据但不播放视频

这是我第一次在此网站上寻求帮助。我搜索了整个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(将#修改为@)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?