@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.
- package/README.md +437 -0
- package/dist/api/get-transaction-history.d.ts +5 -0
- package/dist/api/get-transaction-history.js +28 -0
- package/dist/api/get-voice-api-v2-config.d.ts +2 -0
- package/dist/api/get-voice-api-v2-config.js +26 -0
- package/dist/api/get-voice-api-v2-status.d.ts +51 -0
- package/dist/api/get-voice-api-v2-status.js +25 -0
- package/dist/api/get-voice-api-v3-status.d.ts +51 -0
- package/dist/api/get-voice-api-v3-status.js +26 -0
- package/dist/api/patch-transaction-status.d.ts +4 -0
- package/dist/api/patch-transaction-status.js +43 -0
- package/dist/api/post-cog-init.d.ts +3 -0
- package/dist/api/post-cog-init.js +15 -0
- package/dist/api/post-transaction-commit.d.ts +3 -0
- package/dist/api/post-transaction-commit.js +32 -0
- package/dist/api/post-transaction-init.d.ts +3 -0
- package/dist/api/post-transaction-init.js +40 -0
- package/dist/api/post-transaction-stop.d.ts +3 -0
- package/dist/api/post-transaction-stop.js +32 -0
- package/dist/audio-chunker/__tests__/audio-file-manager.test.d.ts +1 -0
- package/dist/audio-chunker/__tests__/audio-file-manager.test.js +5 -0
- package/dist/audio-chunker/audio-buffer-manager.d.ts +53 -0
- package/dist/audio-chunker/audio-buffer-manager.js +136 -0
- package/dist/audio-chunker/audio-file-manager.d.ts +96 -0
- package/dist/audio-chunker/audio-file-manager.js +579 -0
- package/dist/audio-chunker/vad-web.d.ts +90 -0
- package/dist/audio-chunker/vad-web.js +389 -0
- package/dist/aws-services/configure-aws.d.ts +5 -0
- package/dist/aws-services/configure-aws.js +13 -0
- package/dist/aws-services/get-files-s3.d.ts +10 -0
- package/dist/aws-services/get-files-s3.js +30 -0
- package/dist/aws-services/s3-retry-wrapper.d.ts +2 -0
- package/dist/aws-services/s3-retry-wrapper.js +38 -0
- package/dist/aws-services/translate-text-to-target-language.d.ts +6 -0
- package/dist/aws-services/translate-text-to-target-language.js +18 -0
- package/dist/aws-services/upload-file-to-s3.d.ts +13 -0
- package/dist/aws-services/upload-file-to-s3.js +48 -0
- package/dist/constants/constant.d.ts +27 -0
- package/dist/constants/constant.js +33 -0
- package/dist/constants/enums.d.ts +46 -0
- package/dist/constants/enums.js +51 -0
- package/dist/constants/setup-config.d.ts +14 -0
- package/dist/constants/setup-config.js +31 -0
- package/dist/constants/types.d.ts +224 -0
- package/dist/constants/types.js +1 -0
- package/dist/fetch-client/helper.d.ts +11 -0
- package/dist/fetch-client/helper.js +28 -0
- package/dist/fetch-client/index.d.ts +1 -0
- package/dist/fetch-client/index.js +36 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.js +267 -0
- package/dist/main/end-recording.d.ts +3 -0
- package/dist/main/end-recording.js +141 -0
- package/dist/main/init-transaction.d.ts +3 -0
- package/dist/main/init-transaction.js +86 -0
- package/dist/main/pause-recording.d.ts +3 -0
- package/dist/main/pause-recording.js +59 -0
- package/dist/main/resume-recording.d.ts +3 -0
- package/dist/main/resume-recording.js +33 -0
- package/dist/main/retry-upload-recording.d.ts +5 -0
- package/dist/main/retry-upload-recording.js +69 -0
- package/dist/main/start-recording.d.ts +3 -0
- package/dist/main/start-recording.js +55 -0
- package/dist/shared-worker/s3-file-upload.d.ts +1 -0
- package/dist/shared-worker/s3-file-upload.js +109 -0
- package/dist/shared-worker/s3-file-upload.ts +126 -0
- package/dist/store/store.d.ts +35 -0
- package/dist/store/store.js +121 -0
- package/dist/utils/compress-mp3-audio.d.ts +2 -0
- package/dist/utils/compress-mp3-audio.js +24 -0
- package/package.json +53 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import postTransactionCommit from '../api/post-transaction-commit';
|
|
2
|
+
import { SDK_STATUS_CODE } from '../constants/constant';
|
|
3
|
+
import { ERROR_CODE } from '../constants/enums';
|
|
4
|
+
import EkaScribeStore from '../store/store';
|
|
5
|
+
const retryUploadFailedFiles = async ({ force_commit, }) => {
|
|
6
|
+
try {
|
|
7
|
+
const fileManagerInstance = EkaScribeStore.audioFileManagerInstance;
|
|
8
|
+
if (!fileManagerInstance) {
|
|
9
|
+
throw new Error('Class instances are not initialized');
|
|
10
|
+
}
|
|
11
|
+
const failedFiles = (await fileManagerInstance.retryFailedUploads()) || [];
|
|
12
|
+
const audioInfo = fileManagerInstance?.audioChunks;
|
|
13
|
+
const audioFiles = audioInfo.map((audio) => audio.fileName);
|
|
14
|
+
if (failedFiles.length > 0 && !force_commit) {
|
|
15
|
+
return {
|
|
16
|
+
error_code: ERROR_CODE.AUDIO_UPLOAD_FAILED,
|
|
17
|
+
status_code: SDK_STATUS_CODE.AUDIO_ERROR,
|
|
18
|
+
message: 'Audio upload failed for some files after retry.',
|
|
19
|
+
failed_files: failedFiles,
|
|
20
|
+
total_audio_files: audioFiles,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
// call commit transaction api
|
|
24
|
+
const txnID = EkaScribeStore.txnID;
|
|
25
|
+
if (EkaScribeStore.sessionStatus[txnID].api?.status === 'stop' ||
|
|
26
|
+
EkaScribeStore.sessionStatus[txnID].api?.status === 'commit') {
|
|
27
|
+
const { message: txnCommitMsg, code: txnCommitStatusCode } = await postTransactionCommit({
|
|
28
|
+
txnId: EkaScribeStore.txnID,
|
|
29
|
+
audioFiles,
|
|
30
|
+
});
|
|
31
|
+
if (txnCommitStatusCode != 200) {
|
|
32
|
+
return {
|
|
33
|
+
error_code: ERROR_CODE.TXN_COMMIT_FAILED,
|
|
34
|
+
status_code: txnCommitStatusCode,
|
|
35
|
+
message: txnCommitMsg || 'Transaction stop failed.',
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
EkaScribeStore.sessionStatus[txnID] = {
|
|
39
|
+
...EkaScribeStore.sessionStatus[txnID],
|
|
40
|
+
api: {
|
|
41
|
+
status: 'commit',
|
|
42
|
+
code: txnCommitStatusCode,
|
|
43
|
+
response: txnCommitMsg,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// transaction is not stopped or committed
|
|
49
|
+
return {
|
|
50
|
+
error_code: ERROR_CODE.TXN_STATUS_MISMATCH,
|
|
51
|
+
status_code: SDK_STATUS_CODE.TXN_ERROR,
|
|
52
|
+
message: 'Transaction is not initialised or stopped. Cannot end recording.',
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
status_code: SDK_STATUS_CODE.SUCCESS,
|
|
57
|
+
message: 'All recordings uploaded successfully.',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
console.error('Error retrying upload: ', error);
|
|
62
|
+
return {
|
|
63
|
+
error_code: ERROR_CODE.INTERNAL_SERVER_ERROR,
|
|
64
|
+
status_code: SDK_STATUS_CODE.INTERNAL_SERVER_ERROR,
|
|
65
|
+
message: `An error occurred while retrying failed upload: ${error}`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
export default retryUploadFailedFiles;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { SDK_STATUS_CODE } from '../constants/constant';
|
|
2
|
+
import { ERROR_CODE } from '../constants/enums';
|
|
3
|
+
import EkaScribeStore from '../store/store';
|
|
4
|
+
const startVoiceRecording = async () => {
|
|
5
|
+
try {
|
|
6
|
+
const vadInstance = EkaScribeStore.vadInstance;
|
|
7
|
+
const navigatorPermissionResponse = await navigator.permissions.query({
|
|
8
|
+
name: 'microphone',
|
|
9
|
+
});
|
|
10
|
+
if (navigatorPermissionResponse.state !== 'granted') {
|
|
11
|
+
return {
|
|
12
|
+
error_code: ERROR_CODE.MICROPHONE,
|
|
13
|
+
status_code: SDK_STATUS_CODE.FORBIDDEN,
|
|
14
|
+
message: 'Microphone access is required to start recording. Please recheck access.',
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
console.log('%c Line:22 🍇 vadInstance', 'color:#fca650', vadInstance);
|
|
18
|
+
const micVad = vadInstance?.getMicVad();
|
|
19
|
+
const isVadLoading = vadInstance?.isVadLoading();
|
|
20
|
+
if (isVadLoading || !micVad || Object.keys(micVad).length === 0) {
|
|
21
|
+
// retry initiating vad once and if still is in loading return error
|
|
22
|
+
const reinitializeVadResponse = await vadInstance?.reinitializeVad();
|
|
23
|
+
console.log(reinitializeVadResponse, 'reinitialize vad response');
|
|
24
|
+
if (reinitializeVadResponse) {
|
|
25
|
+
return {
|
|
26
|
+
error_code: ERROR_CODE.VAD_NOT_INITIALIZED,
|
|
27
|
+
status_code: SDK_STATUS_CODE.FORBIDDEN,
|
|
28
|
+
message: 'VAD instance is not initialized. Please try again later.',
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
vadInstance?.startVad();
|
|
33
|
+
const txn_id = EkaScribeStore.txnID;
|
|
34
|
+
EkaScribeStore.sessionStatus[txn_id] = {
|
|
35
|
+
...EkaScribeStore.sessionStatus[txn_id],
|
|
36
|
+
vad: {
|
|
37
|
+
status: 'start',
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
return {
|
|
41
|
+
message: 'Recording started successfully.',
|
|
42
|
+
status_code: SDK_STATUS_CODE.SUCCESS,
|
|
43
|
+
txn_id,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
console.log('%c Line:102 🍇 startRecording err', 'color:#b03734', err);
|
|
48
|
+
return {
|
|
49
|
+
error_code: ERROR_CODE.INTERNAL_SERVER_ERROR,
|
|
50
|
+
status_code: SDK_STATUS_CODE.INTERNAL_SERVER_ERROR,
|
|
51
|
+
message: `An error occurred while starting the recording: ${err}`,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
export default startVoiceRecording;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// window is undefined in sharedWorker so it is needed to decode the XML AWS error
|
|
2
|
+
if (typeof window === 'undefined') {
|
|
3
|
+
self.window = self;
|
|
4
|
+
}
|
|
5
|
+
import { configureAWS } from '../aws-services/configure-aws';
|
|
6
|
+
import pushFileToS3 from '../aws-services/upload-file-to-s3';
|
|
7
|
+
import { AUDIO_EXTENSION_TYPE_MAP, OUTPUT_FORMAT } from '../constants/constant';
|
|
8
|
+
import { SHARED_WORKER_ACTION } from '../constants/enums';
|
|
9
|
+
import compressAudioToMp3 from '../utils/compress-mp3-audio';
|
|
10
|
+
// onconnect - to establish communication channel with the main thread
|
|
11
|
+
// eslint-disable-next-line
|
|
12
|
+
// @ts-ignore
|
|
13
|
+
onconnect = function (event) {
|
|
14
|
+
// after connection messages are being channelled through the port
|
|
15
|
+
const workerPort = event.ports[0];
|
|
16
|
+
let uploadRequestReceived = 0;
|
|
17
|
+
let uploadRequestCompleted = 0;
|
|
18
|
+
// onmessage - to handle messages from the main thread
|
|
19
|
+
workerPort.onmessage = async function (event) {
|
|
20
|
+
const workerData = event.data;
|
|
21
|
+
switch (workerData.action) {
|
|
22
|
+
case SHARED_WORKER_ACTION.CONFIGURE_AWS: {
|
|
23
|
+
try {
|
|
24
|
+
const { accessKeyId, secretKey, sessionToken } = workerData.payload;
|
|
25
|
+
configureAWS({
|
|
26
|
+
accessKeyId,
|
|
27
|
+
secretKey,
|
|
28
|
+
sessionToken,
|
|
29
|
+
});
|
|
30
|
+
workerPort.postMessage({
|
|
31
|
+
action: SHARED_WORKER_ACTION.CONFIGURE_AWS_SUCCESS,
|
|
32
|
+
message: 'AWS configured successfully',
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
workerPort.postMessage({
|
|
37
|
+
action: SHARED_WORKER_ACTION.CONFIGURE_AWS_ERROR,
|
|
38
|
+
error: error || 'Failed to configure AWS',
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
case SHARED_WORKER_ACTION.UPLOAD_FILE_WITH_WORKER: {
|
|
44
|
+
const { fileName, audioFrames, txnID, businessID, fileBlob } = workerData.payload;
|
|
45
|
+
uploadRequestReceived++;
|
|
46
|
+
let audioBlob;
|
|
47
|
+
let compressedAudioBuffer;
|
|
48
|
+
if (fileBlob) {
|
|
49
|
+
audioBlob = fileBlob;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
compressedAudioBuffer = compressAudioToMp3(audioFrames);
|
|
53
|
+
audioBlob = new Blob(compressedAudioBuffer, {
|
|
54
|
+
type: AUDIO_EXTENSION_TYPE_MAP[OUTPUT_FORMAT],
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
await pushFileToS3({
|
|
58
|
+
fileBlob: audioBlob,
|
|
59
|
+
fileName,
|
|
60
|
+
txnID,
|
|
61
|
+
businessID,
|
|
62
|
+
is_shared_worker: true,
|
|
63
|
+
})
|
|
64
|
+
.then((response) => {
|
|
65
|
+
uploadRequestCompleted++;
|
|
66
|
+
// postMessage - to send messages back to the main thread
|
|
67
|
+
workerPort.postMessage({
|
|
68
|
+
action: SHARED_WORKER_ACTION.UPLOAD_FILE_WITH_WORKER_SUCCESS,
|
|
69
|
+
response,
|
|
70
|
+
requestBody: {
|
|
71
|
+
...workerData.payload,
|
|
72
|
+
fileBlob: audioBlob,
|
|
73
|
+
compressedAudioBuffer,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
})
|
|
77
|
+
.catch((error) => {
|
|
78
|
+
console.log(error, 'shared worker - file upload');
|
|
79
|
+
uploadRequestCompleted++;
|
|
80
|
+
});
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
case SHARED_WORKER_ACTION.WAIT_FOR_ALL_UPLOADS: {
|
|
84
|
+
if (uploadRequestReceived === uploadRequestCompleted) {
|
|
85
|
+
workerPort.postMessage({
|
|
86
|
+
action: SHARED_WORKER_ACTION.WAIT_FOR_ALL_UPLOADS_SUCCESS,
|
|
87
|
+
response: {
|
|
88
|
+
uploadRequestReceived,
|
|
89
|
+
uploadRequestCompleted,
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
workerPort.postMessage({
|
|
95
|
+
action: SHARED_WORKER_ACTION.WAIT_FOR_ALL_UPLOADS_ERROR,
|
|
96
|
+
response: {
|
|
97
|
+
uploadRequestReceived,
|
|
98
|
+
uploadRequestCompleted,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
workerPort.postMessage(`[WORKER] Web worker onmessage established ${JSON.stringify(workerPort)}`);
|
|
106
|
+
// start the worker port to listen for messages
|
|
107
|
+
workerPort.start();
|
|
108
|
+
};
|
|
109
|
+
console.log('File upload web worker created');
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// window is undefined in sharedWorker so it is needed to decode the XML AWS error
|
|
2
|
+
if (typeof window === 'undefined') {
|
|
3
|
+
self.window = self;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
import { configureAWS } from '../aws-services/configure-aws';
|
|
7
|
+
import pushFileToS3 from '../aws-services/upload-file-to-s3';
|
|
8
|
+
import { AUDIO_EXTENSION_TYPE_MAP, OUTPUT_FORMAT } from '../constants/constant';
|
|
9
|
+
import { SHARED_WORKER_ACTION } from '../constants/enums';
|
|
10
|
+
import compressAudioToMp3 from '../utils/compress-mp3-audio';
|
|
11
|
+
|
|
12
|
+
// onconnect - to establish communication channel with the main thread
|
|
13
|
+
// eslint-disable-next-line
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
onconnect = function (event: MessageEvent) {
|
|
16
|
+
// after connection messages are being channelled through the port
|
|
17
|
+
const workerPort = event.ports[0];
|
|
18
|
+
|
|
19
|
+
let uploadRequestReceived: number = 0;
|
|
20
|
+
let uploadRequestCompleted: number = 0;
|
|
21
|
+
|
|
22
|
+
// onmessage - to handle messages from the main thread
|
|
23
|
+
workerPort.onmessage = async function (event) {
|
|
24
|
+
const workerData = event.data;
|
|
25
|
+
|
|
26
|
+
switch (workerData.action) {
|
|
27
|
+
case SHARED_WORKER_ACTION.CONFIGURE_AWS: {
|
|
28
|
+
try {
|
|
29
|
+
const { accessKeyId, secretKey, sessionToken } = workerData.payload;
|
|
30
|
+
|
|
31
|
+
configureAWS({
|
|
32
|
+
accessKeyId,
|
|
33
|
+
secretKey,
|
|
34
|
+
sessionToken,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
workerPort.postMessage({
|
|
38
|
+
action: SHARED_WORKER_ACTION.CONFIGURE_AWS_SUCCESS,
|
|
39
|
+
message: 'AWS configured successfully',
|
|
40
|
+
});
|
|
41
|
+
} catch (error: unknown) {
|
|
42
|
+
workerPort.postMessage({
|
|
43
|
+
action: SHARED_WORKER_ACTION.CONFIGURE_AWS_ERROR,
|
|
44
|
+
error: error || 'Failed to configure AWS',
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
case SHARED_WORKER_ACTION.UPLOAD_FILE_WITH_WORKER: {
|
|
52
|
+
const { fileName, audioFrames, txnID, businessID, fileBlob } = workerData.payload;
|
|
53
|
+
uploadRequestReceived++;
|
|
54
|
+
|
|
55
|
+
let audioBlob: Blob;
|
|
56
|
+
let compressedAudioBuffer: Uint8Array<ArrayBufferLike>[];
|
|
57
|
+
|
|
58
|
+
if (fileBlob) {
|
|
59
|
+
audioBlob = fileBlob;
|
|
60
|
+
} else {
|
|
61
|
+
compressedAudioBuffer = compressAudioToMp3(audioFrames);
|
|
62
|
+
|
|
63
|
+
audioBlob = new Blob(compressedAudioBuffer, {
|
|
64
|
+
type: AUDIO_EXTENSION_TYPE_MAP[OUTPUT_FORMAT],
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
await pushFileToS3({
|
|
69
|
+
fileBlob: audioBlob,
|
|
70
|
+
fileName,
|
|
71
|
+
txnID,
|
|
72
|
+
businessID,
|
|
73
|
+
is_shared_worker: true,
|
|
74
|
+
})
|
|
75
|
+
.then((response) => {
|
|
76
|
+
uploadRequestCompleted++;
|
|
77
|
+
// postMessage - to send messages back to the main thread
|
|
78
|
+
workerPort.postMessage({
|
|
79
|
+
action: SHARED_WORKER_ACTION.UPLOAD_FILE_WITH_WORKER_SUCCESS,
|
|
80
|
+
response,
|
|
81
|
+
requestBody: {
|
|
82
|
+
...workerData.payload,
|
|
83
|
+
fileBlob: audioBlob,
|
|
84
|
+
compressedAudioBuffer,
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
})
|
|
88
|
+
.catch((error) => {
|
|
89
|
+
console.log(error, 'shared worker - file upload');
|
|
90
|
+
uploadRequestCompleted++;
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
case SHARED_WORKER_ACTION.WAIT_FOR_ALL_UPLOADS: {
|
|
97
|
+
if (uploadRequestReceived === uploadRequestCompleted) {
|
|
98
|
+
workerPort.postMessage({
|
|
99
|
+
action: SHARED_WORKER_ACTION.WAIT_FOR_ALL_UPLOADS_SUCCESS,
|
|
100
|
+
response: {
|
|
101
|
+
uploadRequestReceived,
|
|
102
|
+
uploadRequestCompleted,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
workerPort.postMessage({
|
|
109
|
+
action: SHARED_WORKER_ACTION.WAIT_FOR_ALL_UPLOADS_ERROR,
|
|
110
|
+
response: {
|
|
111
|
+
uploadRequestReceived,
|
|
112
|
+
uploadRequestCompleted,
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
workerPort.postMessage(`[WORKER] Web worker onmessage established ${JSON.stringify(workerPort)}`);
|
|
121
|
+
|
|
122
|
+
// start the worker port to listen for messages
|
|
123
|
+
workerPort.start();
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
console.log('File upload web worker created');
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import AudioBufferManager from '../audio-chunker/audio-buffer-manager';
|
|
2
|
+
import AudioFileManager from '../audio-chunker/audio-file-manager';
|
|
3
|
+
import VadWebClient from '../audio-chunker/vad-web';
|
|
4
|
+
import { TErrorCallback, TSessionStatus } from '../constants/types';
|
|
5
|
+
declare class EkaScribeStore {
|
|
6
|
+
private static instance;
|
|
7
|
+
private _txnID;
|
|
8
|
+
private _sessionBucketPath;
|
|
9
|
+
private _vadInstance;
|
|
10
|
+
private _audioFileManagerInstance;
|
|
11
|
+
private _audioBufferInstance;
|
|
12
|
+
private _sessionStatus;
|
|
13
|
+
private _errorCallback;
|
|
14
|
+
private _userSpeechCallback;
|
|
15
|
+
static getInstance(): EkaScribeStore;
|
|
16
|
+
get vadInstance(): VadWebClient | null;
|
|
17
|
+
set vadInstance(value: VadWebClient);
|
|
18
|
+
get audioFileManagerInstance(): AudioFileManager | null;
|
|
19
|
+
set audioFileManagerInstance(value: AudioFileManager);
|
|
20
|
+
get audioBufferInstance(): AudioBufferManager | null;
|
|
21
|
+
set audioBufferInstance(value: AudioBufferManager);
|
|
22
|
+
get txnID(): string;
|
|
23
|
+
set txnID(value: string);
|
|
24
|
+
get sessionBucketPath(): string;
|
|
25
|
+
set sessionBucketPath(value: string);
|
|
26
|
+
get sessionStatus(): TSessionStatus;
|
|
27
|
+
set sessionStatus(value: TSessionStatus);
|
|
28
|
+
get errorCallback(): TErrorCallback | null;
|
|
29
|
+
set errorCallback(callback: TErrorCallback | null);
|
|
30
|
+
get userSpeechCallback(): ((isSpeech: boolean) => void) | null;
|
|
31
|
+
set userSpeechCallback(callback: ((isSpeech: boolean) => void) | null);
|
|
32
|
+
resetStore(): void;
|
|
33
|
+
}
|
|
34
|
+
declare const _default: EkaScribeStore;
|
|
35
|
+
export default _default;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
class EkaScribeStore {
|
|
2
|
+
constructor() {
|
|
3
|
+
Object.defineProperty(this, "_txnID", {
|
|
4
|
+
enumerable: true,
|
|
5
|
+
configurable: true,
|
|
6
|
+
writable: true,
|
|
7
|
+
value: ''
|
|
8
|
+
});
|
|
9
|
+
Object.defineProperty(this, "_sessionBucketPath", {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
configurable: true,
|
|
12
|
+
writable: true,
|
|
13
|
+
value: ''
|
|
14
|
+
});
|
|
15
|
+
Object.defineProperty(this, "_vadInstance", {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
configurable: true,
|
|
18
|
+
writable: true,
|
|
19
|
+
value: null
|
|
20
|
+
}); // vadWebClient Instance
|
|
21
|
+
Object.defineProperty(this, "_audioFileManagerInstance", {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
configurable: true,
|
|
24
|
+
writable: true,
|
|
25
|
+
value: null
|
|
26
|
+
}); // AudioFileManager Instance
|
|
27
|
+
Object.defineProperty(this, "_audioBufferInstance", {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
configurable: true,
|
|
30
|
+
writable: true,
|
|
31
|
+
value: null
|
|
32
|
+
}); // AudioBuffer Instance
|
|
33
|
+
Object.defineProperty(this, "_sessionStatus", {
|
|
34
|
+
enumerable: true,
|
|
35
|
+
configurable: true,
|
|
36
|
+
writable: true,
|
|
37
|
+
value: {}
|
|
38
|
+
});
|
|
39
|
+
Object.defineProperty(this, "_errorCallback", {
|
|
40
|
+
enumerable: true,
|
|
41
|
+
configurable: true,
|
|
42
|
+
writable: true,
|
|
43
|
+
value: null
|
|
44
|
+
});
|
|
45
|
+
Object.defineProperty(this, "_userSpeechCallback", {
|
|
46
|
+
enumerable: true,
|
|
47
|
+
configurable: true,
|
|
48
|
+
writable: true,
|
|
49
|
+
value: null
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
static getInstance() {
|
|
53
|
+
if (!EkaScribeStore.instance) {
|
|
54
|
+
EkaScribeStore.instance = new EkaScribeStore();
|
|
55
|
+
}
|
|
56
|
+
return EkaScribeStore.instance;
|
|
57
|
+
}
|
|
58
|
+
// VadWebClient Instance
|
|
59
|
+
get vadInstance() {
|
|
60
|
+
return this._vadInstance;
|
|
61
|
+
}
|
|
62
|
+
set vadInstance(value) {
|
|
63
|
+
this._vadInstance = value;
|
|
64
|
+
}
|
|
65
|
+
// AudioFileManager Instance
|
|
66
|
+
get audioFileManagerInstance() {
|
|
67
|
+
return this._audioFileManagerInstance;
|
|
68
|
+
}
|
|
69
|
+
set audioFileManagerInstance(value) {
|
|
70
|
+
this._audioFileManagerInstance = value;
|
|
71
|
+
}
|
|
72
|
+
// AudioBuffer Instance
|
|
73
|
+
get audioBufferInstance() {
|
|
74
|
+
return this._audioBufferInstance;
|
|
75
|
+
}
|
|
76
|
+
set audioBufferInstance(value) {
|
|
77
|
+
this._audioBufferInstance = value;
|
|
78
|
+
}
|
|
79
|
+
// Transaction ID
|
|
80
|
+
get txnID() {
|
|
81
|
+
return this._txnID;
|
|
82
|
+
}
|
|
83
|
+
set txnID(value) {
|
|
84
|
+
this._txnID = value;
|
|
85
|
+
}
|
|
86
|
+
// session file Path - date/txnID
|
|
87
|
+
get sessionBucketPath() {
|
|
88
|
+
return this._sessionBucketPath;
|
|
89
|
+
}
|
|
90
|
+
set sessionBucketPath(value) {
|
|
91
|
+
this._sessionBucketPath = value;
|
|
92
|
+
}
|
|
93
|
+
// Session Status
|
|
94
|
+
get sessionStatus() {
|
|
95
|
+
return this._sessionStatus;
|
|
96
|
+
}
|
|
97
|
+
set sessionStatus(value) {
|
|
98
|
+
this._sessionStatus = value;
|
|
99
|
+
}
|
|
100
|
+
// Error Callback
|
|
101
|
+
get errorCallback() {
|
|
102
|
+
return this._errorCallback;
|
|
103
|
+
}
|
|
104
|
+
set errorCallback(callback) {
|
|
105
|
+
this._errorCallback = callback;
|
|
106
|
+
}
|
|
107
|
+
// User Speech Callback
|
|
108
|
+
get userSpeechCallback() {
|
|
109
|
+
return this._userSpeechCallback;
|
|
110
|
+
}
|
|
111
|
+
set userSpeechCallback(callback) {
|
|
112
|
+
this._userSpeechCallback = callback;
|
|
113
|
+
}
|
|
114
|
+
// Reset store to initial state
|
|
115
|
+
resetStore() {
|
|
116
|
+
this._txnID = '';
|
|
117
|
+
this._sessionBucketPath = '';
|
|
118
|
+
this._sessionStatus = {};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
export default EkaScribeStore.getInstance();
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as lamejs from '@breezystack/lamejs';
|
|
2
|
+
import { BITRATE, SAMPLING_RATE } from '../constants/constant';
|
|
3
|
+
const compressAudioToMp3 = (audio) => {
|
|
4
|
+
try {
|
|
5
|
+
const audioEncoder = new lamejs.Mp3Encoder(1, SAMPLING_RATE, BITRATE);
|
|
6
|
+
// convert Float32Array to Int16Array
|
|
7
|
+
const samples = new Int16Array(audio.length);
|
|
8
|
+
for (let i = 0; i < audio.length; i++) {
|
|
9
|
+
const s = Math.max(-1, Math.min(1, audio[i]));
|
|
10
|
+
samples[i] = s < 0 ? s * 32768 : s * 32767;
|
|
11
|
+
}
|
|
12
|
+
const mp3Data = [];
|
|
13
|
+
const encodedBuffer = audioEncoder.encodeBuffer(samples);
|
|
14
|
+
mp3Data.push(encodedBuffer);
|
|
15
|
+
const lastAudioBuffer = audioEncoder.flush();
|
|
16
|
+
mp3Data.push(lastAudioBuffer);
|
|
17
|
+
return mp3Data;
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
console.error('Error compressing audio to MP3: lamejs: ', error);
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
export default compressAudioToMp3;
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@eka-care/ekascribe-ts-sdk",
|
|
3
|
+
"version": "1.4.39",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"repository": "git@github.com:eka-care/eka-js-sdk.git",
|
|
6
|
+
"author": "Sanikagoyal28 <sanikagoyal9@gmail.com>",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"ekascribe",
|
|
9
|
+
"typescript",
|
|
10
|
+
"sdk",
|
|
11
|
+
"javascript",
|
|
12
|
+
"voice2rx",
|
|
13
|
+
"eka care"
|
|
14
|
+
],
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"types": "dist/index.d.ts",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc && cp -R eka-sdk/ekascribe-v2rx/shared-worker dist",
|
|
19
|
+
"lint": "eslint . --ext .ts",
|
|
20
|
+
"start": "ts-node ./eka-sdk/ekascribe-v2rx/index.ts",
|
|
21
|
+
"prepare": "yarn build"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=14.0.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^22.14.1",
|
|
31
|
+
"@typescript-eslint/eslint-plugin": "^8.30.1",
|
|
32
|
+
"@typescript-eslint/parser": "^8.30.1",
|
|
33
|
+
"eslint": "^9.25.0",
|
|
34
|
+
"ts-node": "^10.9.2",
|
|
35
|
+
"typescript": "^5.8.3"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@aws-sdk/client-translate": "^3.857.0",
|
|
39
|
+
"@breezystack/lamejs": "^1.2.7",
|
|
40
|
+
"@ffmpeg/ffmpeg": "0.9.4",
|
|
41
|
+
"@ffmpeg/util": "^0.12.2",
|
|
42
|
+
"@ricky0123/vad-web": "^0.0.22",
|
|
43
|
+
"@types/chrome": "^0.0.315",
|
|
44
|
+
"aws-sdk": "^2.1692.0",
|
|
45
|
+
"lamejs": "^1.2.1",
|
|
46
|
+
"uuid": "^11.1.0"
|
|
47
|
+
},
|
|
48
|
+
"files": [
|
|
49
|
+
"dist",
|
|
50
|
+
"README.md",
|
|
51
|
+
"LICENSE"
|
|
52
|
+
]
|
|
53
|
+
}
|