@mulingai-npm/redis 1.8.1 → 1.10.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.
|
@@ -4,11 +4,15 @@ export type TranslationStatus = 'INIT' | 'DISCARDED' | 'READY' | 'USED';
|
|
|
4
4
|
export type TtsStatus = 'INIT' | 'DISCARDED' | 'READY' | 'USED';
|
|
5
5
|
export type MulingstreamChunkStatus = 'INIT' | 'IN_PROGRESS' | 'DISCARDED' | 'USED';
|
|
6
6
|
export type MulingstreamChunkStep = 'RECEIVED' | 'STT' | 'TRANSLATION' | 'TTS' | 'EMITTED' | 'COMPLETED' | 'CANCELED';
|
|
7
|
+
export type SttProvider = 'azure' | 'whisper' | 'google' | 'aws';
|
|
7
8
|
export type MulingstreamChunkData = {
|
|
8
9
|
mulingstreamChunkId: string;
|
|
9
10
|
roomId: string;
|
|
10
11
|
chunkNumber: number;
|
|
11
12
|
language: string;
|
|
13
|
+
sttProviders: SttProvider[];
|
|
14
|
+
targetLanguages: string[];
|
|
15
|
+
finalTranscription: string;
|
|
12
16
|
mulingstreamChunkStatus: MulingstreamChunkStatus;
|
|
13
17
|
mulingstreamChunkStep: MulingstreamChunkStep;
|
|
14
18
|
audioChunk: {
|
|
@@ -21,19 +25,21 @@ export type MulingstreamChunkData = {
|
|
|
21
25
|
processingStart: number;
|
|
22
26
|
};
|
|
23
27
|
stt: {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
finalTranscription: string;
|
|
29
|
-
status: SttStatus;
|
|
28
|
+
[sttService: string]: {
|
|
29
|
+
transcription: string;
|
|
30
|
+
status: SttStatus;
|
|
31
|
+
};
|
|
30
32
|
};
|
|
31
|
-
|
|
33
|
+
translation: {
|
|
32
34
|
[language: string]: {
|
|
33
35
|
translation: string;
|
|
34
|
-
|
|
36
|
+
status: TranslationStatus;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
tts: {
|
|
40
|
+
[language: string]: {
|
|
35
41
|
ttsAudioPath: string;
|
|
36
|
-
|
|
42
|
+
status: TtsStatus;
|
|
37
43
|
isEmitted: boolean;
|
|
38
44
|
};
|
|
39
45
|
};
|
|
@@ -52,13 +58,32 @@ export declare class MulingstreamChunkManager {
|
|
|
52
58
|
isFirst: boolean;
|
|
53
59
|
isLast: boolean;
|
|
54
60
|
theme: string;
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
sttProviders: SttProvider[];
|
|
62
|
+
targetLanguages: string[];
|
|
57
63
|
}): Promise<string>;
|
|
58
64
|
getMulingstreamChunks(): Promise<MulingstreamChunkData[]>;
|
|
59
65
|
getMulingstreamChunk(mulingstreamChunkId: string): Promise<MulingstreamChunkData | null>;
|
|
60
66
|
getMulingstreamChunksByRoom(roomId: string): Promise<MulingstreamChunkData[]>;
|
|
61
67
|
getByChunkNumber(chunkNumber: number, roomId: string): Promise<MulingstreamChunkData | null>;
|
|
62
|
-
|
|
63
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Updates the STT status for a given service in the chunk's STT data.
|
|
70
|
+
*
|
|
71
|
+
* @param mulingstreamChunkId The chunk ID.
|
|
72
|
+
* @param status The new SttStatus to set (INIT, DISCARDED, READY, USED).
|
|
73
|
+
* @param service Which STT service to update (must be among the chunk's services).
|
|
74
|
+
* @param chunkStatus Overall chunk status (e.g. IN_PROGRESS, DISCARDED, USED).
|
|
75
|
+
* @param chunkStep Overall chunk step (e.g. STT, TRANSLATION, etc.).
|
|
76
|
+
*/
|
|
77
|
+
updateSttStatus(mulingstreamChunkId: string, status: SttStatus, service: SttProvider, chunkStatus: MulingstreamChunkStatus, chunkStep: MulingstreamChunkStep): Promise<boolean>;
|
|
78
|
+
/**
|
|
79
|
+
* Updates the transcription + status for a given service in the chunk's STT data.
|
|
80
|
+
*
|
|
81
|
+
* @param mulingstreamChunkId The chunk ID.
|
|
82
|
+
* @param transcription The transcription text to store.
|
|
83
|
+
* @param sttStatus The new status for this STT service.
|
|
84
|
+
* @param service Which STT service to update.
|
|
85
|
+
* @param chunkStatus Overall chunk status (e.g. IN_PROGRESS, DISCARDED, USED).
|
|
86
|
+
* @param chunkStep Overall chunk step (e.g. STT, TRANSLATION, etc.).
|
|
87
|
+
*/
|
|
88
|
+
updateTranscription(mulingstreamChunkId: string, transcription: string, sttStatus: SttStatus, service: SttProvider, chunkStatus: MulingstreamChunkStatus, chunkStep: MulingstreamChunkStep): Promise<boolean>;
|
|
64
89
|
}
|
|
@@ -8,20 +8,27 @@ class MulingstreamChunkManager {
|
|
|
8
8
|
this.redisClient = redisClient;
|
|
9
9
|
}
|
|
10
10
|
parseHashData(data) {
|
|
11
|
-
// Parse nested JSON fields
|
|
11
|
+
// Parse the arrays and nested JSON fields
|
|
12
|
+
const sttProviders = JSON.parse(data.sttProviders);
|
|
13
|
+
const targetLanguages = JSON.parse(data.targetLanguages);
|
|
12
14
|
const audioChunk = JSON.parse(data.audioChunk);
|
|
13
15
|
const stt = JSON.parse(data.stt);
|
|
14
|
-
const
|
|
16
|
+
const translation = JSON.parse(data.translation);
|
|
17
|
+
const tts = JSON.parse(data.tts);
|
|
15
18
|
return {
|
|
16
19
|
mulingstreamChunkId: data.mulingstreamChunkId,
|
|
17
20
|
roomId: data.roomId,
|
|
18
21
|
chunkNumber: parseInt(data.chunkNumber, 10),
|
|
19
22
|
language: data.language,
|
|
23
|
+
sttProviders,
|
|
24
|
+
targetLanguages,
|
|
25
|
+
finalTranscription: data.finalTranscription,
|
|
20
26
|
mulingstreamChunkStatus: data.mulingstreamChunkStatus,
|
|
21
27
|
mulingstreamChunkStep: data.mulingstreamChunkStep,
|
|
22
28
|
audioChunk,
|
|
23
29
|
stt,
|
|
24
|
-
|
|
30
|
+
translation,
|
|
31
|
+
tts
|
|
25
32
|
};
|
|
26
33
|
}
|
|
27
34
|
// Adds a new mulingstream chunk.
|
|
@@ -29,7 +36,7 @@ class MulingstreamChunkManager {
|
|
|
29
36
|
// - Stores the chunk data in a Redis hash under `mulingstreamChunk:{mulingstreamChunkId}`.
|
|
30
37
|
// - Applies an expiration (12h).
|
|
31
38
|
async addMulingstreamChunk(params) {
|
|
32
|
-
const { roomId, chunkNumber, language, start, end, duration, isFirst, isLast, theme,
|
|
39
|
+
const { roomId, chunkNumber, language, start, end, duration, isFirst, isLast, theme, sttProviders, targetLanguages } = params;
|
|
33
40
|
const mulingstreamChunkId = `[${roomId}]-[${chunkNumber}]-[${(0, uuid_1.v4)()}]`;
|
|
34
41
|
// Prepare the nested objects
|
|
35
42
|
const audioChunk = {
|
|
@@ -41,36 +48,46 @@ class MulingstreamChunkManager {
|
|
|
41
48
|
theme,
|
|
42
49
|
processingStart: Date.now()
|
|
43
50
|
};
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
// Build the STT object
|
|
52
|
+
// For each service in `services`, create { transcription: '', status: 'INIT' }
|
|
53
|
+
const stt = {};
|
|
54
|
+
for (const service of sttProviders) {
|
|
55
|
+
stt[service] = {
|
|
56
|
+
transcription: '',
|
|
57
|
+
status: 'INIT'
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// Build translation & tts objects keyed by each target language
|
|
61
|
+
const translation = {};
|
|
62
|
+
const tts = {};
|
|
63
|
+
for (const lang of targetLanguages) {
|
|
64
|
+
translation[lang] = {
|
|
56
65
|
translation: '',
|
|
57
|
-
|
|
66
|
+
status: 'INIT'
|
|
67
|
+
};
|
|
68
|
+
tts[lang] = {
|
|
58
69
|
ttsAudioPath: '',
|
|
59
|
-
|
|
70
|
+
status: 'INIT',
|
|
60
71
|
isEmitted: false
|
|
61
72
|
};
|
|
62
73
|
}
|
|
74
|
+
// Root-level finalTranscription is empty initially
|
|
75
|
+
const finalTranscription = '';
|
|
63
76
|
// Store the data in a Redis hash
|
|
64
77
|
await this.redisClient.hset(`mulingstreamChunk:${mulingstreamChunkId}`, {
|
|
65
78
|
mulingstreamChunkId,
|
|
66
79
|
roomId,
|
|
67
80
|
chunkNumber: chunkNumber.toString(),
|
|
68
81
|
language,
|
|
82
|
+
sttProviders: JSON.stringify(sttProviders),
|
|
83
|
+
targetLanguages: JSON.stringify(targetLanguages),
|
|
84
|
+
finalTranscription,
|
|
69
85
|
mulingstreamChunkStatus: 'INIT',
|
|
70
86
|
mulingstreamChunkStep: 'RECEIVED',
|
|
71
87
|
audioChunk: JSON.stringify(audioChunk),
|
|
72
88
|
stt: JSON.stringify(stt),
|
|
73
|
-
|
|
89
|
+
translation: JSON.stringify(translation),
|
|
90
|
+
tts: JSON.stringify(tts)
|
|
74
91
|
});
|
|
75
92
|
// set expiration
|
|
76
93
|
await this.redisClient.expire(`mulingstreamChunk:${mulingstreamChunkId}`, EXPIRATION);
|
|
@@ -131,17 +148,25 @@ class MulingstreamChunkManager {
|
|
|
131
148
|
}
|
|
132
149
|
return this.parseHashData(data);
|
|
133
150
|
}
|
|
134
|
-
|
|
135
|
-
|
|
151
|
+
/**
|
|
152
|
+
* Updates the STT status for a given service in the chunk's STT data.
|
|
153
|
+
*
|
|
154
|
+
* @param mulingstreamChunkId The chunk ID.
|
|
155
|
+
* @param status The new SttStatus to set (INIT, DISCARDED, READY, USED).
|
|
156
|
+
* @param service Which STT service to update (must be among the chunk's services).
|
|
157
|
+
* @param chunkStatus Overall chunk status (e.g. IN_PROGRESS, DISCARDED, USED).
|
|
158
|
+
* @param chunkStep Overall chunk step (e.g. STT, TRANSLATION, etc.).
|
|
159
|
+
*/
|
|
160
|
+
async updateSttStatus(mulingstreamChunkId, status, service, chunkStatus, chunkStep) {
|
|
136
161
|
const data = await this.redisClient.hgetall(`mulingstreamChunk:${mulingstreamChunkId}`);
|
|
137
162
|
if (!data || !data.mulingstreamChunkId) {
|
|
138
|
-
return false;
|
|
163
|
+
return false;
|
|
139
164
|
}
|
|
140
|
-
// Parse the existing stt field
|
|
141
165
|
const stt = JSON.parse(data.stt);
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
166
|
+
if (!stt[service]) {
|
|
167
|
+
return false; // service not in stt object
|
|
168
|
+
}
|
|
169
|
+
stt[service].status = status;
|
|
145
170
|
await this.redisClient.hset(`mulingstreamChunk:${mulingstreamChunkId}`, {
|
|
146
171
|
mulingstreamChunkStatus: chunkStatus,
|
|
147
172
|
mulingstreamChunkStep: chunkStep,
|
|
@@ -149,18 +174,27 @@ class MulingstreamChunkManager {
|
|
|
149
174
|
});
|
|
150
175
|
return true;
|
|
151
176
|
}
|
|
152
|
-
|
|
153
|
-
|
|
177
|
+
/**
|
|
178
|
+
* Updates the transcription + status for a given service in the chunk's STT data.
|
|
179
|
+
*
|
|
180
|
+
* @param mulingstreamChunkId The chunk ID.
|
|
181
|
+
* @param transcription The transcription text to store.
|
|
182
|
+
* @param sttStatus The new status for this STT service.
|
|
183
|
+
* @param service Which STT service to update.
|
|
184
|
+
* @param chunkStatus Overall chunk status (e.g. IN_PROGRESS, DISCARDED, USED).
|
|
185
|
+
* @param chunkStep Overall chunk step (e.g. STT, TRANSLATION, etc.).
|
|
186
|
+
*/
|
|
187
|
+
async updateTranscription(mulingstreamChunkId, transcription, sttStatus, service, chunkStatus, chunkStep) {
|
|
154
188
|
const data = await this.redisClient.hgetall(`mulingstreamChunk:${mulingstreamChunkId}`);
|
|
155
189
|
if (!data || !data.mulingstreamChunkId) {
|
|
156
|
-
return false;
|
|
190
|
+
return false;
|
|
157
191
|
}
|
|
158
|
-
// Parse the existing stt field
|
|
159
192
|
const stt = JSON.parse(data.stt);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
193
|
+
if (!stt[service]) {
|
|
194
|
+
return false; // service not in stt object
|
|
195
|
+
}
|
|
196
|
+
stt[service].transcription = transcription;
|
|
197
|
+
stt[service].status = sttStatus;
|
|
164
198
|
await this.redisClient.hset(`mulingstreamChunk:${mulingstreamChunkId}`, {
|
|
165
199
|
mulingstreamChunkStatus: chunkStatus,
|
|
166
200
|
mulingstreamChunkStep: chunkStep,
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { RedisClient } from '../redis-client';
|
|
2
|
-
export type SttStatus = 'INIT' | 'DISCARDED' | 'READY' | 'USED';
|
|
3
|
-
export type TranslationStatus = 'INIT' | 'DISCARDED' | 'READY' | 'USED';
|
|
4
|
-
export type TtsStatus = 'INIT' | 'DISCARDED' | 'READY' | 'USED';
|
|
5
|
-
export type MulingstreamChunkStatus = 'INIT' | 'DISCARDED' | 'USED';
|
|
6
|
-
export type MulingstreamChunkData = {
|
|
7
|
-
mulingstreamChunkId: string;
|
|
8
|
-
roomId: string;
|
|
9
|
-
chunkNumber: number;
|
|
10
|
-
language: string;
|
|
11
|
-
mulingstreamChunkStatus: MulingstreamChunkStatus;
|
|
12
|
-
audioChunk: {
|
|
13
|
-
start: number;
|
|
14
|
-
end: number;
|
|
15
|
-
duration: number;
|
|
16
|
-
isFirst: boolean;
|
|
17
|
-
isLast: boolean;
|
|
18
|
-
theme: string;
|
|
19
|
-
processingStart: number;
|
|
20
|
-
};
|
|
21
|
-
stt: {
|
|
22
|
-
services: string[];
|
|
23
|
-
azureTranscription?: string;
|
|
24
|
-
whisperTranscription?: string;
|
|
25
|
-
googleTranscription?: string;
|
|
26
|
-
finalTranscription: string;
|
|
27
|
-
status: SttStatus;
|
|
28
|
-
};
|
|
29
|
-
postStt: {
|
|
30
|
-
[language: string]: {
|
|
31
|
-
translation: string;
|
|
32
|
-
translationStatus: TranslationStatus;
|
|
33
|
-
ttsAudioPath: string;
|
|
34
|
-
ttsStatus: TtsStatus;
|
|
35
|
-
isEmitted: boolean;
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
export declare class MulingstreamChunkManager {
|
|
40
|
-
private redisClient;
|
|
41
|
-
constructor(redisClient: RedisClient);
|
|
42
|
-
private parseHashData;
|
|
43
|
-
addMulingstreamChunk(params: {
|
|
44
|
-
roomId: string;
|
|
45
|
-
chunkNumber: number;
|
|
46
|
-
language: string;
|
|
47
|
-
start: number;
|
|
48
|
-
end: number;
|
|
49
|
-
duration: number;
|
|
50
|
-
isFirst: boolean;
|
|
51
|
-
isLast: boolean;
|
|
52
|
-
theme: string;
|
|
53
|
-
services: string[];
|
|
54
|
-
postSttLanguages: string[];
|
|
55
|
-
}): Promise<string>;
|
|
56
|
-
getMulingstreamChunks(): Promise<MulingstreamChunkData[]>;
|
|
57
|
-
getMulingstreamChunk(mulingstreamChunkId: string): Promise<MulingstreamChunkData | null>;
|
|
58
|
-
getMulingstreamChunksByRoom(roomId: string): Promise<MulingstreamChunkData[]>;
|
|
59
|
-
getByChunkNumber(chunkNumber: number, roomId: string): Promise<MulingstreamChunkData | null>;
|
|
60
|
-
}
|
|
@@ -1,133 +1,174 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
1
|
+
// import { v4 as uuidv4 } from 'uuid';
|
|
2
|
+
// import { RedisClient } from '../redis-client';
|
|
3
|
+
// export type SttStatus = 'INIT' | 'DISCARDED' | 'READY' | 'USED';
|
|
4
|
+
// export type TranslationStatus = 'INIT' | 'DISCARDED' | 'READY' | 'USED';
|
|
5
|
+
// export type TtsStatus = 'INIT' | 'DISCARDED' | 'READY' | 'USED';
|
|
6
|
+
// export type MulingstreamChunkStatus = 'INIT' | 'DISCARDED' | 'USED';
|
|
7
|
+
// export type MulingstreamRoomData = {
|
|
8
|
+
// mulingstreamRoomTrackerId: string;
|
|
9
|
+
// roomId: string;
|
|
10
|
+
// lastReadyChunk: number;
|
|
11
|
+
// lastUsedChunk: number;
|
|
12
|
+
// lastDiscardedChunk: number;
|
|
13
|
+
// stt: {
|
|
14
|
+
// lastReadyStt: number;
|
|
15
|
+
// lastUsedStt: number;
|
|
16
|
+
// lastDiscardedStt: number;
|
|
17
|
+
// };
|
|
18
|
+
// translation: {
|
|
19
|
+
// [language: string]: {
|
|
20
|
+
// lastReadyTranslation: number;
|
|
21
|
+
// lastUsedTranslation: number;
|
|
22
|
+
// lastDiscardedTranslation: number;
|
|
23
|
+
// };
|
|
24
|
+
// };
|
|
25
|
+
// tts: {
|
|
26
|
+
// [language: string]: {
|
|
27
|
+
// lastReadyTts: number;
|
|
28
|
+
// lastUsedTts: number;
|
|
29
|
+
// lastDiscardedTts: number;
|
|
30
|
+
// lastEmittedTts: number;
|
|
31
|
+
// };
|
|
32
|
+
// };
|
|
33
|
+
// };
|
|
34
|
+
// const EXPIRATION = 4 * 60 * 60; // 4 hours in seconds
|
|
35
|
+
// export class MulingstreamChunkManager {
|
|
36
|
+
// private redisClient: RedisClient;
|
|
37
|
+
// constructor(redisClient: RedisClient) {
|
|
38
|
+
// this.redisClient = redisClient;
|
|
39
|
+
// }
|
|
40
|
+
// private parseHashData(data: Record<string, string>): MulingstreamChunkData {
|
|
41
|
+
// // Parse nested JSON fields
|
|
42
|
+
// const audioChunk = JSON.parse(data.audioChunk);
|
|
43
|
+
// const stt = JSON.parse(data.stt);
|
|
44
|
+
// const postStt = JSON.parse(data.postStt);
|
|
45
|
+
// return {
|
|
46
|
+
// mulingstreamChunkId: data.mulingstreamChunkId,
|
|
47
|
+
// roomId: data.roomId,
|
|
48
|
+
// chunkNumber: parseInt(data.chunkNumber, 10),
|
|
49
|
+
// language: data.language,
|
|
50
|
+
// mulingstreamChunkStatus: data.mulingstreamChunkStatus as MulingstreamChunkStatus,
|
|
51
|
+
// audioChunk,
|
|
52
|
+
// stt,
|
|
53
|
+
// postStt
|
|
54
|
+
// };
|
|
55
|
+
// }
|
|
56
|
+
// // Adds a new mulingstream chunk.
|
|
57
|
+
// // - Creates a unique mulingstreamChunkId.
|
|
58
|
+
// // - Stores the chunk data in a Redis hash under `mulingstreamChunk:{mulingstreamChunkId}`.
|
|
59
|
+
// // - Applies an expiration (4h).
|
|
60
|
+
// public async addMulingstreamChunk(params: {
|
|
61
|
+
// roomId: string;
|
|
62
|
+
// chunkNumber: number;
|
|
63
|
+
// language: string;
|
|
64
|
+
// start: number;
|
|
65
|
+
// end: number;
|
|
66
|
+
// duration: number;
|
|
67
|
+
// isFirst: boolean;
|
|
68
|
+
// isLast: boolean;
|
|
69
|
+
// theme: string;
|
|
70
|
+
// services: string[];
|
|
71
|
+
// postSttLanguages: string[]; // e.g. ['en-US', 'es-ES', 'de-DE']
|
|
72
|
+
// }): Promise<string> {
|
|
73
|
+
// const { roomId, chunkNumber, language, start, end, duration, isFirst, isLast, theme, services, postSttLanguages } = params;
|
|
74
|
+
// const mulingstreamChunkId = `[${roomId}]-[${chunkNumber}]-[${uuidv4()}]`;
|
|
75
|
+
// // Prepare the nested objects
|
|
76
|
+
// const audioChunk = {
|
|
77
|
+
// start,
|
|
78
|
+
// end,
|
|
79
|
+
// duration,
|
|
80
|
+
// isFirst,
|
|
81
|
+
// isLast,
|
|
82
|
+
// theme,
|
|
83
|
+
// processingStart: Date.now()
|
|
84
|
+
// };
|
|
85
|
+
// const stt = {
|
|
86
|
+
// services,
|
|
87
|
+
// azureTranscription: '',
|
|
88
|
+
// whisperTranscription: '',
|
|
89
|
+
// googleTranscription: '',
|
|
90
|
+
// finalTranscription: '',
|
|
91
|
+
// status: 'INIT' as SttStatus
|
|
92
|
+
// };
|
|
93
|
+
// // Build postStt object keyed by each language
|
|
94
|
+
// const postStt: MulingstreamChunkData['postStt'] = {};
|
|
95
|
+
// for (const lang of postSttLanguages) {
|
|
96
|
+
// postStt[lang] = {
|
|
97
|
+
// translation: '',
|
|
98
|
+
// translationStatus: 'INIT',
|
|
99
|
+
// ttsAudioPath: '',
|
|
100
|
+
// ttsStatus: 'INIT',
|
|
101
|
+
// isEmitted: false
|
|
102
|
+
// };
|
|
103
|
+
// }
|
|
104
|
+
// // Store the data in a Redis hash
|
|
105
|
+
// await this.redisClient.hset(`mulingstreamChunk:${mulingstreamChunkId}`, {
|
|
106
|
+
// mulingstreamChunkId,
|
|
107
|
+
// roomId,
|
|
108
|
+
// chunkNumber: chunkNumber.toString(),
|
|
109
|
+
// language,
|
|
110
|
+
// mulingstreamChunkStatus: 'INIT',
|
|
111
|
+
// audioChunk: JSON.stringify(audioChunk),
|
|
112
|
+
// stt: JSON.stringify(stt),
|
|
113
|
+
// postStt: JSON.stringify(postStt)
|
|
114
|
+
// });
|
|
115
|
+
// // set expiration
|
|
116
|
+
// await this.redisClient.expire(`mulingstreamChunk:${mulingstreamChunkId}`, EXPIRATION);
|
|
117
|
+
// return mulingstreamChunkId;
|
|
118
|
+
// }
|
|
119
|
+
// // Retrieves all mulingstream chunks by scanning keys `mulingstreamChunk:*`.
|
|
120
|
+
// public async getMulingstreamChunks(): Promise<MulingstreamChunkData[]> {
|
|
121
|
+
// const keys = await this.redisClient.keys('mulingstreamChunk:*');
|
|
122
|
+
// if (!keys || keys.length === 0) {
|
|
123
|
+
// return [];
|
|
124
|
+
// }
|
|
125
|
+
// const results: MulingstreamChunkData[] = [];
|
|
126
|
+
// for (const key of keys) {
|
|
127
|
+
// const data = await this.redisClient.hgetall(key);
|
|
128
|
+
// if (data && data.mulingstreamChunkId) {
|
|
129
|
+
// results.push(this.parseHashData(data));
|
|
130
|
+
// }
|
|
131
|
+
// }
|
|
132
|
+
// return results;
|
|
133
|
+
// }
|
|
134
|
+
// // Retrieves a single mulingstream chunk by ID.
|
|
135
|
+
// public async getMulingstreamChunk(mulingstreamChunkId: string): Promise<MulingstreamChunkData | null> {
|
|
136
|
+
// const data = await this.redisClient.hgetall(`mulingstreamChunk:${mulingstreamChunkId}`);
|
|
137
|
+
// if (!data || !data.mulingstreamChunkId) {
|
|
138
|
+
// return null;
|
|
139
|
+
// }
|
|
140
|
+
// return this.parseHashData(data);
|
|
141
|
+
// }
|
|
142
|
+
// // Retrieves all mulingstream chunks for a specific room by pattern matching keys `mulingstreamChunk:[roomId]-*`.
|
|
143
|
+
// public async getMulingstreamChunksByRoom(roomId: string): Promise<MulingstreamChunkData[]> {
|
|
144
|
+
// const pattern = `mulingstreamChunk:[${roomId}]-*`;
|
|
145
|
+
// const keys = await this.redisClient.keys(pattern);
|
|
146
|
+
// if (!keys || keys.length === 0) {
|
|
147
|
+
// return [];
|
|
148
|
+
// }
|
|
149
|
+
// const results: MulingstreamChunkData[] = [];
|
|
150
|
+
// for (const key of keys) {
|
|
151
|
+
// const data = await this.redisClient.hgetall(key);
|
|
152
|
+
// if (!data || !data.mulingstreamChunkId) {
|
|
153
|
+
// continue;
|
|
154
|
+
// }
|
|
155
|
+
// results.push(this.parseHashData(data));
|
|
156
|
+
// }
|
|
157
|
+
// return results;
|
|
158
|
+
// }
|
|
159
|
+
// // Retrieves a mulingstream chunk by (roomId, chunkNumber).
|
|
160
|
+
// // Since mulingstreamChunkId = `[${roomId}]-[${chunkNumber}]-[uuid]`, we can pattern-match on keys.
|
|
161
|
+
// public async getByChunkNumber(chunkNumber: number, roomId: string): Promise<MulingstreamChunkData | null> {
|
|
162
|
+
// const pattern = `mulingstreamChunk:[${roomId}]-[${chunkNumber}]-*`;
|
|
163
|
+
// const keys = await this.redisClient.keys(pattern);
|
|
164
|
+
// if (!keys || keys.length === 0) {
|
|
165
|
+
// return null;
|
|
166
|
+
// }
|
|
167
|
+
// // If multiple match, return the first
|
|
168
|
+
// const data = await this.redisClient.hgetall(keys[0]);
|
|
169
|
+
// if (!data || !data.mulingstreamChunkId) {
|
|
170
|
+
// return null;
|
|
171
|
+
// }
|
|
172
|
+
// return this.parseHashData(data);
|
|
173
|
+
// }
|
|
174
|
+
// }
|