Skip to content

Instantly share code, notes, and snippets.

@neha-bansal790
Last active March 24, 2022 07:00
Show Gist options
  • Save neha-bansal790/07ba129ead78534668abc1ae0a82dd13 to your computer and use it in GitHub Desktop.
Save neha-bansal790/07ba129ead78534668abc1ae0a82dd13 to your computer and use it in GitHub Desktop.
DRM fairplay with hls integration
//
// DRMFairplay.swift
// Collection
//
// Created by B0203948 on 04/02/20.
// Copyright © 2020 wynk. All rights reserved.
//
import UIKit
import AVFoundation
class DRMFairplay: AVPlayer {
private let queue = DispatchQueue(label: "com.icapps.fairplay.queue")
func play(asset: AVURLAsset) {
// Set the resource loader delegate to this class. The `resourceLoader`'s delegate will be
// triggered when FairPlay handling is required.
asset.resourceLoader.setDelegate(self as? AVAssetResourceLoaderDelegate, queue: queue)
// Load the asset in the player.
let item = AVPlayerItem(asset: asset)
// Set the current item in this player instance.
replaceCurrentItem(with: item)
// Start playing the item. From the moment the `play` is triggered the `resourceLoader` will
// do the rest of the work.
play()
}
func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
// We first check if a url is set in the manifest.
guard loadingRequest.request.url != nil else {
print("failed...", #function, "Unable to read the url/host data.")
loadingRequest.finishLoading(with: NSError(domain: "com.domain.error", code: -1, userInfo: nil))
return false
}
// When the url is correctly found we try to load the certificate date. Watch out! For this
// example the certificate resides inside the bundle. But it should be preferably fetched from
// the server.
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
}
// Request the Server Playback Context.
let contentId = "somehls_1234"
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: "com.domain.error", code: -3, userInfo: nil))
print("failed...", #function, "Unable to read the SPC data.")
return false
}
// Request the Content Key Context from the Key Server Module.
let ckcURL = URL(string: "https://www.abc.com/ckc")!
var request = URLRequest(url: ckcURL)
request.httpMethod = "POST"
request.httpBody = spcData
let session = URLSession(configuration: URLSessionConfiguration.default)
let task = session.dataTask(with: request) { data, response, error in
if let data = data {
// The CKC is correctly returned and is now send to the `AVPlayer` instance so we
// can continue to play the stream.
dataRequest.respond(with: data)
loadingRequest.finishLoading()
} else {
print("failed....", #function, "Unable to fetch the CKC.")
loadingRequest.finishLoading(with: NSError(domain: "com.domain.error", code: -4, userInfo: nil))
}
}
task.resume()
return true
}
}
@neha-bansal790
Copy link
Author

DRM integration with HLS Fairplay protected content

@15kiortiz
Copy link

would this still work or has this been updated?
thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment