首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Swift、AVAssetResourceDelegate中的Fairplay实施

Swift、AVAssetResourceDelegate中的Fairplay实施
EN

Stack Overflow用户
提问于 2018-01-19 20:11:44
回答 1查看 2.5K关注 0票数 4

我看了苹果的FairPlay介绍视频,我读了这段代码:https://gist.github.com/fousa/5709fb7c84e5b53dbdae508c9cb4fadc和我还通过苹果的HLS目录,最后的问题是,我只需要播放FairPlay视频没有任何下载和所有这些东西,所以我从GitHub示例开始。我有一个证书,视频在FairPlay和密钥服务器模块。我的第一个也是主要的问题是,当我为AVURLAsset提供视频url时,AVResourceDelegate没有调用。我在堆栈上读到我需要将方案更改为其他内容,例如https中的"DRM“和正确的AVResourceDelegate调用,但我没有.m3u8文件,因为视频链接是错误的!你们能帮帮我吗?

代码语言:javascript
运行
复制
import Foundation
import AVKit
import NotificationCenter

public struct DRMVideoData{
   var drmKey: String?
   var proxyFairPlay: String
   var fileFairPlay: String
   var idVideo: String
}

class VODDRMImplementation: NSObject, AVAssetResourceLoaderDelegate {

let domain = "DRMDelegate.ContentKeyQueue"
let contentKeyDelegateQueue = DispatchQueue(label: "DRMDelegate.ContentKeyQueue")

var drmData: DRMVideoData?

func startPlayerWithDRM(_ videoDRM: DRMVideoData,_ player: AVPlayer?,_ playerLayer: AVPlayerLayer?, c: @escaping (AVPlayer?, AVPlayerLayer?) -> Void) {

    var urlcomp = URLComponents(string: videoDRM.fileFairPlay)

    urlcomp?.scheme = "drm"

    if let url = try? urlcomp?.asURL(){

        self.drmData = videoDRM

        let url = url

        let asset = AVURLAsset(url: url!)
        asset.resourceLoader.setDelegate(self, queue: self.contentKeyDelegateQueue)

        let playerItem = AVPlayerItem(asset: asset)
        let player = AVPlayer(playerItem: playerItem)
        let playerLayer = AVPlayerLayer(player: player)
        player.pause()

        c(player, playerLayer)
    }else{
        c(nil, nil)
    }

    }

func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
    log.debug("DRM: started")

    // getting data for KSM server
    guard let urlToConvert = loadingRequest.request.url,
        let drmData = drmData else {
            log.debug("DRM: unable to read URL from loadingRequest")
            loadingRequest.finishLoading(with: NSError(domain: domain, code: -1, userInfo: nil))
            return false
    }

    do{

        log.debug("DRM: video link \(urlToVideo)")

        guard let certificateData = getCertificateFromServer() else {
                log.debug("DRM: false to get public certificate")
                loadingRequest.finishLoading(with: NSError(domain: domain, code: -3, userInfo: nil))
                return false
        }

        let contentId = drmData.idVideo // content id
        guard let contentIdData = contentId.data(using: String.Encoding.utf8),
            let spcData = try? loadingRequest.streamingContentKeyRequestData(forApp: certificateData, contentIdentifier: contentIdData, options: nil),
            let dataRequest = loadingRequest.dataRequest else {
                loadingRequest.finishLoading(with: NSError(domain: domain, code: -3, userInfo: nil))
                log.debug("DRM: false to get SPC Data from video")
                return false
        }

        let ksmServer = URL(string: drmData.proxyFairPlay)! // KSM link
        var request = URLRequest(url: ksmServer)
        request.httpMethod = "GET"
        request.httpBody = spcData
        let session = URLSession(configuration: .default)
        let task = session.dataTask(with: request) { data, response, error in
            guard let data = data else {
                log.debug("DRM: unable to fetch ckc key :/")
                loadingRequest.finishLoading(with: NSError(domain: self.domain, code: -4, userInfo: nil))
                return
            }
            dataRequest.respond(with: data)
            loadingRequest.finishLoading()
        }
        task.resume()

    }catch{
        loadingRequest.finishLoading(with: NSError(domain: domain, code: -3, userInfo: nil))
        log.debug("DRM: cannot generate url to video")
        return false
    }


    return true


}

func takeURLFromId(_ videoLink: String) -> URL{
    let urlString = videoLink
    let url = URLComponents(string: urlString)
    do{
        let urlToReturn = try url?.asURL()
        guard let urlToReturn2 = urlToReturn else {
            let error = NSError(domain: domain, code: 0, userInfo: nil)
            throw error }
        return urlToReturn2
    }catch{
        if let url = NSURL(string: videoLink){
            return url as URL
        }else{
            return NSURL(string: videoLink)! as URL
        }
    }

}

func getCertificateFromServer() -> Data?{
    let filePath = Bundle.main.path(forResource: "privatekey", ofType: "pem")

    guard let data = try? Data(contentsOf: URL(string: filePath!)!) else {
        return nil
    }

    return data
}

}
EN

回答 1

Stack Overflow用户

发布于 2019-01-07 17:27:14

您可以尝试更改行:

player.pause()player.play()

此外,我认为在你的类中保留对玩家的引用应该会有所帮助,如下所示:

代码语言:javascript
运行
复制
var player: AVPlayer?
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48340839

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档