-
Notifications
You must be signed in to change notification settings - Fork 344
/
Copy patheme.js
131 lines (113 loc) · 3.78 KB
/
eme.js
1
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Define a key: hardcoded in this example
// This corresponds to the key used for encryption
var KEY = new Uint8Array([
0x40, 0x6d, 0x5e, 0x65, 0xb8, 0x55, 0x43, 0xf2, 0x49, 0x93, 0x20, 0xd7, 0xf4, 0xb4, 0x2d, 0xfa
]);
function hexStringToByteArray(str) {
var result = new Uint8Array(16);
var i = 0;
while (str.length >= 2) {
if (str.substring(0,1) == ' ') {
str = str.substring(1,str.length);
}
result[i] = parseInt(str.substring(0, 2), 16);
str = str.substring(2, str.length);
i++;
}
return result;
}
function initializeEME(video, mime, key) {
KEY = hexStringToByteArray(key);
// following config returns correctly in Chrome https or http (even localhost)
var configWebM = [{
initDataTypes: ['webm'],
videoCapabilities: [{
contentType: 'video/webm; codecs="vp8"'
}]
}];
var configMp4 = [{
"initDataTypes": ["cenc"],
//"audioCapabilities": [{ "contentType": 'audio/mp4;codecs="mp4a.40.2"', robustness: 'SW_SECURE_CRYPTO' }],
// codecs config is required
"videoCapabilities": [{
contentType: 'video/mp4;codecs="avc1.64001E"'
}]
}];
var configMp4Mime = [{
initDataTypes: ["cenc"],
//"audioCapabilities": [{ "contentType": 'audio/mp4;codecs="mp4a.40.2"', robustness: 'SW_SECURE_CRYPTO' }],
// codecs config is required
videoCapabilities: [{
contentType: 'video/mp4;codecs="avc1.64001E"'
}]
}];
configMp4Mime[0].videoCapabilities[0].contentType = mime;
var WIDEVINE_KEY_SYSTEM = 'com.widevine.alpha';
var CLEARKEY_KEY_SYSTEM = 'org.w3.clearkey';
video.addEventListener('encrypted', handleEncrypted, false);
navigator.requestMediaKeySystemAccess(CLEARKEY_KEY_SYSTEM, configMp4Mime).then(
function(keySystemAccess) {
return keySystemAccess.createMediaKeys();
}
).then(
function(createdMediaKeys) {
return video.setMediaKeys(createdMediaKeys);
}
).catch(
function(error) {
console.error('Failed to set up MediaKeys', error);
}
);
}
function handleEncrypted(event) {
console.log("Encrypted event", event);
//return;
video = event.target;
var session = video.mediaKeys.createSession();
session.addEventListener('message', handleMessage, false);
session.generateRequest(event.initDataType, event.initData).catch(
function(error) {
console.error('Failed to generate a license request', error);
}
);
}
function handleMessage(event) {
console.log('message event: ', event);
// If you had a license server, you would make an asynchronous XMLHttpRequest
// with event.message as the body. The response from the server, as a
// Uint8Array, would then be passed to session.update().
// Instead, we will generate the license synchronously on the client, using
// the hard-coded KEY at the top.
var license = generateLicense(event.message);
console.log('license: ', license);
var session = event.target;
session.update(license).catch(
function(error) {
console.error('Failed to update the session', error);
}
);
}
// Convert Uint8Array into base64 using base64url alphabet, without padding.
function toBase64(u8arr) {
return btoa(String.fromCharCode.apply(null, u8arr)).
replace(/\+/g, '-').replace(/\//g, '_').replace(/=*$/, '');
}
// This takes the place of a license server.
// kids is an array of base64-encoded key IDs
// keys is an array of base64-encoded keys
function generateLicense(message) {
// Parse the clearkey license request.
var request = JSON.parse(new TextDecoder().decode(message));
// We only know one key, so there should only be one key ID.
// A real license server could easily serve multiple keys.
console.assert(request.kids.length === 1);
var keyObj = {
kty: 'oct',
alg: 'A128KW',
kid: request.kids[0],
k: toBase64(KEY)
};
return new TextEncoder().encode(JSON.stringify({
keys: [keyObj]
}));
}