Ahora toca el turno para configurar FairPlay (DRM) en el ShakaPlayer .
Al inicio debemos obtener el certificado de FairPlay proporcionado por el servidor de DRM al cual debemos tener acceso, el certificado puede ser descargado con fetch
algo asi:
fetch("FAIRPLAY_CERT_URL")
.then((res) => res.arrayBuffer())
.then((buffer) => setCert(buffer))
.catch((error) => console.log(error));
Una vez obtenido el certificado, hay que configurar ShakaPlayer con dos filtros, primero en el Request
para poder mandar con un formato especial el spc=
y otro filtro en el Response
para poder convertir la respuesta en un formato que pueda ser leĆdo por el ShakaPlayer.
// TODO: Fetch FairPlay certificate
const cert = "<CERT_BUFFER>";
// Detect type of DRM supported
const isFairPlaySupported = async () => {
const config = {
initDataTypes: ["cenc", "sinf", "skd"],
videoCapabilities: [{ contentType: 'video/mp4; codecs="avc1.42E01E"' }],
};
try {
await navigator.requestMediaKeySystemAccess("com.apple.fps", [config]);
return true;
} catch (error) {
return false;
}
};
const videoEl = document.getElementById("video");
const player = new shaka.Player(videoEl);
// WideVine and PlayReady
player.configure({
drm: {
servers: {
"com.widevine.alpha": "https://<DRM_SERVER>/WideVine/",
"com.microsoft.playready": "https://<DRM_SERVER>/PlayReady/",
"com.apple.fps.1_0": "skd://<DRM_SERVER>/FairPlay".replace("skd://", "https://"),
},
advanced: {
"com.widevine.alpha": {
videoRobustness: "SW_SECURE_CRYPTO",
audioRobustness: "SW_SECURE_CRYPTO",
},
},
},
});
// FairPlay
player.configure("drm.advanced.com\\.apple\\.fps\\.1_0.serverCertificate", shaka.util.BufferUtils.toUint8(cert));
player.getNetworkingEngine().registerRequestFilter((type, request) => {
if (type !== shaka.net.NetworkingEngine.RequestType.LICENSE) {
return;
}
request.headers["Authorization"] = "<DRM_TOKEN>";
if (isFairPlaySupported) {
const originalPayload = shaka.util.BufferUtils.toUint8(request.body);
const base64Payload = encodeURI(btoa(String.fromCharCode(...originalPayload)));
request.headers["Content-Type"] = "application/x-www-form-urlencoded";
request.body = shaka.util.StringUtils.toUTF8(`spc=${base64Payload}`);
}
});
player.getNetworkingEngine().registerResponseFilter((type, response) => {
if (type !== shaka.net.NetworkingEngine.RequestType.LICENSE) {
return;
}
if (isFairPlaySupported) {
const responseText = shaka.util.StringUtils.fromUTF8(response.data);
const b64key = responseText.trim().slice(5, -6);
const key = new Uint8Array(atob(b64key).split("").map((c) => c.charCodeAt(0)));
response.data = key;
}
});
const play = async () => {
try {
await player.load(isFairPlaySupported ? "<HSL_VIDEO_URL>" : "<MPEG_DASH_URL>");
videoEl.play();
} catch (error) {
console.log("Error:", error);
}
};
play();
Relacionados: