hls.js 1.5.14-0.canary.10431 → 1.5.14-0.canary.10432
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/dist/hls.js +316 -232
- package/dist/hls.js.d.ts +4 -2
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +316 -235
- package/dist/hls.light.js.map +1 -1
- package/dist/hls.light.min.js +1 -1
- package/dist/hls.light.min.js.map +1 -1
- package/dist/hls.light.mjs +244 -168
- package/dist/hls.light.mjs.map +1 -1
- package/dist/hls.min.js +1 -1
- package/dist/hls.min.js.map +1 -1
- package/dist/hls.mjs +244 -165
- package/dist/hls.mjs.map +1 -1
- package/dist/hls.worker.js +1 -1
- package/dist/hls.worker.js.map +1 -1
- package/package.json +1 -1
- package/src/controller/base-stream-controller.ts +5 -4
- package/src/demux/audio/aacdemuxer.ts +3 -3
- package/src/demux/audio/ac3-demuxer.ts +1 -1
- package/src/demux/inject-worker.ts +38 -4
- package/src/demux/transmuxer-interface.ts +98 -67
- package/src/demux/transmuxer-worker.ts +110 -76
- package/src/demux/transmuxer.ts +29 -16
- package/src/demux/tsdemuxer.ts +47 -24
- package/src/hls.ts +2 -1
- package/src/remux/mp4-remuxer.ts +24 -23
- package/src/remux/passthrough-remuxer.ts +22 -7
- package/src/version.ts +1 -0
package/package.json
CHANGED
@@ -365,6 +365,10 @@ export default class BaseStreamController
|
|
365
365
|
|
366
366
|
protected onHandlerDestroying() {
|
367
367
|
this.stopLoad();
|
368
|
+
if (this.transmuxer) {
|
369
|
+
this.transmuxer.destroy();
|
370
|
+
this.transmuxer = null;
|
371
|
+
}
|
368
372
|
super.onHandlerDestroying();
|
369
373
|
// @ts-ignore
|
370
374
|
this.hls = this.onMediaSeeking = this.onMediaEnded = null;
|
@@ -1931,10 +1935,7 @@ export default class BaseStreamController
|
|
1931
1935
|
}
|
1932
1936
|
|
1933
1937
|
protected resetTransmuxer() {
|
1934
|
-
|
1935
|
-
this.transmuxer.destroy();
|
1936
|
-
this.transmuxer = null;
|
1937
|
-
}
|
1938
|
+
this.transmuxer?.reset();
|
1938
1939
|
}
|
1939
1940
|
|
1940
1941
|
protected recoverWorkerError(data: ErrorData) {
|
@@ -4,16 +4,16 @@
|
|
4
4
|
import BaseAudioDemuxer from './base-audio-demuxer';
|
5
5
|
import * as ADTS from './adts';
|
6
6
|
import * as MpegAudio from './mpegaudio';
|
7
|
-
import { logger } from '../../utils/logger';
|
8
7
|
import { getId3Data } from '@svta/common-media-library/id3/getId3Data';
|
9
8
|
import type { HlsEventEmitter } from '../../events';
|
10
9
|
import type { HlsConfig } from '../../config';
|
10
|
+
import type { ILogger } from '../../utils/logger';
|
11
11
|
|
12
12
|
class AACDemuxer extends BaseAudioDemuxer {
|
13
13
|
private readonly observer: HlsEventEmitter;
|
14
14
|
private readonly config: HlsConfig;
|
15
15
|
|
16
|
-
constructor(observer, config) {
|
16
|
+
constructor(observer: HlsEventEmitter, config) {
|
17
17
|
super();
|
18
18
|
this.observer = observer;
|
19
19
|
this.config = config;
|
@@ -42,7 +42,7 @@ class AACDemuxer extends BaseAudioDemuxer {
|
|
42
42
|
}
|
43
43
|
|
44
44
|
// Source for probe info - https://wiki.multimedia.cx/index.php?title=ADTS
|
45
|
-
static probe(data: Uint8Array | undefined): boolean {
|
45
|
+
static probe(data: Uint8Array | undefined, logger: ILogger): boolean {
|
46
46
|
if (!data) {
|
47
47
|
return false;
|
48
48
|
}
|
@@ -8,7 +8,7 @@ import type { AudioFrame, DemuxedAudioTrack } from '../../types/demuxer';
|
|
8
8
|
export class AC3Demuxer extends BaseAudioDemuxer {
|
9
9
|
private readonly observer: HlsEventEmitter;
|
10
10
|
|
11
|
-
constructor(observer) {
|
11
|
+
constructor(observer: HlsEventEmitter) {
|
12
12
|
super();
|
13
13
|
this.observer = observer;
|
14
14
|
}
|
@@ -1,6 +1,9 @@
|
|
1
1
|
// ensure the worker ends up in the bundle
|
2
2
|
// If the worker should not be included this gets aliased to empty.js
|
3
3
|
import './transmuxer-worker';
|
4
|
+
import { version } from '../version';
|
5
|
+
|
6
|
+
const workerStore: Record<string, WorkerContext> = {};
|
4
7
|
|
5
8
|
export function hasUMDWorker(): boolean {
|
6
9
|
return typeof __HLS_WORKER_BUNDLE__ === 'function';
|
@@ -10,9 +13,15 @@ export type WorkerContext = {
|
|
10
13
|
worker: Worker;
|
11
14
|
objectURL?: string;
|
12
15
|
scriptURL?: string;
|
16
|
+
clientCount: number;
|
13
17
|
};
|
14
18
|
|
15
19
|
export function injectWorker(): WorkerContext {
|
20
|
+
const workerContext = workerStore[version];
|
21
|
+
if (workerContext) {
|
22
|
+
workerContext.clientCount++;
|
23
|
+
return workerContext;
|
24
|
+
}
|
16
25
|
const blob = new self.Blob(
|
17
26
|
[
|
18
27
|
`var exports={};var module={exports:exports};function define(f){f()};define.amd=true;(${__HLS_WORKER_BUNDLE__.toString()})(true);`,
|
@@ -23,19 +32,44 @@ export function injectWorker(): WorkerContext {
|
|
23
32
|
);
|
24
33
|
const objectURL = self.URL.createObjectURL(blob);
|
25
34
|
const worker = new self.Worker(objectURL);
|
26
|
-
|
27
|
-
return {
|
35
|
+
const result = {
|
28
36
|
worker,
|
29
37
|
objectURL,
|
38
|
+
clientCount: 1,
|
30
39
|
};
|
40
|
+
workerStore[version] = result;
|
41
|
+
return result;
|
31
42
|
}
|
32
43
|
|
33
44
|
export function loadWorker(path: string): WorkerContext {
|
45
|
+
const workerContext = workerStore[path];
|
46
|
+
if (workerContext) {
|
47
|
+
workerContext.clientCount++;
|
48
|
+
return workerContext;
|
49
|
+
}
|
34
50
|
const scriptURL = new self.URL(path, self.location.href).href;
|
35
51
|
const worker = new self.Worker(scriptURL);
|
36
|
-
|
37
|
-
return {
|
52
|
+
const result = {
|
38
53
|
worker,
|
39
54
|
scriptURL,
|
55
|
+
clientCount: 1,
|
40
56
|
};
|
57
|
+
workerStore[path] = result;
|
58
|
+
return result;
|
59
|
+
}
|
60
|
+
|
61
|
+
export function removeWorkerFromStore(path?: string | null) {
|
62
|
+
const workerContext = workerStore[path || version];
|
63
|
+
if (workerContext) {
|
64
|
+
const clientCount = workerContext.clientCount--;
|
65
|
+
if (clientCount === 1) {
|
66
|
+
const { worker, objectURL } = workerContext;
|
67
|
+
delete workerStore[path || version];
|
68
|
+
if (objectURL) {
|
69
|
+
// revoke the Object URL that was used to create transmuxer worker, so as not to leak it
|
70
|
+
self.URL.revokeObjectURL(objectURL);
|
71
|
+
}
|
72
|
+
worker.terminate();
|
73
|
+
}
|
74
|
+
}
|
41
75
|
}
|
@@ -3,6 +3,7 @@ import {
|
|
3
3
|
hasUMDWorker,
|
4
4
|
injectWorker,
|
5
5
|
loadWorker,
|
6
|
+
removeWorkerFromStore as removeWorkerClient,
|
6
7
|
} from './inject-worker';
|
7
8
|
import { Events } from '../events';
|
8
9
|
import Transmuxer, {
|
@@ -10,29 +11,30 @@ import Transmuxer, {
|
|
10
11
|
TransmuxState,
|
11
12
|
isPromise,
|
12
13
|
} from '../demux/transmuxer';
|
13
|
-
import { logger } from '../utils/logger';
|
14
14
|
import { ErrorTypes, ErrorDetails } from '../errors';
|
15
15
|
import { EventEmitter } from 'eventemitter3';
|
16
16
|
import { MediaFragment, Part } from '../loader/fragment';
|
17
17
|
import { getM2TSSupportedAudioTypes } from '../utils/codecs';
|
18
|
+
|
18
19
|
import type { ChunkMetadata, TransmuxerResult } from '../types/transmuxer';
|
19
20
|
import type Hls from '../hls';
|
20
21
|
import type { HlsEventEmitter, HlsListeners } from '../events';
|
22
|
+
import type { ErrorData, FragDecryptedData } from '../types/events';
|
21
23
|
import type { PlaylistLevelType } from '../types/loader';
|
22
24
|
import type { RationalTimestamp } from '../utils/timescale-conversion';
|
23
25
|
|
26
|
+
let transmuxerInstanceCount: number = 0;
|
27
|
+
|
24
28
|
export default class TransmuxerInterface {
|
25
29
|
public error: Error | null = null;
|
26
30
|
private hls: Hls;
|
27
31
|
private id: PlaylistLevelType;
|
32
|
+
private instanceNo: number = transmuxerInstanceCount++;
|
28
33
|
private observer: HlsEventEmitter;
|
29
34
|
private frag: MediaFragment | null = null;
|
30
35
|
private part: Part | null = null;
|
31
36
|
private useWorker: boolean;
|
32
37
|
private workerContext: WorkerContext | null = null;
|
33
|
-
private onwmsg?: (
|
34
|
-
event: MessageEvent<{ event: string; data?: any } | null>,
|
35
|
-
) => void;
|
36
38
|
private transmuxer: Transmuxer | null = null;
|
37
39
|
private onTransmuxComplete: (transmuxResult: TransmuxerResult) => void;
|
38
40
|
private onFlush: (chunkMeta: ChunkMetadata) => void;
|
@@ -50,11 +52,16 @@ export default class TransmuxerInterface {
|
|
50
52
|
this.onTransmuxComplete = onTransmuxComplete;
|
51
53
|
this.onFlush = onFlush;
|
52
54
|
|
53
|
-
const forwardMessage = (
|
55
|
+
const forwardMessage = (
|
56
|
+
ev: Events.ERROR | Events.FRAG_DECRYPTED,
|
57
|
+
data: ErrorData | FragDecryptedData,
|
58
|
+
) => {
|
54
59
|
data = data || {};
|
55
|
-
data.frag = this.frag;
|
56
|
-
data.id = this.id;
|
60
|
+
data.frag = this.frag || undefined;
|
57
61
|
if (ev === Events.ERROR) {
|
62
|
+
data = data as ErrorData;
|
63
|
+
data.parent = this.id;
|
64
|
+
data.part = this.part;
|
58
65
|
this.error = data.error;
|
59
66
|
}
|
60
67
|
this.hls.trigger(ev, data);
|
@@ -70,6 +77,7 @@ export default class TransmuxerInterface {
|
|
70
77
|
);
|
71
78
|
|
72
79
|
if (this.useWorker && typeof Worker !== 'undefined') {
|
80
|
+
const logger = this.hls.logger;
|
73
81
|
const canCreateWorker = config.workerPath || hasUMDWorker();
|
74
82
|
if (canCreateWorker) {
|
75
83
|
try {
|
@@ -80,28 +88,14 @@ export default class TransmuxerInterface {
|
|
80
88
|
logger.log(`injecting Web Worker for "${id}"`);
|
81
89
|
this.workerContext = injectWorker();
|
82
90
|
}
|
83
|
-
this.onwmsg = (event) => this.onWorkerMessage(event);
|
84
91
|
const { worker } = this.workerContext;
|
85
|
-
worker.addEventListener('message', this.
|
86
|
-
worker.
|
87
|
-
const error = new Error(
|
88
|
-
`${event.message} (${event.filename}:${event.lineno})`,
|
89
|
-
);
|
90
|
-
config.enableWorker = false;
|
91
|
-
logger.warn(`Error in "${id}" Web Worker, fallback to inline`);
|
92
|
-
this.hls.trigger(Events.ERROR, {
|
93
|
-
type: ErrorTypes.OTHER_ERROR,
|
94
|
-
details: ErrorDetails.INTERNAL_EXCEPTION,
|
95
|
-
fatal: false,
|
96
|
-
event: 'demuxerWorker',
|
97
|
-
error,
|
98
|
-
});
|
99
|
-
};
|
92
|
+
worker.addEventListener('message', this.onWorkerMessage);
|
93
|
+
worker.addEventListener('error', this.onWorkerError);
|
100
94
|
worker.postMessage({
|
95
|
+
instanceNo: this.instanceNo,
|
101
96
|
cmd: 'init',
|
102
97
|
typeSupported: m2tsTypeSupported,
|
103
|
-
|
104
|
-
id: id,
|
98
|
+
id,
|
105
99
|
config: JSON.stringify(config),
|
106
100
|
});
|
107
101
|
} catch (err) {
|
@@ -109,7 +103,7 @@ export default class TransmuxerInterface {
|
|
109
103
|
`Error setting up "${id}" Web Worker, fallback to inline`,
|
110
104
|
err,
|
111
105
|
);
|
112
|
-
this.
|
106
|
+
this.terminateWorker();
|
113
107
|
this.error = null;
|
114
108
|
this.transmuxer = new Transmuxer(
|
115
109
|
this.observer,
|
@@ -117,6 +111,7 @@ export default class TransmuxerInterface {
|
|
117
111
|
config,
|
118
112
|
'',
|
119
113
|
id,
|
114
|
+
hls.logger,
|
120
115
|
);
|
121
116
|
}
|
122
117
|
return;
|
@@ -129,27 +124,46 @@ export default class TransmuxerInterface {
|
|
129
124
|
config,
|
130
125
|
'',
|
131
126
|
id,
|
127
|
+
hls.logger,
|
132
128
|
);
|
133
129
|
}
|
134
130
|
|
135
|
-
|
131
|
+
reset() {
|
132
|
+
this.frag = null;
|
133
|
+
this.part = null;
|
136
134
|
if (this.workerContext) {
|
137
|
-
const
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
worker.
|
144
|
-
|
135
|
+
const instanceNo = this.instanceNo;
|
136
|
+
this.instanceNo = transmuxerInstanceCount++;
|
137
|
+
const config = this.hls.config;
|
138
|
+
const m2tsTypeSupported = getM2TSSupportedAudioTypes(
|
139
|
+
config.preferManagedMediaSource,
|
140
|
+
);
|
141
|
+
this.workerContext.worker.postMessage({
|
142
|
+
instanceNo: this.instanceNo,
|
143
|
+
cmd: 'reset',
|
144
|
+
resetNo: instanceNo,
|
145
|
+
typeSupported: m2tsTypeSupported,
|
146
|
+
id: this.id,
|
147
|
+
config: JSON.stringify(config),
|
148
|
+
});
|
149
|
+
}
|
150
|
+
}
|
151
|
+
|
152
|
+
private terminateWorker() {
|
153
|
+
if (this.workerContext) {
|
154
|
+
const { worker } = this.workerContext;
|
145
155
|
this.workerContext = null;
|
156
|
+
worker.removeEventListener('message', this.onWorkerMessage);
|
157
|
+
worker.removeEventListener('error', this.onWorkerError);
|
158
|
+
removeWorkerClient(this.hls.config.workerPath);
|
146
159
|
}
|
147
160
|
}
|
148
161
|
|
149
162
|
destroy() {
|
150
163
|
if (this.workerContext) {
|
151
|
-
this.
|
152
|
-
|
164
|
+
this.terminateWorker();
|
165
|
+
// @ts-ignore
|
166
|
+
this.onWorkerMessage = this.onWorkerError = null;
|
153
167
|
} else {
|
154
168
|
const transmuxer = this.transmuxer;
|
155
169
|
if (transmuxer) {
|
@@ -162,6 +176,7 @@ export default class TransmuxerInterface {
|
|
162
176
|
observer.removeAllListeners();
|
163
177
|
}
|
164
178
|
this.frag = null;
|
179
|
+
this.part = null;
|
165
180
|
// @ts-ignore
|
166
181
|
this.observer = null;
|
167
182
|
// @ts-ignore
|
@@ -181,7 +196,7 @@ export default class TransmuxerInterface {
|
|
181
196
|
defaultInitPTS?: RationalTimestamp,
|
182
197
|
) {
|
183
198
|
chunkMeta.transmuxing.start = self.performance.now();
|
184
|
-
const { transmuxer } = this;
|
199
|
+
const { instanceNo, transmuxer } = this;
|
185
200
|
const timeOffset = part ? part.start : frag.start;
|
186
201
|
// TODO: push "clear-lead" decrypt data for unencrypted fragments in streams with encrypted ones
|
187
202
|
const decryptdata = frag.decryptdata;
|
@@ -219,7 +234,8 @@ export default class TransmuxerInterface {
|
|
219
234
|
initSegmentChange,
|
220
235
|
);
|
221
236
|
if (!contiguous || discontinuity || initSegmentChange) {
|
222
|
-
|
237
|
+
this.hls.logger
|
238
|
+
.log(`[transmuxer-interface, ${frag.type}]: Starting new transmux session for sn: ${chunkMeta.sn} p: ${chunkMeta.part} level: ${chunkMeta.level} id: ${chunkMeta.id}
|
223
239
|
discontinuity: ${discontinuity}
|
224
240
|
trackSwitch: ${trackSwitch}
|
225
241
|
contiguous: ${contiguous}
|
@@ -244,6 +260,7 @@ export default class TransmuxerInterface {
|
|
244
260
|
// post fragment payload as transferable objects for ArrayBuffer (no copy)
|
245
261
|
this.workerContext.worker.postMessage(
|
246
262
|
{
|
263
|
+
instanceNo,
|
247
264
|
cmd: 'demux',
|
248
265
|
data,
|
249
266
|
decryptdata,
|
@@ -260,7 +277,6 @@ export default class TransmuxerInterface {
|
|
260
277
|
state,
|
261
278
|
);
|
262
279
|
if (isPromise(transmuxResult)) {
|
263
|
-
transmuxer.async = true;
|
264
280
|
transmuxResult
|
265
281
|
.then((data) => {
|
266
282
|
this.handleTransmuxComplete(data);
|
@@ -273,7 +289,6 @@ export default class TransmuxerInterface {
|
|
273
289
|
);
|
274
290
|
});
|
275
291
|
} else {
|
276
|
-
transmuxer.async = false;
|
277
292
|
this.handleTransmuxComplete(transmuxResult as TransmuxerResult);
|
278
293
|
}
|
279
294
|
}
|
@@ -281,20 +296,17 @@ export default class TransmuxerInterface {
|
|
281
296
|
|
282
297
|
flush(chunkMeta: ChunkMetadata) {
|
283
298
|
chunkMeta.transmuxing.start = self.performance.now();
|
284
|
-
const { transmuxer } = this;
|
299
|
+
const { instanceNo, transmuxer } = this;
|
285
300
|
if (this.workerContext) {
|
286
301
|
1;
|
287
302
|
this.workerContext.worker.postMessage({
|
303
|
+
instanceNo,
|
288
304
|
cmd: 'flush',
|
289
305
|
chunkMeta,
|
290
306
|
});
|
291
307
|
} else if (transmuxer) {
|
292
|
-
|
293
|
-
|
294
|
-
if (asyncFlush || transmuxer.async) {
|
295
|
-
if (!isPromise(transmuxResult)) {
|
296
|
-
transmuxResult = Promise.resolve(transmuxResult);
|
297
|
-
}
|
308
|
+
const transmuxResult = transmuxer.flush(chunkMeta);
|
309
|
+
if (isPromise(transmuxResult)) {
|
298
310
|
transmuxResult
|
299
311
|
.then((data) => {
|
300
312
|
this.handleFlushResult(data, chunkMeta);
|
@@ -307,10 +319,7 @@ export default class TransmuxerInterface {
|
|
307
319
|
);
|
308
320
|
});
|
309
321
|
} else {
|
310
|
-
this.handleFlushResult(
|
311
|
-
transmuxResult as Array<TransmuxerResult>,
|
312
|
-
chunkMeta,
|
313
|
-
);
|
322
|
+
this.handleFlushResult(transmuxResult, chunkMeta);
|
314
323
|
}
|
315
324
|
}
|
316
325
|
}
|
@@ -329,6 +338,7 @@ export default class TransmuxerInterface {
|
|
329
338
|
details: ErrorDetails.FRAG_PARSING_ERROR,
|
330
339
|
chunkMeta,
|
331
340
|
frag: this.frag || undefined,
|
341
|
+
part: this.part || undefined,
|
332
342
|
fatal: false,
|
333
343
|
error,
|
334
344
|
err: error,
|
@@ -346,18 +356,16 @@ export default class TransmuxerInterface {
|
|
346
356
|
this.onFlush(chunkMeta);
|
347
357
|
}
|
348
358
|
|
349
|
-
private onWorkerMessage(
|
350
|
-
event: MessageEvent<{
|
351
|
-
|
359
|
+
private onWorkerMessage = (
|
360
|
+
event: MessageEvent<{
|
361
|
+
event: string;
|
362
|
+
data?: any;
|
363
|
+
instanceNo?: number;
|
364
|
+
} | null>,
|
365
|
+
) => {
|
352
366
|
const data = event.data;
|
353
|
-
if (!data?.event) {
|
354
|
-
logger.warn(
|
355
|
-
`worker message received with no ${data ? 'event name' : 'data'}`,
|
356
|
-
);
|
357
|
-
return;
|
358
|
-
}
|
359
367
|
const hls = this.hls;
|
360
|
-
if (!this.
|
368
|
+
if (!hls || !data?.event || data.instanceNo !== this.instanceNo) {
|
361
369
|
return;
|
362
370
|
}
|
363
371
|
switch (data.event) {
|
@@ -381,26 +389,49 @@ export default class TransmuxerInterface {
|
|
381
389
|
}
|
382
390
|
|
383
391
|
// pass logs from the worker thread to the main logger
|
384
|
-
case 'workerLog':
|
385
|
-
if (logger[data.data.logType]) {
|
386
|
-
logger[data.data.logType](data.data.message);
|
392
|
+
case 'workerLog': {
|
393
|
+
if (hls.logger[data.data.logType]) {
|
394
|
+
hls.logger[data.data.logType](data.data.message);
|
387
395
|
}
|
388
396
|
break;
|
397
|
+
}
|
389
398
|
|
390
399
|
default: {
|
391
400
|
data.data = data.data || {};
|
392
401
|
data.data.frag = this.frag;
|
402
|
+
data.data.part = this.part;
|
393
403
|
data.data.id = this.id;
|
394
404
|
hls.trigger(data.event as keyof HlsListeners, data.data);
|
395
405
|
break;
|
396
406
|
}
|
397
407
|
}
|
398
|
-
}
|
408
|
+
};
|
409
|
+
|
410
|
+
private onWorkerError = (event) => {
|
411
|
+
if (!this.hls) {
|
412
|
+
return;
|
413
|
+
}
|
414
|
+
const error = new Error(
|
415
|
+
`${event.message} (${event.filename}:${event.lineno})`,
|
416
|
+
);
|
417
|
+
this.hls.config.enableWorker = false;
|
418
|
+
this.hls.logger.warn(
|
419
|
+
`Error in "${this.id}" Web Worker, fallback to inline`,
|
420
|
+
);
|
421
|
+
this.hls.trigger(Events.ERROR, {
|
422
|
+
type: ErrorTypes.OTHER_ERROR,
|
423
|
+
details: ErrorDetails.INTERNAL_EXCEPTION,
|
424
|
+
fatal: false,
|
425
|
+
event: 'demuxerWorker',
|
426
|
+
error,
|
427
|
+
});
|
428
|
+
};
|
399
429
|
|
400
430
|
private configureTransmuxer(config: TransmuxConfig) {
|
401
|
-
const { transmuxer } = this;
|
431
|
+
const { instanceNo, transmuxer } = this;
|
402
432
|
if (this.workerContext) {
|
403
433
|
this.workerContext.worker.postMessage({
|
434
|
+
instanceNo,
|
404
435
|
cmd: 'configure',
|
405
436
|
config,
|
406
437
|
});
|