@layercode/js-sdk 2.4.0 → 2.6.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.
|
@@ -511,12 +511,37 @@ registerProcessor('stream_processor', StreamProcessor);
|
|
|
511
511
|
this.sampleRate = sampleRate;
|
|
512
512
|
this.context = null;
|
|
513
513
|
this.stream = null;
|
|
514
|
+
this.gainNode = null;
|
|
514
515
|
this.analyser = null;
|
|
515
516
|
this.trackSampleOffsets = {};
|
|
516
517
|
this.interruptedTrackIds = {};
|
|
517
518
|
this.finishedPlayingCallback = finishedPlayingCallback;
|
|
518
519
|
this.isPlaying = false;
|
|
519
520
|
this.amplitudeMonitorRaf = undefined;
|
|
521
|
+
this.muted = false;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
_ensureGainNode() {
|
|
525
|
+
if (!this.context) {
|
|
526
|
+
return null;
|
|
527
|
+
}
|
|
528
|
+
if (!this.gainNode) {
|
|
529
|
+
this.gainNode = this.context.createGain();
|
|
530
|
+
this._applyGain();
|
|
531
|
+
}
|
|
532
|
+
return this.gainNode;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
_applyGain() {
|
|
536
|
+
if (!this.gainNode || !this.context) {
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
const target = this.muted ? 0 : 1;
|
|
540
|
+
try {
|
|
541
|
+
this.gainNode.gain.setTargetAtTime(target, this.context.currentTime, 0.01);
|
|
542
|
+
} catch {
|
|
543
|
+
this.gainNode.gain.value = target;
|
|
544
|
+
}
|
|
520
545
|
}
|
|
521
546
|
|
|
522
547
|
/**
|
|
@@ -556,6 +581,7 @@ registerProcessor('stream_processor', StreamProcessor);
|
|
|
556
581
|
analyser.fftSize = 8192;
|
|
557
582
|
analyser.smoothingTimeConstant = 0.1;
|
|
558
583
|
this.analyser = analyser;
|
|
584
|
+
this._ensureGainNode();
|
|
559
585
|
this.isPlaying = true;
|
|
560
586
|
return true;
|
|
561
587
|
}
|
|
@@ -625,12 +651,19 @@ registerProcessor('stream_processor', StreamProcessor);
|
|
|
625
651
|
*/
|
|
626
652
|
_start() {
|
|
627
653
|
const streamNode = new AudioWorkletNode(this.context, "stream_processor");
|
|
628
|
-
|
|
654
|
+
const gainNode = this._ensureGainNode();
|
|
655
|
+
if (!gainNode) {
|
|
656
|
+
throw new Error("GainNode not initialized");
|
|
657
|
+
}
|
|
629
658
|
streamNode.port.onmessage = (e) => {
|
|
630
659
|
const { event } = e.data;
|
|
631
660
|
if (event === "stop") {
|
|
632
661
|
streamNode.disconnect();
|
|
662
|
+
gainNode.disconnect();
|
|
633
663
|
this.stream = null;
|
|
664
|
+
if (this.analyser) {
|
|
665
|
+
this.analyser.disconnect();
|
|
666
|
+
}
|
|
634
667
|
this.isPlaying = false;
|
|
635
668
|
this.finishedPlayingCallback();
|
|
636
669
|
} else if (event === "offset") {
|
|
@@ -639,8 +672,15 @@ registerProcessor('stream_processor', StreamProcessor);
|
|
|
639
672
|
this.trackSampleOffsets[requestId] = { trackId, offset, currentTime };
|
|
640
673
|
}
|
|
641
674
|
};
|
|
642
|
-
this.analyser
|
|
643
|
-
|
|
675
|
+
if (this.analyser) {
|
|
676
|
+
this.analyser.disconnect();
|
|
677
|
+
streamNode.connect(gainNode);
|
|
678
|
+
gainNode.connect(this.analyser);
|
|
679
|
+
this.analyser.connect(this.context.destination);
|
|
680
|
+
} else {
|
|
681
|
+
streamNode.connect(gainNode);
|
|
682
|
+
gainNode.connect(this.context.destination);
|
|
683
|
+
}
|
|
644
684
|
this.stream = streamNode;
|
|
645
685
|
this.isPlaying = true;
|
|
646
686
|
return true;
|
|
@@ -770,6 +810,16 @@ registerProcessor('stream_processor', StreamProcessor);
|
|
|
770
810
|
}
|
|
771
811
|
}
|
|
772
812
|
|
|
813
|
+
mute() {
|
|
814
|
+
this.muted = true;
|
|
815
|
+
this._applyGain();
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
unmute() {
|
|
819
|
+
this.muted = false;
|
|
820
|
+
this._applyGain();
|
|
821
|
+
}
|
|
822
|
+
|
|
773
823
|
/**
|
|
774
824
|
* Disconnects the audio context and cleans up resources
|
|
775
825
|
* @returns {void}
|
|
@@ -781,6 +831,11 @@ registerProcessor('stream_processor', StreamProcessor);
|
|
|
781
831
|
this.stream = null;
|
|
782
832
|
}
|
|
783
833
|
|
|
834
|
+
if (this.gainNode) {
|
|
835
|
+
this.gainNode.disconnect();
|
|
836
|
+
this.gainNode = null;
|
|
837
|
+
}
|
|
838
|
+
|
|
784
839
|
if (this.analyser) {
|
|
785
840
|
this.analyser.disconnect();
|
|
786
841
|
}
|
|
@@ -3631,7 +3686,7 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
3631
3686
|
* @param {Object} options - Configuration options
|
|
3632
3687
|
*/
|
|
3633
3688
|
constructor(options) {
|
|
3634
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
3689
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
|
|
3635
3690
|
this.deviceId = null;
|
|
3636
3691
|
this.options = {
|
|
3637
3692
|
agentId: options.agentId,
|
|
@@ -3642,22 +3697,25 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
3642
3697
|
vadResumeDelay: (_c = options.vadResumeDelay) !== null && _c !== void 0 ? _c : 500,
|
|
3643
3698
|
audioInput: (_d = options.audioInput) !== null && _d !== void 0 ? _d : true,
|
|
3644
3699
|
audioInputChanged: (_e = options.audioInputChanged) !== null && _e !== void 0 ? _e : NOOP,
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3700
|
+
audioOutput: (_f = options.audioOutput) !== null && _f !== void 0 ? _f : true,
|
|
3701
|
+
audioOutputChanged: (_g = options.audioOutputChanged) !== null && _g !== void 0 ? _g : NOOP,
|
|
3702
|
+
onConnect: (_h = options.onConnect) !== null && _h !== void 0 ? _h : NOOP,
|
|
3703
|
+
onDisconnect: (_j = options.onDisconnect) !== null && _j !== void 0 ? _j : NOOP,
|
|
3704
|
+
onError: (_k = options.onError) !== null && _k !== void 0 ? _k : NOOP,
|
|
3705
|
+
onDeviceSwitched: (_l = options.onDeviceSwitched) !== null && _l !== void 0 ? _l : NOOP,
|
|
3706
|
+
onDevicesChanged: (_m = options.onDevicesChanged) !== null && _m !== void 0 ? _m : NOOP,
|
|
3707
|
+
onDataMessage: (_o = options.onDataMessage) !== null && _o !== void 0 ? _o : NOOP,
|
|
3708
|
+
onMessage: (_p = options.onMessage) !== null && _p !== void 0 ? _p : NOOP,
|
|
3709
|
+
onUserAmplitudeChange: (_q = options.onUserAmplitudeChange) !== null && _q !== void 0 ? _q : NOOP,
|
|
3710
|
+
onAgentAmplitudeChange: (_r = options.onAgentAmplitudeChange) !== null && _r !== void 0 ? _r : NOOP,
|
|
3711
|
+
onStatusChange: (_s = options.onStatusChange) !== null && _s !== void 0 ? _s : NOOP,
|
|
3712
|
+
onUserIsSpeakingChange: (_t = options.onUserIsSpeakingChange) !== null && _t !== void 0 ? _t : NOOP,
|
|
3713
|
+
onAgentSpeakingChange: (_u = options.onAgentSpeakingChange) !== null && _u !== void 0 ? _u : NOOP,
|
|
3714
|
+
onMuteStateChange: (_v = options.onMuteStateChange) !== null && _v !== void 0 ? _v : NOOP,
|
|
3715
|
+
enableAmplitudeMonitoring: (_w = options.enableAmplitudeMonitoring) !== null && _w !== void 0 ? _w : true,
|
|
3659
3716
|
};
|
|
3660
|
-
this.audioInput = (
|
|
3717
|
+
this.audioInput = (_x = options.audioInput) !== null && _x !== void 0 ? _x : true;
|
|
3718
|
+
this.audioOutput = (_y = options.audioOutput) !== null && _y !== void 0 ? _y : true;
|
|
3661
3719
|
this._emitAudioInput();
|
|
3662
3720
|
this.AMPLITUDE_MONITORING_SAMPLE_RATE = 2;
|
|
3663
3721
|
this._websocketUrl = DEFAULT_WS_URL;
|
|
@@ -4043,11 +4101,30 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
4043
4101
|
}
|
|
4044
4102
|
}
|
|
4045
4103
|
_stopAmplitudeMonitoring() {
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4104
|
+
this._stopPlayerAmplitudeMonitoring();
|
|
4105
|
+
this._stopRecorderAmplitudeMonitoring();
|
|
4106
|
+
}
|
|
4107
|
+
_stopPlayerAmplitudeMonitoring() {
|
|
4108
|
+
var _a;
|
|
4109
|
+
this.agentAudioAmplitude = 0;
|
|
4110
|
+
if (this.options.enableAmplitudeMonitoring && this.options.onAgentAmplitudeChange !== NOOP) {
|
|
4111
|
+
this.options.onAgentAmplitudeChange(0);
|
|
4112
|
+
}
|
|
4113
|
+
if (this.stopPlayerAmplitude) {
|
|
4114
|
+
(_a = this.stopPlayerAmplitude) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
4115
|
+
this.stopPlayerAmplitude = undefined;
|
|
4116
|
+
}
|
|
4117
|
+
}
|
|
4118
|
+
_stopRecorderAmplitudeMonitoring() {
|
|
4119
|
+
var _a;
|
|
4120
|
+
this.userAudioAmplitude = 0;
|
|
4121
|
+
if (this.options.enableAmplitudeMonitoring && this.options.onUserAmplitudeChange !== NOOP) {
|
|
4122
|
+
this.options.onUserAmplitudeChange(0);
|
|
4123
|
+
}
|
|
4124
|
+
if (this.stopRecorderAmplitude) {
|
|
4125
|
+
(_a = this.stopRecorderAmplitude) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
4126
|
+
this.stopRecorderAmplitude = undefined;
|
|
4127
|
+
}
|
|
4051
4128
|
}
|
|
4052
4129
|
async audioInputConnect() {
|
|
4053
4130
|
// Turn mic ON
|
|
@@ -4056,10 +4133,9 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
4056
4133
|
this._setupDeviceChangeListener();
|
|
4057
4134
|
}
|
|
4058
4135
|
async audioInputDisconnect() {
|
|
4059
|
-
var _a;
|
|
4060
4136
|
try {
|
|
4061
4137
|
// stop amplitude monitoring tied to the recorder
|
|
4062
|
-
|
|
4138
|
+
this._stopRecorderAmplitudeMonitoring();
|
|
4063
4139
|
// Try a graceful stop; end() already stops tracks and closes the AudioContext
|
|
4064
4140
|
await this.wavRecorder.end();
|
|
4065
4141
|
this.stopVad();
|
|
@@ -4067,7 +4143,7 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
4067
4143
|
this._teardownDeviceListeners();
|
|
4068
4144
|
this.recorderStarted = false;
|
|
4069
4145
|
}
|
|
4070
|
-
catch (
|
|
4146
|
+
catch (_a) {
|
|
4071
4147
|
// If there wasn't an active session, just release any stray tracks
|
|
4072
4148
|
const stream = this.wavRecorder.getStream();
|
|
4073
4149
|
stream === null || stream === void 0 ? void 0 : stream.getTracks().forEach((t) => t.stop());
|
|
@@ -4085,10 +4161,25 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
4085
4161
|
}
|
|
4086
4162
|
}
|
|
4087
4163
|
}
|
|
4164
|
+
async setAudioOutput(state) {
|
|
4165
|
+
if (this.audioOutput !== state) {
|
|
4166
|
+
this.audioOutput = state;
|
|
4167
|
+
this._emitAudioOutput();
|
|
4168
|
+
if (state) {
|
|
4169
|
+
this.wavPlayer.unmute();
|
|
4170
|
+
}
|
|
4171
|
+
else {
|
|
4172
|
+
this.wavPlayer.mute();
|
|
4173
|
+
}
|
|
4174
|
+
}
|
|
4175
|
+
}
|
|
4088
4176
|
/** Emitters for audio flags */
|
|
4089
4177
|
_emitAudioInput() {
|
|
4090
4178
|
this.options.audioInputChanged(this.audioInput);
|
|
4091
4179
|
}
|
|
4180
|
+
_emitAudioOutput() {
|
|
4181
|
+
this.options.audioOutputChanged(this.audioOutput);
|
|
4182
|
+
}
|
|
4092
4183
|
get audioInputEnabled() {
|
|
4093
4184
|
return this.audioInput;
|
|
4094
4185
|
}
|
|
@@ -4214,6 +4305,12 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
4214
4305
|
if (!this.options.enableAmplitudeMonitoring) {
|
|
4215
4306
|
this.agentAudioAmplitude = 0;
|
|
4216
4307
|
}
|
|
4308
|
+
if (this.audioOutput) {
|
|
4309
|
+
this.wavPlayer.unmute();
|
|
4310
|
+
}
|
|
4311
|
+
else {
|
|
4312
|
+
this.wavPlayer.mute();
|
|
4313
|
+
}
|
|
4217
4314
|
}
|
|
4218
4315
|
async connectToAudioInput() {
|
|
4219
4316
|
if (!this.audioInput) {
|
|
@@ -4287,16 +4384,15 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
4287
4384
|
* Restarts audio recording after a device switch to ensure audio is captured from the new device
|
|
4288
4385
|
*/
|
|
4289
4386
|
async _restartAudioRecording() {
|
|
4290
|
-
var _a, _b
|
|
4387
|
+
var _a, _b;
|
|
4291
4388
|
try {
|
|
4292
4389
|
console.debug('Restarting audio recording after device switch...');
|
|
4293
4390
|
// Stop amplitude monitoring tied to the previous recording session before tearing it down
|
|
4294
|
-
|
|
4295
|
-
this.stopRecorderAmplitude = undefined;
|
|
4391
|
+
this._stopRecorderAmplitudeMonitoring();
|
|
4296
4392
|
try {
|
|
4297
4393
|
await this.wavRecorder.end();
|
|
4298
4394
|
}
|
|
4299
|
-
catch (
|
|
4395
|
+
catch (_c) {
|
|
4300
4396
|
// Ignore cleanup errors
|
|
4301
4397
|
}
|
|
4302
4398
|
// Start with new device
|
|
@@ -4318,7 +4414,7 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
4318
4414
|
this.recorderStarted = true;
|
|
4319
4415
|
this._sendReadyIfNeeded();
|
|
4320
4416
|
}
|
|
4321
|
-
const reportedDeviceId = (
|
|
4417
|
+
const reportedDeviceId = (_a = this.activeDeviceId) !== null && _a !== void 0 ? _a : (this.useSystemDefaultDevice ? 'default' : (_b = this.deviceId) !== null && _b !== void 0 ? _b : 'default');
|
|
4322
4418
|
if (reportedDeviceId !== previousReportedDeviceId) {
|
|
4323
4419
|
this.lastReportedDeviceId = reportedDeviceId;
|
|
4324
4420
|
if (this.options.onDeviceSwitched) {
|
|
@@ -4462,6 +4558,7 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
4462
4558
|
console.log('Microphone muted');
|
|
4463
4559
|
this.options.onMuteStateChange(true);
|
|
4464
4560
|
this.stopVad();
|
|
4561
|
+
this._stopRecorderAmplitudeMonitoring();
|
|
4465
4562
|
}
|
|
4466
4563
|
}
|
|
4467
4564
|
/**
|
|
@@ -4473,6 +4570,9 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
4473
4570
|
console.log('Microphone unmuted');
|
|
4474
4571
|
this.options.onMuteStateChange(false);
|
|
4475
4572
|
this._initializeVAD();
|
|
4573
|
+
if (this.stopRecorderAmplitude === undefined) {
|
|
4574
|
+
this._setupAmplitudeMonitoring(this.wavRecorder, this.options.onUserAmplitudeChange, (amp) => (this.userAudioAmplitude = amp));
|
|
4575
|
+
}
|
|
4476
4576
|
}
|
|
4477
4577
|
}
|
|
4478
4578
|
}
|