@eka-care/ekascribe-ts-sdk 1.4.39

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.
Files changed (71) hide show
  1. package/README.md +437 -0
  2. package/dist/api/get-transaction-history.d.ts +5 -0
  3. package/dist/api/get-transaction-history.js +28 -0
  4. package/dist/api/get-voice-api-v2-config.d.ts +2 -0
  5. package/dist/api/get-voice-api-v2-config.js +26 -0
  6. package/dist/api/get-voice-api-v2-status.d.ts +51 -0
  7. package/dist/api/get-voice-api-v2-status.js +25 -0
  8. package/dist/api/get-voice-api-v3-status.d.ts +51 -0
  9. package/dist/api/get-voice-api-v3-status.js +26 -0
  10. package/dist/api/patch-transaction-status.d.ts +4 -0
  11. package/dist/api/patch-transaction-status.js +43 -0
  12. package/dist/api/post-cog-init.d.ts +3 -0
  13. package/dist/api/post-cog-init.js +15 -0
  14. package/dist/api/post-transaction-commit.d.ts +3 -0
  15. package/dist/api/post-transaction-commit.js +32 -0
  16. package/dist/api/post-transaction-init.d.ts +3 -0
  17. package/dist/api/post-transaction-init.js +40 -0
  18. package/dist/api/post-transaction-stop.d.ts +3 -0
  19. package/dist/api/post-transaction-stop.js +32 -0
  20. package/dist/audio-chunker/__tests__/audio-file-manager.test.d.ts +1 -0
  21. package/dist/audio-chunker/__tests__/audio-file-manager.test.js +5 -0
  22. package/dist/audio-chunker/audio-buffer-manager.d.ts +53 -0
  23. package/dist/audio-chunker/audio-buffer-manager.js +136 -0
  24. package/dist/audio-chunker/audio-file-manager.d.ts +96 -0
  25. package/dist/audio-chunker/audio-file-manager.js +579 -0
  26. package/dist/audio-chunker/vad-web.d.ts +90 -0
  27. package/dist/audio-chunker/vad-web.js +389 -0
  28. package/dist/aws-services/configure-aws.d.ts +5 -0
  29. package/dist/aws-services/configure-aws.js +13 -0
  30. package/dist/aws-services/get-files-s3.d.ts +10 -0
  31. package/dist/aws-services/get-files-s3.js +30 -0
  32. package/dist/aws-services/s3-retry-wrapper.d.ts +2 -0
  33. package/dist/aws-services/s3-retry-wrapper.js +38 -0
  34. package/dist/aws-services/translate-text-to-target-language.d.ts +6 -0
  35. package/dist/aws-services/translate-text-to-target-language.js +18 -0
  36. package/dist/aws-services/upload-file-to-s3.d.ts +13 -0
  37. package/dist/aws-services/upload-file-to-s3.js +48 -0
  38. package/dist/constants/constant.d.ts +27 -0
  39. package/dist/constants/constant.js +33 -0
  40. package/dist/constants/enums.d.ts +46 -0
  41. package/dist/constants/enums.js +51 -0
  42. package/dist/constants/setup-config.d.ts +14 -0
  43. package/dist/constants/setup-config.js +31 -0
  44. package/dist/constants/types.d.ts +224 -0
  45. package/dist/constants/types.js +1 -0
  46. package/dist/fetch-client/helper.d.ts +11 -0
  47. package/dist/fetch-client/helper.js +28 -0
  48. package/dist/fetch-client/index.d.ts +1 -0
  49. package/dist/fetch-client/index.js +36 -0
  50. package/dist/index.d.ts +60 -0
  51. package/dist/index.js +267 -0
  52. package/dist/main/end-recording.d.ts +3 -0
  53. package/dist/main/end-recording.js +141 -0
  54. package/dist/main/init-transaction.d.ts +3 -0
  55. package/dist/main/init-transaction.js +86 -0
  56. package/dist/main/pause-recording.d.ts +3 -0
  57. package/dist/main/pause-recording.js +59 -0
  58. package/dist/main/resume-recording.d.ts +3 -0
  59. package/dist/main/resume-recording.js +33 -0
  60. package/dist/main/retry-upload-recording.d.ts +5 -0
  61. package/dist/main/retry-upload-recording.js +69 -0
  62. package/dist/main/start-recording.d.ts +3 -0
  63. package/dist/main/start-recording.js +55 -0
  64. package/dist/shared-worker/s3-file-upload.d.ts +1 -0
  65. package/dist/shared-worker/s3-file-upload.js +109 -0
  66. package/dist/shared-worker/s3-file-upload.ts +126 -0
  67. package/dist/store/store.d.ts +35 -0
  68. package/dist/store/store.js +121 -0
  69. package/dist/utils/compress-mp3-audio.d.ts +2 -0
  70. package/dist/utils/compress-mp3-audio.js +24 -0
  71. package/package.json +53 -0
@@ -0,0 +1,389 @@
1
+ import { MicVAD } from '@ricky0123/vad-web';
2
+ import { FRAME_SIZE, LONG_SILENCE_THRESHOLD, OUTPUT_FORMAT, PRE_SPEECH_PAD_FRAMES, SDK_STATUS_CODE, SHORT_SILENCE_THRESHOLD, } from '../constants/constant';
3
+ import EkaScribeStore from '../store/store';
4
+ import { ERROR_CODE } from '../constants/enums';
5
+ class VadWebClient {
6
+ /**
7
+ * Class that handle Vad functions and manages audio chunk
8
+ * @param pref_length Preferred length in seconds
9
+ * @param desp_length Desperate length in seconds
10
+ * @param max_length Maximum length in seconds
11
+ * @param sr Sample rate in Hz
12
+ */
13
+ constructor(pref_length, desp_length, max_length, sr) {
14
+ Object.defineProperty(this, "vad_past", {
15
+ enumerable: true,
16
+ configurable: true,
17
+ writable: true,
18
+ value: void 0
19
+ });
20
+ Object.defineProperty(this, "last_clip_index", {
21
+ enumerable: true,
22
+ configurable: true,
23
+ writable: true,
24
+ value: void 0
25
+ });
26
+ Object.defineProperty(this, "clip_points", {
27
+ enumerable: true,
28
+ configurable: true,
29
+ writable: true,
30
+ value: void 0
31
+ });
32
+ Object.defineProperty(this, "sil_duration_acc", {
33
+ enumerable: true,
34
+ configurable: true,
35
+ writable: true,
36
+ value: void 0
37
+ });
38
+ Object.defineProperty(this, "pref_length_samples", {
39
+ enumerable: true,
40
+ configurable: true,
41
+ writable: true,
42
+ value: void 0
43
+ });
44
+ Object.defineProperty(this, "desp_length_samples", {
45
+ enumerable: true,
46
+ configurable: true,
47
+ writable: true,
48
+ value: void 0
49
+ });
50
+ Object.defineProperty(this, "max_length_samples", {
51
+ enumerable: true,
52
+ configurable: true,
53
+ writable: true,
54
+ value: void 0
55
+ });
56
+ Object.defineProperty(this, "shor_thsld", {
57
+ enumerable: true,
58
+ configurable: true,
59
+ writable: true,
60
+ value: void 0
61
+ });
62
+ Object.defineProperty(this, "long_thsld", {
63
+ enumerable: true,
64
+ configurable: true,
65
+ writable: true,
66
+ value: void 0
67
+ });
68
+ Object.defineProperty(this, "frame_size", {
69
+ enumerable: true,
70
+ configurable: true,
71
+ writable: true,
72
+ value: void 0
73
+ });
74
+ Object.defineProperty(this, "speech_pad_frames", {
75
+ enumerable: true,
76
+ configurable: true,
77
+ writable: true,
78
+ value: void 0
79
+ });
80
+ Object.defineProperty(this, "micVad", {
81
+ enumerable: true,
82
+ configurable: true,
83
+ writable: true,
84
+ value: void 0
85
+ }); // MicVad Object
86
+ Object.defineProperty(this, "is_vad_loading", {
87
+ enumerable: true,
88
+ configurable: true,
89
+ writable: true,
90
+ value: true
91
+ });
92
+ Object.defineProperty(this, "noSpeechStartTime", {
93
+ enumerable: true,
94
+ configurable: true,
95
+ writable: true,
96
+ value: null
97
+ });
98
+ Object.defineProperty(this, "recording_started", {
99
+ enumerable: true,
100
+ configurable: true,
101
+ writable: true,
102
+ value: false
103
+ });
104
+ Object.defineProperty(this, "lastWarningTime", {
105
+ enumerable: true,
106
+ configurable: true,
107
+ writable: true,
108
+ value: null
109
+ });
110
+ Object.defineProperty(this, "warningCooldownPeriod", {
111
+ enumerable: true,
112
+ configurable: true,
113
+ writable: true,
114
+ value: 2000
115
+ }); // 2 seconds cooldown after warning
116
+ this.vad_past = [];
117
+ this.last_clip_index = 0;
118
+ this.clip_points = [0];
119
+ this.sil_duration_acc = 0;
120
+ this.pref_length_samples = pref_length * sr;
121
+ this.desp_length_samples = desp_length * sr;
122
+ this.max_length_samples = max_length * sr;
123
+ this.shor_thsld = SHORT_SILENCE_THRESHOLD * sr;
124
+ this.long_thsld = LONG_SILENCE_THRESHOLD * sr;
125
+ this.frame_size = FRAME_SIZE;
126
+ this.speech_pad_frames = PRE_SPEECH_PAD_FRAMES;
127
+ this.micVad = {};
128
+ // instantiate MicVad
129
+ // TODO: initialise this in start recording
130
+ // this.initVad();
131
+ }
132
+ /**
133
+ * Check for continuous silence and trigger periodic warnings
134
+ * @param isSpeech - vad probability (0 or 1)
135
+ */
136
+ checkNoSpeech(isSpeech) {
137
+ if (!this.recording_started)
138
+ return;
139
+ const now = Date.now();
140
+ const errorCallback = EkaScribeStore.errorCallback;
141
+ const silenceThreshold = 10000; // 10 seconds
142
+ if (isSpeech === 0) {
143
+ if (this.noSpeechStartTime === null) {
144
+ this.noSpeechStartTime = now;
145
+ }
146
+ else {
147
+ const silenceDuration = now - this.noSpeechStartTime;
148
+ // Check if we should show a warning (every 10 seconds of silence)
149
+ if (silenceDuration >= silenceThreshold) {
150
+ // Check if enough time has passed since the last warning (cooldown period)
151
+ if (this.lastWarningTime === null ||
152
+ now - this.lastWarningTime >= this.warningCooldownPeriod) {
153
+ if (errorCallback) {
154
+ errorCallback({
155
+ error_code: ERROR_CODE.NO_AUDIO_CAPTURE,
156
+ status_code: SDK_STATUS_CODE.AUDIO_ERROR,
157
+ message: 'No audio detected for a while. Please talk or stop the recording if done.',
158
+ });
159
+ }
160
+ this.lastWarningTime = now;
161
+ // Reset the silence timer to start counting the next 10 seconds
162
+ this.noSpeechStartTime = now;
163
+ }
164
+ }
165
+ }
166
+ }
167
+ else {
168
+ // Reset timers when speech is detected
169
+ this.noSpeechStartTime = null;
170
+ this.lastWarningTime = null;
171
+ if (errorCallback) {
172
+ errorCallback({
173
+ error_code: ERROR_CODE.SPEECH_DETECTED,
174
+ status_code: SDK_STATUS_CODE.SUCCESS,
175
+ message: 'Audio captured. Recording continues.',
176
+ });
177
+ }
178
+ }
179
+ }
180
+ /**
181
+ * Get the micVad instance
182
+ */
183
+ getMicVad() {
184
+ return this.micVad;
185
+ }
186
+ /**
187
+ * Check if VAD is loading
188
+ */
189
+ isVadLoading() {
190
+ return this.is_vad_loading;
191
+ }
192
+ /**
193
+ * Process a VAD frame and determine if it's a clip point
194
+ * @param vad_frame Voice activity detection frame (0 for silence, 1 for speech)
195
+ */
196
+ processVadFrame(vad_frame) {
197
+ let is_clip_point_frame = false;
198
+ if (this.vad_past.length > 0) {
199
+ if (vad_frame === 0) {
200
+ this.sil_duration_acc += 1;
201
+ }
202
+ if (vad_frame === 1) {
203
+ this.sil_duration_acc = 0;
204
+ }
205
+ }
206
+ const sample_passed = this.vad_past.length - this.last_clip_index;
207
+ if (sample_passed > this.pref_length_samples) {
208
+ if (this.sil_duration_acc > this.long_thsld) {
209
+ this.last_clip_index =
210
+ this.vad_past.length - Math.min(Math.floor(this.sil_duration_acc / 2), 5);
211
+ this.clip_points.push(this.last_clip_index);
212
+ this.sil_duration_acc = 0;
213
+ is_clip_point_frame = true;
214
+ }
215
+ }
216
+ if (sample_passed > this.desp_length_samples) {
217
+ if (this.sil_duration_acc > this.shor_thsld) {
218
+ this.last_clip_index =
219
+ this.vad_past.length - Math.min(Math.floor(this.sil_duration_acc / 2), 5);
220
+ this.clip_points.push(this.last_clip_index);
221
+ this.sil_duration_acc = 0;
222
+ is_clip_point_frame = true;
223
+ }
224
+ }
225
+ if (sample_passed >= this.max_length_samples) {
226
+ this.last_clip_index = this.vad_past.length;
227
+ this.clip_points.push(this.last_clip_index);
228
+ this.sil_duration_acc = 0;
229
+ is_clip_point_frame = true;
230
+ }
231
+ this.vad_past.push(vad_frame);
232
+ if (is_clip_point_frame) {
233
+ return [true, this.clip_points[this.clip_points.length - 1]];
234
+ }
235
+ return [false, this.clip_points[this.clip_points.length - 1]];
236
+ }
237
+ /**
238
+ * initialize the VAD instance
239
+ */
240
+ async initVad() {
241
+ const audioFileManager = EkaScribeStore.audioFileManagerInstance;
242
+ const audioBuffer = EkaScribeStore.audioBufferInstance;
243
+ this.is_vad_loading = true;
244
+ const vad = await MicVAD.new({
245
+ frameSamples: this.frame_size,
246
+ preSpeechPadFrames: this.speech_pad_frames,
247
+ onFrameProcessed: (prob, frames) => {
248
+ audioFileManager?.incrementTotalRawSamples(frames);
249
+ audioBuffer?.append(frames);
250
+ // Check if audio chunk needs to be clipped
251
+ const { isSpeech } = prob;
252
+ let vad_dec = 0;
253
+ if (isSpeech >= 0.5) {
254
+ vad_dec = 1;
255
+ }
256
+ // Call the new checkNoSpeech function
257
+ this.checkNoSpeech(vad_dec);
258
+ const vadResponse = this.processVadFrame(vad_dec);
259
+ const is_clip_point = vadResponse[0];
260
+ if (is_clip_point) {
261
+ // audio chunk is of float32 Array <ArrayBuffer>
262
+ const activeAudioChunk = audioBuffer?.getAudioData();
263
+ this.processAudioChunk({ audioFrames: activeAudioChunk });
264
+ }
265
+ },
266
+ onSpeechStart: () => {
267
+ EkaScribeStore.userSpeechCallback?.(true);
268
+ },
269
+ onSpeechEnd: () => {
270
+ EkaScribeStore.userSpeechCallback?.(false);
271
+ },
272
+ });
273
+ this.is_vad_loading = false;
274
+ this.micVad = vad;
275
+ return this.is_vad_loading;
276
+ }
277
+ /**
278
+ * reinitialize the vad instance
279
+ */
280
+ async reinitializeVad() {
281
+ const response = await this.initVad();
282
+ return response;
283
+ }
284
+ /**
285
+ * process and upload audio chunk to s3
286
+ */
287
+ async processAudioChunk({ audioFrames }) {
288
+ const audioFileManager = EkaScribeStore.audioFileManagerInstance;
289
+ const audioBuffer = EkaScribeStore.audioBufferInstance;
290
+ if (!audioFrames || !audioFileManager || !audioBuffer)
291
+ return;
292
+ // get the number of chunks already processed
293
+ const filenumber = (audioFileManager.audioChunks.length || 0) + 1;
294
+ const fileName = `${filenumber}.${OUTPUT_FORMAT}`;
295
+ const rawSampleDetails = audioFileManager.getRawSampleDetails();
296
+ const chunkTimestamps = audioBuffer?.calculateChunkTimestamps(rawSampleDetails.totalRawSamples);
297
+ try {
298
+ const chunkInfo = {
299
+ fileName,
300
+ timestamp: {
301
+ st: chunkTimestamps.start,
302
+ et: chunkTimestamps.end,
303
+ },
304
+ status: 'pending',
305
+ audioFrames,
306
+ };
307
+ const audioChunkLength = audioFileManager.updateAudioInfo(chunkInfo);
308
+ audioFileManager?.incrementInsertedSamples(audioBuffer.getCurrentSampleLength(), audioBuffer.getCurrentFrameLength());
309
+ audioBuffer.resetBufferState();
310
+ await audioFileManager.uploadAudioToS3({
311
+ audioFrames,
312
+ fileName,
313
+ chunkIndex: audioChunkLength - 1,
314
+ });
315
+ }
316
+ catch (error) {
317
+ console.error('Error uploading audio chunk:', error);
318
+ }
319
+ }
320
+ /**
321
+ * Start VAD
322
+ */
323
+ startVad() {
324
+ this.micVad.start();
325
+ this.recording_started = true;
326
+ // this.monitorAudioCapture();
327
+ }
328
+ /**
329
+ * Pause VAD
330
+ */
331
+ pauseVad() {
332
+ this.micVad.pause();
333
+ this.recording_started = false;
334
+ }
335
+ /**
336
+ * reset vadWeb instance
337
+ */
338
+ resetVadWebInstance() {
339
+ this.vad_past = [];
340
+ this.last_clip_index = 0;
341
+ this.clip_points = [0];
342
+ this.sil_duration_acc = 0;
343
+ this.noSpeechStartTime = null;
344
+ this.lastWarningTime = null;
345
+ this.recording_started = false;
346
+ // TODO: will handle this - dont pass this callback - handle it properly - clear the error callback on client side on resetEkascribe
347
+ if (EkaScribeStore.errorCallback) {
348
+ EkaScribeStore.errorCallback({
349
+ error_code: ERROR_CODE.SPEECH_DETECTED,
350
+ status_code: SDK_STATUS_CODE.SUCCESS,
351
+ message: 'Audio captured. Recording continues.',
352
+ });
353
+ }
354
+ }
355
+ /**
356
+ * monitor initial audio capture within starting 4 seconds
357
+ */
358
+ monitorAudioCapture() {
359
+ const audioBuffer = EkaScribeStore.audioBufferInstance;
360
+ const errorCallback = EkaScribeStore.errorCallback;
361
+ setTimeout(() => {
362
+ if (audioBuffer && audioBuffer.getCurrentSampleLength() <= 0) {
363
+ this.micVad.pause();
364
+ if (errorCallback) {
365
+ errorCallback({
366
+ error_code: ERROR_CODE.NO_AUDIO_CAPTURE,
367
+ status_code: SDK_STATUS_CODE.AUDIO_ERROR,
368
+ message: 'No audio is being captured. Please check your microphone.',
369
+ });
370
+ }
371
+ return false;
372
+ }
373
+ return true;
374
+ }, 5000);
375
+ }
376
+ /**
377
+ * Callback to configure constants
378
+ */
379
+ configureVadConstants({ pref_length, desp_length, max_length, sr, frame_size, pre_speech_pad_frames, short_thsld, long_thsld, }) {
380
+ this.pref_length_samples = pref_length * sr;
381
+ this.desp_length_samples = desp_length * sr;
382
+ this.max_length_samples = max_length * sr;
383
+ this.shor_thsld = short_thsld * sr;
384
+ this.long_thsld = long_thsld * sr;
385
+ this.frame_size = frame_size;
386
+ this.speech_pad_frames = pre_speech_pad_frames;
387
+ }
388
+ }
389
+ export default VadWebClient;
@@ -0,0 +1,5 @@
1
+ export declare function configureAWS({ accessKeyId, secretKey, sessionToken, }: {
2
+ accessKeyId: string;
3
+ secretKey: string;
4
+ sessionToken: string;
5
+ }): void;
@@ -0,0 +1,13 @@
1
+ import * as AWS from 'aws-sdk';
2
+ export function configureAWS({ accessKeyId, secretKey, sessionToken, }) {
3
+ try {
4
+ AWS.config.update({
5
+ sessionToken,
6
+ accessKeyId,
7
+ secretAccessKey: secretKey,
8
+ });
9
+ }
10
+ catch (err) {
11
+ console.log(err, 'AWS config error');
12
+ }
13
+ }
@@ -0,0 +1,10 @@
1
+ import * as AWS from 'aws-sdk';
2
+ type TS3Response = {
3
+ response?: AWS.S3.GetObjectOutput;
4
+ error?: string;
5
+ };
6
+ export declare const getFilesS3: ({ fileName, maxPollingTime, }: {
7
+ fileName: string;
8
+ maxPollingTime: number;
9
+ }) => Promise<TS3Response>;
10
+ export {};
@@ -0,0 +1,30 @@
1
+ import * as AWS from 'aws-sdk';
2
+ import s3RetryWrapper from './s3-retry-wrapper';
3
+ export const getFilesS3 = async ({ fileName, maxPollingTime, }) => {
4
+ try {
5
+ const requestBody = {
6
+ Bucket: 'm-prod-voice2rx',
7
+ Key: fileName,
8
+ };
9
+ const getFileCall = () => new Promise((resolve, reject) => {
10
+ const s3Bucket = new AWS.S3({
11
+ region: 'ap-south-1',
12
+ maxRetries: 0,
13
+ });
14
+ s3Bucket.getObject(requestBody, (err, data) => {
15
+ if (err)
16
+ return reject(err);
17
+ resolve(data);
18
+ });
19
+ });
20
+ // retry upload with s3RetryWrapper
21
+ const result = await s3RetryWrapper(getFileCall, maxPollingTime, 1000, 0);
22
+ return {
23
+ response: result,
24
+ };
25
+ }
26
+ catch (error) {
27
+ console.error('getFilesS3 =>', error);
28
+ throw error;
29
+ }
30
+ };
@@ -0,0 +1,2 @@
1
+ declare function s3RetryWrapper<T>(s3Fn: () => Promise<T>, maxRetryCount: number, delay: number, retryAttempt: number, is_shared_worker?: boolean): Promise<T>;
2
+ export default s3RetryWrapper;
@@ -0,0 +1,38 @@
1
+ import postCogInit from '../api/post-cog-init';
2
+ import { configureAWS } from './configure-aws';
3
+ async function s3RetryWrapper(s3Fn, maxRetryCount, delay, retryAttempt, is_shared_worker = false) {
4
+ try {
5
+ return await s3Fn();
6
+ }
7
+ catch (error) {
8
+ if (retryAttempt >= maxRetryCount) {
9
+ throw error;
10
+ }
11
+ if (is_shared_worker) {
12
+ // eslint-disable-next-line
13
+ // @ts-ignore
14
+ if (error.statusCode >= 400) {
15
+ throw error;
16
+ }
17
+ }
18
+ else {
19
+ // eslint-disable-next-line
20
+ // @ts-ignore
21
+ if (error.code === 'ExpiredToken') {
22
+ const cogResponse = await postCogInit();
23
+ const { credentials } = cogResponse;
24
+ if (credentials) {
25
+ configureAWS({
26
+ accessKeyId: credentials.AccessKeyId,
27
+ secretKey: credentials.SecretKey,
28
+ sessionToken: credentials.SessionToken,
29
+ });
30
+ }
31
+ }
32
+ }
33
+ await new Promise((resolve) => setTimeout(resolve, delay));
34
+ // Retry the operation
35
+ return s3RetryWrapper(s3Fn, maxRetryCount, delay, retryAttempt + 1);
36
+ }
37
+ }
38
+ export default s3RetryWrapper;
@@ -0,0 +1,6 @@
1
+ declare function awsTranslateText({ source_language, target_language, content, }: {
2
+ source_language: string;
3
+ target_language: string;
4
+ content: string;
5
+ }): Promise<void>;
6
+ export default awsTranslateText;
@@ -0,0 +1,18 @@
1
+ import { TranslateClient, TranslateTextCommand } from '@aws-sdk/client-translate';
2
+ const translateClient = new TranslateClient({ region: 'ap-south-1' }); // e.g., "us-east-1"
3
+ async function awsTranslateText({ source_language, target_language, content, }) {
4
+ const command = new TranslateTextCommand({
5
+ SourceLanguageCode: source_language,
6
+ TargetLanguageCode: target_language,
7
+ Text: content,
8
+ });
9
+ try {
10
+ const result = await translateClient.send(command);
11
+ console.log(result, 'result');
12
+ console.log('Translated text:', result.TranslatedText);
13
+ }
14
+ catch (error) {
15
+ console.error('Translation error:', error);
16
+ }
17
+ }
18
+ export default awsTranslateText;
@@ -0,0 +1,13 @@
1
+ declare const pushFileToS3: ({ fileBlob, fileName, txnID, businessID, is_shared_worker, }: {
2
+ fileBlob: Blob;
3
+ fileName: string;
4
+ txnID: string;
5
+ businessID: string;
6
+ is_shared_worker?: boolean;
7
+ }) => Promise<{
8
+ success?: string;
9
+ error?: string;
10
+ errorCode?: string;
11
+ code?: number;
12
+ }>;
13
+ export default pushFileToS3;
@@ -0,0 +1,48 @@
1
+ // @ts-nocheck
2
+ import * as AWS from 'aws-sdk';
3
+ import s3RetryWrapper from './s3-retry-wrapper';
4
+ import { S3_BUCKET_NAME } from '../constants/constant';
5
+ const pushFileToS3 = async ({ fileBlob, fileName, txnID, businessID, is_shared_worker = false, }) => {
6
+ try {
7
+ const requestBody = {
8
+ Bucket: S3_BUCKET_NAME,
9
+ Key: fileName,
10
+ Body: fileBlob,
11
+ Metadata: {
12
+ txnid: txnID,
13
+ bid: businessID,
14
+ },
15
+ };
16
+ const uploadCall = () => new Promise((resolve, reject) => {
17
+ const s3Bucket = new AWS.S3({
18
+ region: 'ap-south-1',
19
+ maxRetries: 0,
20
+ });
21
+ s3Bucket.upload(requestBody, (err, data) => {
22
+ if (err)
23
+ return reject(err);
24
+ resolve(data);
25
+ });
26
+ });
27
+ // retry upload with s3RetryWrapper
28
+ const result = await s3RetryWrapper(uploadCall, 3, 2000, 0, is_shared_worker);
29
+ // Return success with the data
30
+ return { success: result.ETag || 'Upload successful' };
31
+ }
32
+ catch (error) {
33
+ const err = JSON.stringify(error, null, 2);
34
+ console.error('pushFilesToS3V2 error =>', err);
35
+ if (error.statusCode && error.statusCode >= 400) {
36
+ return {
37
+ error: `Expired token. Please re-authenticate! ${err}`,
38
+ errorCode: 'ExpiredToken',
39
+ code: error.statusCode,
40
+ };
41
+ }
42
+ return {
43
+ error: `Something went wrong! ${err}`,
44
+ code: error.statusCode,
45
+ };
46
+ }
47
+ };
48
+ export default pushFileToS3;
@@ -0,0 +1,27 @@
1
+ export declare const PREF_CHUNK_LENGTH = 10;
2
+ export declare const DESP_CHUNK_LENGTH = 20;
3
+ export declare const MAX_CHUNK_LENGTH = 25;
4
+ export declare const FRAME_SIZE = 1024;
5
+ export declare const SAMPLING_RATE = 16000;
6
+ export declare const DURATION_PER_FRAME: number;
7
+ export declare const SILENCE_THRESHOLD = 0.01;
8
+ export declare const FRAME_RATE: number;
9
+ export declare const SHORT_SILENCE_THRESHOLD = 0.1;
10
+ export declare const LONG_SILENCE_THRESHOLD = 0.5;
11
+ export declare const SPEECH_DETECTION_THRESHOLD = 0.5;
12
+ export declare const PRE_SPEECH_PAD_FRAMES = 20;
13
+ export declare const BITRATE = 128;
14
+ export declare const QUALITY = 0;
15
+ export declare const CHANNELS = 1;
16
+ export declare const AUDIO_BUFFER_SIZE_IN_S: number;
17
+ export declare const OUTPUT_FORMAT = "mp3";
18
+ export declare const AUDIO_EXTENSION_TYPE_MAP: Record<string, string>;
19
+ export declare const S3_BUCKET_NAME = "m-prod-voice-record";
20
+ export declare const SDK_STATUS_CODE: {
21
+ AUDIO_ERROR: number;
22
+ SUCCESS: number;
23
+ TXN_ERROR: number;
24
+ BAD_REQUEST: number;
25
+ INTERNAL_SERVER_ERROR: number;
26
+ FORBIDDEN: number;
27
+ };
@@ -0,0 +1,33 @@
1
+ export const PREF_CHUNK_LENGTH = 10;
2
+ export const DESP_CHUNK_LENGTH = 20;
3
+ export const MAX_CHUNK_LENGTH = 25;
4
+ export const FRAME_SIZE = 1024;
5
+ export const SAMPLING_RATE = 16000;
6
+ export const DURATION_PER_FRAME = FRAME_SIZE / SAMPLING_RATE;
7
+ export const SILENCE_THRESHOLD = 0.01;
8
+ export const FRAME_RATE = SAMPLING_RATE / FRAME_SIZE;
9
+ export const SHORT_SILENCE_THRESHOLD = 0.1;
10
+ export const LONG_SILENCE_THRESHOLD = 0.5;
11
+ export const SPEECH_DETECTION_THRESHOLD = 0.5;
12
+ // export const REDEMPTION_FRAMES = 10;
13
+ export const PRE_SPEECH_PAD_FRAMES = 20;
14
+ // export const MIN_SPEECH_FRAMES = 80;
15
+ export const BITRATE = 128;
16
+ export const QUALITY = 0;
17
+ export const CHANNELS = 1;
18
+ export const AUDIO_BUFFER_SIZE_IN_S = DESP_CHUNK_LENGTH + 5;
19
+ export const OUTPUT_FORMAT = 'mp3';
20
+ export const AUDIO_EXTENSION_TYPE_MAP = {
21
+ m4a: 'audio/m4a',
22
+ wav: 'audio/wav',
23
+ mp3: 'audio/mpeg',
24
+ };
25
+ export const S3_BUCKET_NAME = 'm-prod-voice-record';
26
+ export const SDK_STATUS_CODE = {
27
+ AUDIO_ERROR: 1001,
28
+ SUCCESS: 200,
29
+ TXN_ERROR: 1003,
30
+ BAD_REQUEST: 1004,
31
+ INTERNAL_SERVER_ERROR: 1005,
32
+ FORBIDDEN: 1006,
33
+ };