shouldWaitForLoadingOfRequestedResource delegate method not getting called

31 views Asked by At

I'm trying to implement DRM in the app. It's working fine on the sample app, which I downloaded from https://github.com/ankit0812/FairplayTestProj/tree/main. But when I am using the same code on my app, it is not calling the shouldWaitForLoadingOfRequestedResource delegate method. Is there any specific setting that is required in order to get this method called?

@IBAction func playVideo(_ sender: UIButton) {
        let url = URL(string: RESOURCE_URL)!
        
        // Create the asset instance and the resource loader because we will be asked
        // for the license to playback DRM protected asset.
        let asset = AVURLAsset(url: url)
        let queue = DispatchQueue(label: CUSTOM_SERIAL_QUEUE_LABEL)
        asset.resourceLoader.setDelegate(self, queue: queue)
        
        // Create the player item and the player to play it back in.
        let playerItem = AVPlayerItem(asset: asset)
        let player = AVPlayer(playerItem: playerItem)
        
        // Create a new AVPlayerViewController and pass it a reference to the player.
        let controller = AVPlayerViewController()
        controller.player = player
        
        // Modally present the player and call the player's play() method when complete.
        present(controller, animated: true) {
            player.play()
        }
    }
    
    //Please note if your delegate method is not being called then you need to run on a REAL DEVICE
    
    func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
        
        // Getting data for KSM server. Get the URL from tha manifest, we wil need it later as it
        // contains the assetId required for the license request.
        guard let url = loadingRequest.request.url else {
            print(#function, "Unable to read URL from loadingRequest")
            loadingRequest.finishLoading(with: NSError(domain: "", code: -1, userInfo: nil))
            return false
        }
        
        // Link to your certificate on BuyDRM's side.
        // Use the commented section if you want to refer the certificate from your bundle i.e. Store Locally
        
        /*
         guard let certificateURL = Bundle.main.url(forResource: "certificate", withExtension: "der"), let certificateData = try? Data(contentsOf: certificateURL) else {
         print("failed...", #function, "Unable to read the certificate data.")
         loadingRequest.finishLoading(with: NSError(domain: "com.domain.error", code: -2, userInfo: nil))
         return false
         }
         */
        
        guard let certificateData = try? Data(contentsOf: URL(string: CERTIFICATE_URL)!) else {
            print(#function, "Unable to read the certificate data.")
            loadingRequest.finishLoading(with: NSError(domain: "", code: -2, userInfo: nil))
            return false
        }
        
        // The assetId from the main/variant manifest - skd://xxx, the xxx part. Get the SPC based on the
        // already collected data i.e. certificate and the assetId
        guard let contentId = url.host, let contentIdData = contentId.data(using: String.Encoding.utf8) else {
            loadingRequest.finishLoading(with: NSError(domain: "", code: -3, userInfo: nil))
            print(#function, "Unable to read the SPC data.")
            return false
        }
        
        guard
            let spcData = try? loadingRequest.streamingContentKeyRequestData(forApp: certificateData, contentIdentifier: contentIdData, options: nil) else {
            loadingRequest.finishLoading(with: NSError(domain: "", code: -3, userInfo: nil))
            print(#function, "Unable to read the SPC data.")
            return false
        }
        
        // Prepare to get the license i.e. CKC.
        let requestUrl = CKC_URL
        let stringBody = "spc=\(spcData.base64EncodedString())&assetId=\(contentId)"
        let postData = NSData(data: stringBody.data(using: String.Encoding.utf8)!)
        
        // Make the POST request with customdata set to the authentication XML.
        var request = URLRequest(url: URL(string: requestUrl)!)
        request.httpMethod = "POST"
        request.httpBody = postData as Data
        request.allHTTPHeaderFields = ["customdata" : ACCESS_TOKEN]
        let configuration = URLSessionConfiguration.default
        let session = URLSession(configuration: configuration)
        let task = session.dataTask(with: request) { data, response, error in
            if let data = data {
                
                // The response from the KeyOS MultiKey License server may be an error inside JSON.
                do {
                    let parsedData = try JSONSerialization.jsonObject(with: data) as! [String:Any]
                    let errorId = parsedData["errorid"] as! String
                    let errorMsg = parsedData["errormsg"] as! String
                    print(#function, "License request failed with an error: \(errorMsg) [\(errorId)]")
                } catch let error as NSError {
                    print(#function, "The response may be a license. Moving on.", error)
                }
                
                // The response from the KeyOS MultiKey License server is Base64 encoded.
                let dataRequest = loadingRequest.dataRequest!
                
                // This command sends the CKC to the player.
                dataRequest.respond(with: Data(base64Encoded: data)!)
                loadingRequest.finishLoading()
            } else {
                print(#function, error?.localizedDescription ?? "Error during CKC request.")
            }
        }
        
        task.resume()
        
        // Tell the AVPlayer instance to wait. We are working on getting what it wants.
        return true
    }
0

There are 0 answers