forked from video-dev/hls.js
-
Notifications
You must be signed in to change notification settings - Fork 2
/
sample-aes.js
124 lines (99 loc) · 3.6 KB
/
sample-aes.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
/**
* SAMPLE-AES decrypter
*/
import Decrypter from '../crypt/decrypter';
class SampleAesDecrypter {
constructor (observer, config, decryptdata, discardEPB) {
this.decryptdata = decryptdata;
this.discardEPB = discardEPB;
this.decrypter = new Decrypter(observer, config, { removePKCS7Padding: false });
}
decryptBuffer (encryptedData, callback) {
this.decrypter.decrypt(encryptedData, this.decryptdata.key.buffer, this.decryptdata.iv.buffer, callback);
}
// AAC - encrypt all full 16 bytes blocks starting from offset 16
decryptAacSample (samples, sampleIndex, callback, sync) {
let curUnit = samples[sampleIndex].unit;
let encryptedData = curUnit.subarray(16, curUnit.length - curUnit.length % 16);
let encryptedBuffer = encryptedData.buffer.slice(
encryptedData.byteOffset,
encryptedData.byteOffset + encryptedData.length);
let localthis = this;
this.decryptBuffer(encryptedBuffer, function (decryptedData) {
decryptedData = new Uint8Array(decryptedData);
curUnit.set(decryptedData, 16);
if (!sync) {
localthis.decryptAacSamples(samples, sampleIndex + 1, callback);
}
});
}
decryptAacSamples (samples, sampleIndex, callback) {
for (;; sampleIndex++) {
if (sampleIndex >= samples.length) {
callback();
return;
}
if (samples[sampleIndex].unit.length < 32) {
continue;
}
let sync = this.decrypter.isSync();
this.decryptAacSample(samples, sampleIndex, callback, sync);
if (!sync) {
return;
}
}
}
// AVC - encrypt one 16 bytes block out of ten, starting from offset 32
getAvcEncryptedData (decodedData) {
let encryptedDataLen = Math.floor((decodedData.length - 48) / 160) * 16 + 16;
let encryptedData = new Int8Array(encryptedDataLen);
let outputPos = 0;
for (let inputPos = 32; inputPos <= decodedData.length - 16; inputPos += 160, outputPos += 16) {
encryptedData.set(decodedData.subarray(inputPos, inputPos + 16), outputPos);
}
return encryptedData;
}
getAvcDecryptedUnit (decodedData, decryptedData) {
decryptedData = new Uint8Array(decryptedData);
let inputPos = 0;
for (let outputPos = 32; outputPos <= decodedData.length - 16; outputPos += 160, inputPos += 16) {
decodedData.set(decryptedData.subarray(inputPos, inputPos + 16), outputPos);
}
return decodedData;
}
decryptAvcSample (samples, sampleIndex, unitIndex, callback, curUnit, sync) {
let decodedData = this.discardEPB(curUnit.data);
let encryptedData = this.getAvcEncryptedData(decodedData);
let localthis = this;
this.decryptBuffer(encryptedData.buffer, function (decryptedData) {
curUnit.data = localthis.getAvcDecryptedUnit(decodedData, decryptedData);
if (!sync) {
localthis.decryptAvcSamples(samples, sampleIndex, unitIndex + 1, callback);
}
});
}
decryptAvcSamples (samples, sampleIndex, unitIndex, callback) {
for (;; sampleIndex++, unitIndex = 0) {
if (sampleIndex >= samples.length) {
callback();
return;
}
let curUnits = samples[sampleIndex].units;
for (;; unitIndex++) {
if (unitIndex >= curUnits.length) {
break;
}
let curUnit = curUnits[unitIndex];
if (curUnit.length <= 48 || (curUnit.type !== 1 && curUnit.type !== 5)) {
continue;
}
let sync = this.decrypter.isSync();
this.decryptAvcSample(samples, sampleIndex, unitIndex, callback, curUnit, sync);
if (!sync) {
return;
}
}
}
}
}
export default SampleAesDecrypter;