# Apple FairPlay
Note
ฟีเจอร์ DRM ของ ByteArk Player รองรับเฉพาะผู้ใช้ ByteArk Video Cloud for Business หากคุณต้องการใช้งานกรุณาติดต่อ sales@byteark.com
ByteArk Player SDK for iOS รองรับ Apple FairPlay Streaming (FPS) (opens new window) สำหรับการเล่นวิดีโอที่ป้องกันด้วย DRM ในการเปิดใช้งานฟีเจอร์นี้ คุณต้อง implement protocol ByteArkPlayerDrmDataSource เมื่อ SDK ตรวจพบเนื้อหาที่เข้ารหัสด้วย FairPlay จะร้องขอข้อมูลและ Key ที่จำเป็นสำหรับการถอดรหัสจากแอปของคุณ
ข้อควรระวัง
FairPlay decryption ทำงานได้บนอุปกรณ์จริงเท่านั้น ไม่สามารถใช้งานบน Simulator ได้
ByteArkPlayerDrmDataSource Protocol
// A dataSource requests the necessary data to decrypt Apple FairPlay Drm content
@objc public protocol ByteArkPlayerDrmDataSource: AnyObject {
/// Called when player needs to decrypt the current protected content and requires a content identifier (content id) from the application to start the decryption process
///
/// - Parameters:
/// - url: The url of the resource being loaded.
/// - completionHandler: The handler block used to provide the content identifier to the ByteArk Player.
///
func contentIdentifier(for url: URL, completionHandler handler: @escaping (_ contentIdentifier: Data?) -> Void)
/// Called when player needs to decrypt the current protected content and requires an application certificate from the application to start the decryption process
///
/// - Parameters:
/// - url: The url of the resource being loaded.
/// - completionHandler: The handler block used to provide the application certificate to the ByteArk Player, the Application Certificate data you receive after registering an FPS playback app.
///
func applicationCertificate(for url: URL, completionHandler handler: @escaping (_ certificate: Data?) -> Void)
/// Called when player needs to decrypt the current protected content and requires a content key from the application to start the decryption process
///
/// - Parameters:
/// - spcData: The SPC (Server Playback Context) message from the operating system which must be sent to the Key Server in order to obtain the CKC (Content Key Context) message.
/// - completionHandler: The completion block used to provide CKC (Content Key Context) that received from the Server Response to the ByteArk Player.
///
func contentKey(with spcData: Data, completionHandler handler: @escaping (_ ckcData: Data?) -> Void)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Implementation
ข้อควรระวัง
การถอดรหัส FairPlay สามารถใช้งานได้เฉพาะบนอุปกรณ์จริงเคุณั้น และจะไม่ทำงานบนตัวจำลอง (simulator)
- Implement the
contentIdentifier(for url: URL, completionHandler handler: @escaping (_ contentIdentifier: Data?) -> Void)delegate method in your class
This delegate method requests the identifier for the protected content to be passed through the delegate method's completion block.
func contentIdentifier(for url: URL, completionHandler handler: @escaping (Data?) -> Void) {
// extract content identifier from url
if #available(iOS 16.0, *) {
handler(url.host()?.data(using: .utf8))
} else {
// Fallback on earlier versions
handler(url.host?.data(using: .utf8))
}
}
2
3
4
5
6
7
8
9
- Implement the
applicationCertificate(for url: URL, completionHandler handler: @escaping (_ certificate: Data?) -> Void)delegate method in your class
This delegate method requests an Application Certificate binary which must be passed through the completion block.
func applicationCertificate(for url: URL, completionHandler handler: @escaping (Data?) -> Void) {
// request an application certificate from server
var request = URLRequest(url: URL(string: "APPLICATION_CERTIFICATE_URL")!)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
handler(data)
}
task.resume()
}
2
3
4
5
6
7
8
9
10
11
- Implement the
contentKey(with spcData: Data, completionHandler handler: @escaping (_ ckcData: Data?) -> Void)delegate method in your class
This delegate method provides the SPC (Server Playback Context) message from the operating system which must be sent to the Key Server in order to obtain the CKC (Content Key Context) message. The CKC message must be returned via the completion block under the response parameter.
func contentKey(with spcData: Data, completionHandler handler: @escaping (Data?) -> Void) {
var request = URLRequest(url: URL(string: "APPLE_FAIRPLAY_KEY_SERVER_URL")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
// convert spc to base64 and set json body
let json: [String: Any] = [ "spc": spcData.base64EncodedString() ]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data,
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
let ckcString = json["ckc"] as? String,
let ckcData = Data(base64Encoded: ckcString)
else {
handler(nil)
return
}
handler(ckcData)
}
task.resume()
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- Set your
ByteArkPlayerDrmDataSourceimplementation toByteArkPlayerItemBuilder.
do {
let item = try ByteArkPlayerItemBuilder()
.title("FairPlay Source")
.media(URL(string: "FAIRPLAY_MEDIA_URL")!)
.drmDataSource(YOUR_DRM_DATA_SOURCE_IMPLEMENTATION)
.build()
let config = try ByteArkPlayerConfigBuilder()
.autoplay(true)
.item(item)
.build()
bytearkPlayerViewController.player.configure(with: config)
} catch {
print(error.localizedDescription)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16