react-native-video/ios/Video/Features/RCTVideoErrorHandling.swift
Krzysztof Moch 0e4c95def9
feat(iOS): rewrite DRM Module (#4136)
* minimal api

* add suport for `getLicense`

* update logic for obtaining `assetId`

* add support for localSourceEncryptionKeyScheme

* fix typo

* fix pendingLicenses key bug

* lint code

* code clean

* code clean

* remove old files

* fix tvOS build

* fix errors loop

* move `localSourceEncryptionKeyScheme` into drm params

* add check for drm type

* use DebugLog

* lint

* update docs

* lint code

* fix bad rebase

* update docs

* fix crashes on simulators

* show error on simulator when using DRM

* fix typos

* code clean
2024-09-20 17:46:10 +02:00

189 lines
9.1 KiB
Swift

import Foundation
// MARK: - RCTVideoError
enum RCTVideoError: Error, Hashable {
case fromJSPart(String)
case noLicenseServerURL
case licenseRequestFailed(Int)
case noDataFromLicenseRequest
case noSPC
case noCertificateData
case noCertificateURL
case noDRMData
case invalidContentId
case invalidAppCert
case keyRequestCreationFailed
case persistableKeyRequestFailed
case embeddedKeyExtractionFailed
case offlineDRMNotSupported
case unsupportedDRMType
case simulatorDRMNotSupported
var errorCode: Int {
switch self {
case .fromJSPart:
return 1000
case .noLicenseServerURL:
return 1001
case .licenseRequestFailed:
return 1002
case .noDataFromLicenseRequest:
return 1003
case .noSPC:
return 1004
case .noCertificateData:
return 1005
case .noCertificateURL:
return 1006
case .noDRMData:
return 1007
case .invalidContentId:
return 1008
case .invalidAppCert:
return 1009
case .keyRequestCreationFailed:
return 1010
case .persistableKeyRequestFailed:
return 1011
case .embeddedKeyExtractionFailed:
return 1012
case .offlineDRMNotSupported:
return 1013
case .unsupportedDRMType:
return 1014
case .simulatorDRMNotSupported:
return 1015
}
}
}
// MARK: LocalizedError
extension RCTVideoError: LocalizedError {
var errorDescription: String? {
switch self {
case let .fromJSPart(error):
return NSLocalizedString("Error from JavaScript: \(error)", comment: "")
case .noLicenseServerURL:
return NSLocalizedString("No license server URL provided", comment: "")
case let .licenseRequestFailed(statusCode):
return NSLocalizedString("License request failed with status code: \(statusCode)", comment: "")
case .noDataFromLicenseRequest:
return NSLocalizedString("No data received from license server", comment: "")
case .noSPC:
return NSLocalizedString("Failed to create Server Playback Context (SPC)", comment: "")
case .noCertificateData:
return NSLocalizedString("No certificate data obtained", comment: "")
case .noCertificateURL:
return NSLocalizedString("No certificate URL provided", comment: "")
case .noDRMData:
return NSLocalizedString("No DRM data available", comment: "")
case .invalidContentId:
return NSLocalizedString("Invalid content ID", comment: "")
case .invalidAppCert:
return NSLocalizedString("Invalid application certificate", comment: "")
case .keyRequestCreationFailed:
return NSLocalizedString("Failed to create content key request", comment: "")
case .persistableKeyRequestFailed:
return NSLocalizedString("Failed to create persistable content key request", comment: "")
case .embeddedKeyExtractionFailed:
return NSLocalizedString("Failed to extract embedded key", comment: "")
case .offlineDRMNotSupported:
return NSLocalizedString("Offline DRM is not supported, see https://github.com/TheWidlarzGroup/react-native-video/issues/3539", comment: "")
case .unsupportedDRMType:
return NSLocalizedString("Unsupported DRM type", comment: "")
case .simulatorDRMNotSupported:
return NSLocalizedString("DRM on simulators is not supported", comment: "")
}
}
var failureReason: String? {
switch self {
case .fromJSPart:
return NSLocalizedString("An error occurred in the JavaScript part of the application.", comment: "")
case .noLicenseServerURL:
return NSLocalizedString("The license server URL is missing in the DRM configuration.", comment: "")
case .licenseRequestFailed:
return NSLocalizedString("The license server responded with an error status code.", comment: "")
case .noDataFromLicenseRequest:
return NSLocalizedString("The license server did not return any data.", comment: "")
case .noSPC:
return NSLocalizedString("Failed to generate the Server Playback Context (SPC) for the content.", comment: "")
case .noCertificateData:
return NSLocalizedString("Unable to retrieve certificate data from the specified URL.", comment: "")
case .noCertificateURL:
return NSLocalizedString("The certificate URL is missing in the DRM configuration.", comment: "")
case .noDRMData:
return NSLocalizedString("The required DRM data is not available or is invalid.", comment: "")
case .invalidContentId:
return NSLocalizedString("The content ID provided is not valid or recognized.", comment: "")
case .invalidAppCert:
return NSLocalizedString("The application certificate is invalid or not recognized.", comment: "")
case .keyRequestCreationFailed:
return NSLocalizedString("Unable to create a content key request for DRM.", comment: "")
case .persistableKeyRequestFailed:
return NSLocalizedString("Failed to create a persistable content key request for offline playback.", comment: "")
case .embeddedKeyExtractionFailed:
return NSLocalizedString("Unable to extract the embedded key from the custom scheme URL.", comment: "")
case .offlineDRMNotSupported:
return NSLocalizedString("You tried to use Offline DRM but it is not supported yet", comment: "")
case .unsupportedDRMType:
return NSLocalizedString("You tried to use unsupported DRM type", comment: "")
case .simulatorDRMNotSupported:
return NSLocalizedString("You tried to DRM on a simulator", comment: "")
}
}
var recoverySuggestion: String? {
switch self {
case .fromJSPart:
return NSLocalizedString("Check the JavaScript logs for more details and fix any issues in the JS code.", comment: "")
case .noLicenseServerURL:
return NSLocalizedString("Ensure that you have specified the 'licenseServer' property in the DRM configuration.", comment: "")
case .licenseRequestFailed:
return NSLocalizedString("Verify that the license server is functioning correctly and that you're sending the correct data.", comment: "")
case .noDataFromLicenseRequest:
return NSLocalizedString("Check if the license server is operational and responding with the expected data.", comment: "")
case .noSPC:
return NSLocalizedString("Verify that the content key request is properly configured and that the DRM setup is correct.", comment: "")
case .noCertificateData:
return NSLocalizedString("Check if the certificate URL is correct and accessible, and that it returns valid certificate data.", comment: "")
case .noCertificateURL:
return NSLocalizedString("Make sure you have specified the 'certificateUrl' property in the DRM configuration.", comment: "")
case .noDRMData:
return NSLocalizedString("Ensure that you have provided all necessary DRM-related data in the configuration.", comment: "")
case .invalidContentId:
return NSLocalizedString("Verify that the content ID is correct and matches the expected format for your DRM system.", comment: "")
case .invalidAppCert:
return NSLocalizedString("Check if the application certificate is valid and properly formatted for your DRM system.", comment: "")
case .keyRequestCreationFailed:
return NSLocalizedString("Review your DRM configuration and ensure all required parameters are correctly set.", comment: "")
case .persistableKeyRequestFailed:
return NSLocalizedString("Verify that offline playback is supported and properly configured for your content.", comment: "")
case .embeddedKeyExtractionFailed:
return NSLocalizedString("Check if the embedded key is present in the URL and the custom scheme is correctly implemented.", comment: "")
case .offlineDRMNotSupported:
return NSLocalizedString("Check if localSourceEncryptionKeyScheme is set", comment: "")
case .unsupportedDRMType:
return NSLocalizedString("Verify that you are using fairplay (on Apple devices)", comment: "")
case .simulatorDRMNotSupported:
return NSLocalizedString("You need to test DRM content on real device", comment: "")
}
}
}
// MARK: - RCTVideoErrorHandler
enum RCTVideoErrorHandler {
static func createError(from error: RCTVideoError) -> [String: Any] {
return [
"code": error.errorCode,
"localizedDescription": error.localizedDescription,
"localizedFailureReason": error.failureReason ?? "",
"localizedRecoverySuggestion": error.recoverySuggestion ?? "",
"domain": "RCTVideo",
]
}
}