@zenvor/hls.js 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +28 -0
- package/README.md +472 -0
- package/dist/hls-demo.js +26995 -0
- package/dist/hls-demo.js.map +1 -0
- package/dist/hls.d.mts +4204 -0
- package/dist/hls.d.ts +4204 -0
- package/dist/hls.js +40050 -0
- package/dist/hls.js.d.ts +4204 -0
- package/dist/hls.js.map +1 -0
- package/dist/hls.light.js +27145 -0
- package/dist/hls.light.js.map +1 -0
- package/dist/hls.light.min.js +2 -0
- package/dist/hls.light.min.js.map +1 -0
- package/dist/hls.light.mjs +26392 -0
- package/dist/hls.light.mjs.map +1 -0
- package/dist/hls.min.js +2 -0
- package/dist/hls.min.js.map +1 -0
- package/dist/hls.mjs +38956 -0
- package/dist/hls.mjs.map +1 -0
- package/dist/hls.worker.js +2 -0
- package/dist/hls.worker.js.map +1 -0
- package/package.json +143 -0
- package/src/config.ts +794 -0
- package/src/controller/abr-controller.ts +1019 -0
- package/src/controller/algo-data-controller.ts +794 -0
- package/src/controller/audio-stream-controller.ts +1099 -0
- package/src/controller/audio-track-controller.ts +454 -0
- package/src/controller/base-playlist-controller.ts +438 -0
- package/src/controller/base-stream-controller.ts +2526 -0
- package/src/controller/buffer-controller.ts +2015 -0
- package/src/controller/buffer-operation-queue.ts +159 -0
- package/src/controller/cap-level-controller.ts +367 -0
- package/src/controller/cmcd-controller.ts +422 -0
- package/src/controller/content-steering-controller.ts +622 -0
- package/src/controller/eme-controller.ts +1617 -0
- package/src/controller/error-controller.ts +627 -0
- package/src/controller/fps-controller.ts +146 -0
- package/src/controller/fragment-finders.ts +256 -0
- package/src/controller/fragment-tracker.ts +567 -0
- package/src/controller/gap-controller.ts +719 -0
- package/src/controller/id3-track-controller.ts +488 -0
- package/src/controller/interstitial-player.ts +302 -0
- package/src/controller/interstitials-controller.ts +2895 -0
- package/src/controller/interstitials-schedule.ts +698 -0
- package/src/controller/latency-controller.ts +294 -0
- package/src/controller/level-controller.ts +776 -0
- package/src/controller/stream-controller.ts +1597 -0
- package/src/controller/subtitle-stream-controller.ts +508 -0
- package/src/controller/subtitle-track-controller.ts +617 -0
- package/src/controller/timeline-controller.ts +677 -0
- package/src/crypt/aes-crypto.ts +36 -0
- package/src/crypt/aes-decryptor.ts +339 -0
- package/src/crypt/decrypter-aes-mode.ts +4 -0
- package/src/crypt/decrypter.ts +225 -0
- package/src/crypt/fast-aes-key.ts +39 -0
- package/src/define-plugin.d.ts +17 -0
- package/src/demux/audio/aacdemuxer.ts +126 -0
- package/src/demux/audio/ac3-demuxer.ts +170 -0
- package/src/demux/audio/adts.ts +249 -0
- package/src/demux/audio/base-audio-demuxer.ts +205 -0
- package/src/demux/audio/dolby.ts +21 -0
- package/src/demux/audio/mp3demuxer.ts +85 -0
- package/src/demux/audio/mpegaudio.ts +177 -0
- package/src/demux/chunk-cache.ts +42 -0
- package/src/demux/dummy-demuxed-track.ts +13 -0
- package/src/demux/inject-worker.ts +75 -0
- package/src/demux/mp4demuxer.ts +234 -0
- package/src/demux/sample-aes.ts +198 -0
- package/src/demux/transmuxer-interface.ts +449 -0
- package/src/demux/transmuxer-worker.ts +221 -0
- package/src/demux/transmuxer.ts +560 -0
- package/src/demux/tsdemuxer.ts +1256 -0
- package/src/demux/video/avc-video-parser.ts +401 -0
- package/src/demux/video/base-video-parser.ts +198 -0
- package/src/demux/video/exp-golomb.ts +153 -0
- package/src/demux/video/hevc-video-parser.ts +736 -0
- package/src/empty-es.js +5 -0
- package/src/empty.js +3 -0
- package/src/errors.ts +107 -0
- package/src/events.ts +548 -0
- package/src/exports-default.ts +3 -0
- package/src/exports-named.ts +81 -0
- package/src/hls.ts +1613 -0
- package/src/is-supported.ts +54 -0
- package/src/loader/date-range.ts +207 -0
- package/src/loader/fragment-loader.ts +403 -0
- package/src/loader/fragment.ts +487 -0
- package/src/loader/interstitial-asset-list.ts +162 -0
- package/src/loader/interstitial-event.ts +337 -0
- package/src/loader/key-loader.ts +439 -0
- package/src/loader/level-details.ts +203 -0
- package/src/loader/level-key.ts +259 -0
- package/src/loader/load-stats.ts +17 -0
- package/src/loader/m3u8-parser.ts +1072 -0
- package/src/loader/playlist-loader.ts +839 -0
- package/src/polyfills/number.ts +15 -0
- package/src/remux/aac-helper.ts +81 -0
- package/src/remux/mp4-generator.ts +1380 -0
- package/src/remux/mp4-remuxer.ts +1261 -0
- package/src/remux/passthrough-remuxer.ts +434 -0
- package/src/task-loop.ts +130 -0
- package/src/types/algo.ts +44 -0
- package/src/types/buffer.ts +105 -0
- package/src/types/component-api.ts +20 -0
- package/src/types/demuxer.ts +208 -0
- package/src/types/events.ts +574 -0
- package/src/types/fragment-tracker.ts +23 -0
- package/src/types/level.ts +268 -0
- package/src/types/loader.ts +198 -0
- package/src/types/media-playlist.ts +92 -0
- package/src/types/network-details.ts +3 -0
- package/src/types/remuxer.ts +104 -0
- package/src/types/track.ts +12 -0
- package/src/types/transmuxer.ts +46 -0
- package/src/types/tuples.ts +6 -0
- package/src/types/vtt.ts +11 -0
- package/src/utils/arrays.ts +22 -0
- package/src/utils/attr-list.ts +192 -0
- package/src/utils/binary-search.ts +46 -0
- package/src/utils/buffer-helper.ts +173 -0
- package/src/utils/cea-608-parser.ts +1413 -0
- package/src/utils/chunker.ts +41 -0
- package/src/utils/codecs.ts +314 -0
- package/src/utils/cues.ts +96 -0
- package/src/utils/discontinuities.ts +174 -0
- package/src/utils/encryption-methods-util.ts +21 -0
- package/src/utils/error-helper.ts +95 -0
- package/src/utils/event-listener-helper.ts +16 -0
- package/src/utils/ewma-bandwidth-estimator.ts +97 -0
- package/src/utils/ewma.ts +43 -0
- package/src/utils/fetch-loader.ts +331 -0
- package/src/utils/global.ts +2 -0
- package/src/utils/hash.ts +10 -0
- package/src/utils/hdr.ts +67 -0
- package/src/utils/hex.ts +32 -0
- package/src/utils/imsc1-ttml-parser.ts +261 -0
- package/src/utils/keysystem-util.ts +45 -0
- package/src/utils/level-helper.ts +629 -0
- package/src/utils/logger.ts +120 -0
- package/src/utils/media-option-attributes.ts +49 -0
- package/src/utils/mediacapabilities-helper.ts +301 -0
- package/src/utils/mediakeys-helper.ts +210 -0
- package/src/utils/mediasource-helper.ts +37 -0
- package/src/utils/mp4-tools.ts +1473 -0
- package/src/utils/number.ts +3 -0
- package/src/utils/numeric-encoding-utils.ts +26 -0
- package/src/utils/output-filter.ts +46 -0
- package/src/utils/rendition-helper.ts +505 -0
- package/src/utils/safe-json-stringify.ts +22 -0
- package/src/utils/texttrack-utils.ts +164 -0
- package/src/utils/time-ranges.ts +17 -0
- package/src/utils/timescale-conversion.ts +46 -0
- package/src/utils/utf8-utils.ts +18 -0
- package/src/utils/variable-substitution.ts +105 -0
- package/src/utils/vttcue.ts +384 -0
- package/src/utils/vttparser.ts +497 -0
- package/src/utils/webvtt-parser.ts +166 -0
- package/src/utils/xhr-loader.ts +337 -0
- package/src/version.ts +1 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { utf8ArrayToStr } from '@svta/common-media-library/utils/utf8ArrayToStr';
|
|
2
|
+
import { findBox } from './mp4-tools';
|
|
3
|
+
import { toTimescaleFromScale } from './timescale-conversion';
|
|
4
|
+
import VTTCue from './vttcue';
|
|
5
|
+
import { parseTimeStamp } from './vttparser';
|
|
6
|
+
import { generateCueId } from './webvtt-parser';
|
|
7
|
+
import type { TimestampOffset } from './timescale-conversion';
|
|
8
|
+
|
|
9
|
+
export const IMSC1_CODEC = 'stpp.ttml.im1t';
|
|
10
|
+
|
|
11
|
+
// Time format: h:m:s:frames(.subframes)
|
|
12
|
+
const HMSF_REGEX = /^(\d{2,}):(\d{2}):(\d{2}):(\d{2})\.?(\d+)?$/;
|
|
13
|
+
|
|
14
|
+
// Time format: hours, minutes, seconds, milliseconds, frames, ticks
|
|
15
|
+
const TIME_UNIT_REGEX = /^(\d*(?:\.\d*)?)(h|m|s|ms|f|t)$/;
|
|
16
|
+
|
|
17
|
+
const textAlignToLineAlign: Partial<Record<string, LineAlignSetting>> = {
|
|
18
|
+
left: 'start',
|
|
19
|
+
center: 'center',
|
|
20
|
+
right: 'end',
|
|
21
|
+
start: 'start',
|
|
22
|
+
end: 'end',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function parseIMSC1(
|
|
26
|
+
payload: ArrayBuffer,
|
|
27
|
+
initPTS: TimestampOffset,
|
|
28
|
+
callBack: (cues: Array<VTTCue>) => any,
|
|
29
|
+
errorCallBack: (error: Error) => any,
|
|
30
|
+
) {
|
|
31
|
+
const results = findBox(new Uint8Array(payload), ['mdat']);
|
|
32
|
+
if (results.length === 0) {
|
|
33
|
+
errorCallBack(new Error('Could not parse IMSC1 mdat'));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const ttmlList = results.map((mdat) => utf8ArrayToStr(mdat));
|
|
38
|
+
|
|
39
|
+
const syncTime = toTimescaleFromScale(initPTS.baseTime, 1, initPTS.timescale);
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
ttmlList.forEach((ttml) => callBack(parseTTML(ttml, syncTime)));
|
|
43
|
+
} catch (error) {
|
|
44
|
+
errorCallBack(error);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function parseTTML(ttml: string, syncTime: number): Array<VTTCue> {
|
|
49
|
+
const parser = new DOMParser();
|
|
50
|
+
const xmlDoc = parser.parseFromString(ttml, 'text/xml');
|
|
51
|
+
const tt = xmlDoc.getElementsByTagName('tt')[0];
|
|
52
|
+
if (!tt) {
|
|
53
|
+
throw new Error('Invalid ttml');
|
|
54
|
+
}
|
|
55
|
+
const defaultRateInfo = {
|
|
56
|
+
frameRate: 30,
|
|
57
|
+
subFrameRate: 1,
|
|
58
|
+
frameRateMultiplier: 0,
|
|
59
|
+
tickRate: 0,
|
|
60
|
+
};
|
|
61
|
+
const rateInfo: Object = Object.keys(defaultRateInfo).reduce(
|
|
62
|
+
(result, key) => {
|
|
63
|
+
result[key] = tt.getAttribute(`ttp:${key}`) || defaultRateInfo[key];
|
|
64
|
+
return result;
|
|
65
|
+
},
|
|
66
|
+
{},
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
const trim = tt.getAttribute('xml:space') !== 'preserve';
|
|
70
|
+
|
|
71
|
+
const styleElements = collectionToDictionary(
|
|
72
|
+
getElementCollection(tt, 'styling', 'style'),
|
|
73
|
+
);
|
|
74
|
+
const regionElements = collectionToDictionary(
|
|
75
|
+
getElementCollection(tt, 'layout', 'region'),
|
|
76
|
+
);
|
|
77
|
+
const cueElements = getElementCollection(tt, 'body', '[begin]');
|
|
78
|
+
|
|
79
|
+
return [].map
|
|
80
|
+
.call(cueElements, (cueElement) => {
|
|
81
|
+
const cueText = getTextContent(cueElement, trim);
|
|
82
|
+
|
|
83
|
+
if (!cueText || !cueElement.hasAttribute('begin')) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
const startTime = parseTtmlTime(
|
|
87
|
+
cueElement.getAttribute('begin'),
|
|
88
|
+
rateInfo,
|
|
89
|
+
);
|
|
90
|
+
const duration = parseTtmlTime(cueElement.getAttribute('dur'), rateInfo);
|
|
91
|
+
let endTime = parseTtmlTime(cueElement.getAttribute('end'), rateInfo);
|
|
92
|
+
if (startTime === null) {
|
|
93
|
+
throw timestampParsingError(cueElement);
|
|
94
|
+
}
|
|
95
|
+
if (endTime === null) {
|
|
96
|
+
if (duration === null) {
|
|
97
|
+
throw timestampParsingError(cueElement);
|
|
98
|
+
}
|
|
99
|
+
endTime = startTime + duration;
|
|
100
|
+
}
|
|
101
|
+
const cue = new VTTCue(startTime - syncTime, endTime - syncTime, cueText);
|
|
102
|
+
cue.id = generateCueId(cue.startTime, cue.endTime, cue.text);
|
|
103
|
+
|
|
104
|
+
const region = regionElements[cueElement.getAttribute('region')];
|
|
105
|
+
const style = styleElements[cueElement.getAttribute('style')];
|
|
106
|
+
|
|
107
|
+
// Apply styles to cue
|
|
108
|
+
const styles = getTtmlStyles(region, style, styleElements);
|
|
109
|
+
const { textAlign } = styles;
|
|
110
|
+
if (textAlign) {
|
|
111
|
+
// cue.positionAlign not settable in FF~2016
|
|
112
|
+
const lineAlign = textAlignToLineAlign[textAlign];
|
|
113
|
+
if (lineAlign) {
|
|
114
|
+
cue.lineAlign = lineAlign;
|
|
115
|
+
}
|
|
116
|
+
cue.align = textAlign as AlignSetting;
|
|
117
|
+
}
|
|
118
|
+
Object.assign(cue, styles);
|
|
119
|
+
|
|
120
|
+
return cue;
|
|
121
|
+
})
|
|
122
|
+
.filter((cue) => cue !== null);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function getElementCollection(
|
|
126
|
+
fromElement,
|
|
127
|
+
parentName,
|
|
128
|
+
childName,
|
|
129
|
+
): Array<HTMLElement> {
|
|
130
|
+
const parent = fromElement.getElementsByTagName(parentName)[0];
|
|
131
|
+
if (parent) {
|
|
132
|
+
return [].slice.call(parent.querySelectorAll(childName));
|
|
133
|
+
}
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function collectionToDictionary(elementsWithId: Array<HTMLElement>): {
|
|
138
|
+
[id: string]: HTMLElement;
|
|
139
|
+
} {
|
|
140
|
+
return elementsWithId.reduce((dict, element: HTMLElement) => {
|
|
141
|
+
const id = element.getAttribute('xml:id');
|
|
142
|
+
if (id) {
|
|
143
|
+
dict[id] = element;
|
|
144
|
+
}
|
|
145
|
+
return dict;
|
|
146
|
+
}, {});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function getTextContent(element, trim): string {
|
|
150
|
+
return [].slice.call(element.childNodes).reduce((str, node, i) => {
|
|
151
|
+
if (node.nodeName === 'br' && i) {
|
|
152
|
+
return str + '\n';
|
|
153
|
+
}
|
|
154
|
+
if (node.childNodes?.length) {
|
|
155
|
+
return getTextContent(node, trim);
|
|
156
|
+
} else if (trim) {
|
|
157
|
+
return str + node.textContent.trim().replace(/\s+/g, ' ');
|
|
158
|
+
}
|
|
159
|
+
return str + node.textContent;
|
|
160
|
+
}, '');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function getTtmlStyles(
|
|
164
|
+
region,
|
|
165
|
+
style,
|
|
166
|
+
styleElements,
|
|
167
|
+
): { [style: string]: string } {
|
|
168
|
+
const ttsNs = 'http://www.w3.org/ns/ttml#styling';
|
|
169
|
+
let regionStyle = null;
|
|
170
|
+
const styleAttributes = [
|
|
171
|
+
'displayAlign',
|
|
172
|
+
'textAlign',
|
|
173
|
+
'color',
|
|
174
|
+
'backgroundColor',
|
|
175
|
+
'fontSize',
|
|
176
|
+
'fontFamily',
|
|
177
|
+
// 'fontWeight',
|
|
178
|
+
// 'lineHeight',
|
|
179
|
+
// 'wrapOption',
|
|
180
|
+
// 'fontStyle',
|
|
181
|
+
// 'direction',
|
|
182
|
+
// 'writingMode'
|
|
183
|
+
];
|
|
184
|
+
|
|
185
|
+
const regionStyleName = region?.hasAttribute('style')
|
|
186
|
+
? region.getAttribute('style')
|
|
187
|
+
: null;
|
|
188
|
+
|
|
189
|
+
if (regionStyleName && styleElements.hasOwnProperty(regionStyleName)) {
|
|
190
|
+
regionStyle = styleElements[regionStyleName];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return styleAttributes.reduce((styles, name) => {
|
|
194
|
+
const value =
|
|
195
|
+
getAttributeNS(style, ttsNs, name) ||
|
|
196
|
+
getAttributeNS(region, ttsNs, name) ||
|
|
197
|
+
getAttributeNS(regionStyle, ttsNs, name);
|
|
198
|
+
if (value) {
|
|
199
|
+
styles[name] = value;
|
|
200
|
+
}
|
|
201
|
+
return styles;
|
|
202
|
+
}, {});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function getAttributeNS(element, ns, name): string | null {
|
|
206
|
+
if (!element) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
return element.hasAttributeNS(ns, name)
|
|
210
|
+
? element.getAttributeNS(ns, name)
|
|
211
|
+
: null;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function timestampParsingError(node) {
|
|
215
|
+
return new Error(`Could not parse ttml timestamp ${node}`);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function parseTtmlTime(timeAttributeValue, rateInfo): number | null {
|
|
219
|
+
if (!timeAttributeValue) {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
let seconds: number | null = parseTimeStamp(timeAttributeValue);
|
|
223
|
+
if (seconds === null) {
|
|
224
|
+
if (HMSF_REGEX.test(timeAttributeValue)) {
|
|
225
|
+
seconds = parseHoursMinutesSecondsFrames(timeAttributeValue, rateInfo);
|
|
226
|
+
} else if (TIME_UNIT_REGEX.test(timeAttributeValue)) {
|
|
227
|
+
seconds = parseTimeUnits(timeAttributeValue, rateInfo);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return seconds;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function parseHoursMinutesSecondsFrames(timeAttributeValue, rateInfo): number {
|
|
234
|
+
const m = HMSF_REGEX.exec(timeAttributeValue) as Array<any>;
|
|
235
|
+
const frames = (m[4] | 0) + (m[5] | 0) / rateInfo.subFrameRate;
|
|
236
|
+
return (
|
|
237
|
+
(m[1] | 0) * 3600 +
|
|
238
|
+
(m[2] | 0) * 60 +
|
|
239
|
+
(m[3] | 0) +
|
|
240
|
+
frames / rateInfo.frameRate
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function parseTimeUnits(timeAttributeValue, rateInfo): number {
|
|
245
|
+
const m = TIME_UNIT_REGEX.exec(timeAttributeValue) as Array<any>;
|
|
246
|
+
const value = Number(m[1]);
|
|
247
|
+
const unit = m[2];
|
|
248
|
+
switch (unit) {
|
|
249
|
+
case 'h':
|
|
250
|
+
return value * 3600;
|
|
251
|
+
case 'm':
|
|
252
|
+
return value * 60;
|
|
253
|
+
case 'ms':
|
|
254
|
+
return value * 1000;
|
|
255
|
+
case 'f':
|
|
256
|
+
return value / rateInfo.frameRate;
|
|
257
|
+
case 't':
|
|
258
|
+
return value / rateInfo.tickRate;
|
|
259
|
+
}
|
|
260
|
+
return value;
|
|
261
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { base64Decode } from './numeric-encoding-utils';
|
|
2
|
+
import { strToUtf8array } from './utf8-utils';
|
|
3
|
+
|
|
4
|
+
function getKeyIdBytes(str: string): Uint8Array<ArrayBuffer> {
|
|
5
|
+
const keyIdbytes = strToUtf8array(str).subarray(0, 16);
|
|
6
|
+
const paddedkeyIdbytes = new Uint8Array(16);
|
|
7
|
+
paddedkeyIdbytes.set(keyIdbytes, 16 - keyIdbytes.length);
|
|
8
|
+
return paddedkeyIdbytes;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function changeEndianness(keyId: Uint8Array) {
|
|
12
|
+
const swap = function (array: Uint8Array, from: number, to: number) {
|
|
13
|
+
const cur = array[from];
|
|
14
|
+
array[from] = array[to];
|
|
15
|
+
array[to] = cur;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
swap(keyId, 0, 3);
|
|
19
|
+
swap(keyId, 1, 2);
|
|
20
|
+
swap(keyId, 4, 5);
|
|
21
|
+
swap(keyId, 6, 7);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function convertDataUriToArrayBytes(
|
|
25
|
+
uri: string,
|
|
26
|
+
): Uint8Array<ArrayBuffer> | null {
|
|
27
|
+
// data:[<media type][;attribute=value][;base64],<data>
|
|
28
|
+
const colonsplit = uri.split(':');
|
|
29
|
+
let keydata: Uint8Array<ArrayBuffer> | null = null;
|
|
30
|
+
if (colonsplit[0] === 'data' && colonsplit.length === 2) {
|
|
31
|
+
const semicolonsplit = colonsplit[1].split(';');
|
|
32
|
+
const commasplit = semicolonsplit[semicolonsplit.length - 1].split(',');
|
|
33
|
+
if (commasplit.length === 2) {
|
|
34
|
+
const isbase64 = commasplit[0] === 'base64';
|
|
35
|
+
const data = commasplit[1];
|
|
36
|
+
if (isbase64) {
|
|
37
|
+
semicolonsplit.splice(-1, 1); // remove from processing
|
|
38
|
+
keydata = base64Decode(data);
|
|
39
|
+
} else {
|
|
40
|
+
keydata = getKeyIdBytes(data);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return keydata;
|
|
45
|
+
}
|