@aituber-onair/core 0.1.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.
- package/README.md +723 -0
- package/dist/constants/api.d.ts +4 -0
- package/dist/constants/api.js +13 -0
- package/dist/constants/api.js.map +1 -0
- package/dist/constants/index.d.ts +23 -0
- package/dist/constants/index.js +25 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/constants/openaiApi.d.ts +15 -0
- package/dist/constants/openaiApi.js +15 -0
- package/dist/constants/openaiApi.js.map +1 -0
- package/dist/constants/prompts.d.ts +2 -0
- package/dist/constants/prompts.js +13 -0
- package/dist/constants/prompts.js.map +1 -0
- package/dist/core/AITuberOnAirCore.d.ts +142 -0
- package/dist/core/AITuberOnAirCore.js +316 -0
- package/dist/core/AITuberOnAirCore.js.map +1 -0
- package/dist/core/ChatProcessor.d.ts +86 -0
- package/dist/core/ChatProcessor.js +246 -0
- package/dist/core/ChatProcessor.js.map +1 -0
- package/dist/core/EventEmitter.d.ts +35 -0
- package/dist/core/EventEmitter.js +72 -0
- package/dist/core/EventEmitter.js.map +1 -0
- package/dist/core/MemoryManager.d.ts +98 -0
- package/dist/core/MemoryManager.js +208 -0
- package/dist/core/MemoryManager.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/services/chat/ChatService.d.ts +21 -0
- package/dist/services/chat/ChatService.js +2 -0
- package/dist/services/chat/ChatService.js.map +1 -0
- package/dist/services/chat/ChatServiceFactory.d.ts +38 -0
- package/dist/services/chat/ChatServiceFactory.js +55 -0
- package/dist/services/chat/ChatServiceFactory.js.map +1 -0
- package/dist/services/chat/OpenAIChatService.d.ts +38 -0
- package/dist/services/chat/OpenAIChatService.js +166 -0
- package/dist/services/chat/OpenAIChatService.js.map +1 -0
- package/dist/services/chat/OpenAISummarizer.d.ts +25 -0
- package/dist/services/chat/OpenAISummarizer.js +70 -0
- package/dist/services/chat/OpenAISummarizer.js.map +1 -0
- package/dist/services/chat/providers/ChatServiceProvider.d.ts +44 -0
- package/dist/services/chat/providers/ChatServiceProvider.js +2 -0
- package/dist/services/chat/providers/ChatServiceProvider.js.map +1 -0
- package/dist/services/chat/providers/OpenAIChatServiceProvider.d.ts +33 -0
- package/dist/services/chat/providers/OpenAIChatServiceProvider.js +44 -0
- package/dist/services/chat/providers/OpenAIChatServiceProvider.js.map +1 -0
- package/dist/services/voice/VoiceEngineAdapter.d.ts +46 -0
- package/dist/services/voice/VoiceEngineAdapter.js +173 -0
- package/dist/services/voice/VoiceEngineAdapter.js.map +1 -0
- package/dist/services/voice/VoiceService.d.ts +55 -0
- package/dist/services/voice/VoiceService.js +2 -0
- package/dist/services/voice/VoiceService.js.map +1 -0
- package/dist/services/voice/engines/AivisSpeechEngine.d.ts +10 -0
- package/dist/services/voice/engines/AivisSpeechEngine.js +70 -0
- package/dist/services/voice/engines/AivisSpeechEngine.js.map +1 -0
- package/dist/services/voice/engines/NijiVoiceEngine.d.ts +12 -0
- package/dist/services/voice/engines/NijiVoiceEngine.js +105 -0
- package/dist/services/voice/engines/NijiVoiceEngine.js.map +1 -0
- package/dist/services/voice/engines/OpenAiEngine.d.ts +9 -0
- package/dist/services/voice/engines/OpenAiEngine.js +34 -0
- package/dist/services/voice/engines/OpenAiEngine.js.map +1 -0
- package/dist/services/voice/engines/VoiceEngine.d.ts +21 -0
- package/dist/services/voice/engines/VoiceEngine.js +2 -0
- package/dist/services/voice/engines/VoiceEngine.js.map +1 -0
- package/dist/services/voice/engines/VoiceEngineFactory.d.ts +14 -0
- package/dist/services/voice/engines/VoiceEngineFactory.js +34 -0
- package/dist/services/voice/engines/VoiceEngineFactory.js.map +1 -0
- package/dist/services/voice/engines/VoicePeakEngine.d.ts +13 -0
- package/dist/services/voice/engines/VoicePeakEngine.js +46 -0
- package/dist/services/voice/engines/VoicePeakEngine.js.map +1 -0
- package/dist/services/voice/engines/VoiceVoxEngine.d.ts +13 -0
- package/dist/services/voice/engines/VoiceVoxEngine.js +67 -0
- package/dist/services/voice/engines/VoiceVoxEngine.js.map +1 -0
- package/dist/services/voice/engines/index.d.ts +7 -0
- package/dist/services/voice/engines/index.js +7 -0
- package/dist/services/voice/engines/index.js.map +1 -0
- package/dist/services/voice/messages.d.ts +38 -0
- package/dist/services/voice/messages.js +49 -0
- package/dist/services/voice/messages.js.map +1 -0
- package/dist/services/youtube/YouTubeDataApiService.d.ts +69 -0
- package/dist/services/youtube/YouTubeDataApiService.js +255 -0
- package/dist/services/youtube/YouTubeDataApiService.js.map +1 -0
- package/dist/services/youtube/YouTubeService.d.ts +63 -0
- package/dist/services/youtube/YouTubeService.js +2 -0
- package/dist/services/youtube/YouTubeService.js.map +1 -0
- package/dist/types/index.d.ts +82 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/nijiVoice.d.ts +27 -0
- package/dist/types/nijiVoice.js +2 -0
- package/dist/types/nijiVoice.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/screenplay.d.ts +19 -0
- package/dist/utils/screenplay.js +42 -0
- package/dist/utils/screenplay.js.map +1 -0
- package/dist/utils/screenshot.d.ts +19 -0
- package/dist/utils/screenshot.js +44 -0
- package/dist/utils/screenshot.js.map +1 -0
- package/dist/utils/storage.d.ts +44 -0
- package/dist/utils/storage.js +103 -0
- package/dist/utils/storage.js.map +1 -0
- package/package.json +33 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { ENDPOINT_YOUTUBE_API } from '../../constants';
|
|
2
|
+
import { EventEmitter } from '../../core/EventEmitter';
|
|
3
|
+
/**
|
|
4
|
+
* YouTube Data API implementation using YouTube service
|
|
5
|
+
*/
|
|
6
|
+
export class YouTubeDataApiService extends EventEmitter {
|
|
7
|
+
/**
|
|
8
|
+
* Constructor
|
|
9
|
+
* @param options Service settings options
|
|
10
|
+
*/
|
|
11
|
+
constructor(options) {
|
|
12
|
+
super();
|
|
13
|
+
this.isWatchingLive = false;
|
|
14
|
+
this.watchingIntervalId = null;
|
|
15
|
+
this.nextPageToken = '';
|
|
16
|
+
this.currentLiveId = '';
|
|
17
|
+
this.options = {
|
|
18
|
+
apiKey: options.apiKey,
|
|
19
|
+
fetchInterval: options.fetchInterval || 20000, // デフォルト20秒
|
|
20
|
+
selectionStrategy: options.selectionStrategy || 'random',
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Start watching live comments
|
|
25
|
+
* @param liveId Live ID
|
|
26
|
+
*/
|
|
27
|
+
async startWatching(liveId) {
|
|
28
|
+
if (this.isWatchingLive) {
|
|
29
|
+
this.stopWatching();
|
|
30
|
+
}
|
|
31
|
+
this.isWatchingLive = true;
|
|
32
|
+
this.nextPageToken = '';
|
|
33
|
+
this.currentLiveId = liveId;
|
|
34
|
+
try {
|
|
35
|
+
// Get live chat ID
|
|
36
|
+
const liveChatId = await this.getLiveChatId(liveId);
|
|
37
|
+
if (!liveChatId) {
|
|
38
|
+
console.error('Could not get live chat ID');
|
|
39
|
+
this.isWatchingLive = false;
|
|
40
|
+
this.emit('error', new Error('Could not get live chat ID'));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// Get comments periodically
|
|
44
|
+
this.watchingIntervalId = window.setInterval(async () => {
|
|
45
|
+
try {
|
|
46
|
+
await this.fetchAndProcessComments(liveChatId);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
console.error('Error fetching comments:', error);
|
|
50
|
+
this.emit('error', error);
|
|
51
|
+
}
|
|
52
|
+
}, this.options.fetchInterval);
|
|
53
|
+
this.emit('watchingStarted', liveId);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.error('Error starting live monitoring:', error);
|
|
57
|
+
this.isWatchingLive = false;
|
|
58
|
+
this.emit('error', error);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Stop watching live comments
|
|
63
|
+
*/
|
|
64
|
+
stopWatching() {
|
|
65
|
+
if (this.watchingIntervalId) {
|
|
66
|
+
window.clearInterval(this.watchingIntervalId);
|
|
67
|
+
this.watchingIntervalId = null;
|
|
68
|
+
}
|
|
69
|
+
this.isWatchingLive = false;
|
|
70
|
+
this.nextPageToken = '';
|
|
71
|
+
this.currentLiveId = '';
|
|
72
|
+
this.emit('watchingStopped');
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Return whether currently fetching
|
|
76
|
+
*/
|
|
77
|
+
isWatching() {
|
|
78
|
+
return this.isWatchingLive;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Set comment fetch interval
|
|
82
|
+
* @param interval Interval in milliseconds
|
|
83
|
+
*/
|
|
84
|
+
setFetchInterval(interval) {
|
|
85
|
+
this.options.fetchInterval = interval;
|
|
86
|
+
// If currently watching, update interval
|
|
87
|
+
if (this.isWatchingLive && this.watchingIntervalId && this.currentLiveId) {
|
|
88
|
+
window.clearInterval(this.watchingIntervalId);
|
|
89
|
+
this.watchingIntervalId = window.setInterval(async () => {
|
|
90
|
+
try {
|
|
91
|
+
const liveChatId = await this.getLiveChatId(this.currentLiveId);
|
|
92
|
+
if (liveChatId) {
|
|
93
|
+
await this.fetchAndProcessComments(liveChatId);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
console.error('Error fetching comments:', error);
|
|
98
|
+
this.emit('error', error);
|
|
99
|
+
}
|
|
100
|
+
}, interval);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Set comment selection strategy
|
|
105
|
+
* @param strategy Selection strategy ('random' or 'latest')
|
|
106
|
+
*/
|
|
107
|
+
setSelectionStrategy(strategy) {
|
|
108
|
+
this.options.selectionStrategy = strategy;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Fetch latest comments (for manual retrieval)
|
|
112
|
+
* @param liveId Live ID
|
|
113
|
+
* @returns Comments array
|
|
114
|
+
*/
|
|
115
|
+
async fetchLatestComments(liveId) {
|
|
116
|
+
try {
|
|
117
|
+
const liveChatId = await this.getLiveChatId(liveId);
|
|
118
|
+
if (!liveChatId) {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
return await this.retrieveLiveComments(liveChatId, false);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
console.error('Error fetching comments:', error);
|
|
125
|
+
this.emit('error', error);
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Subscribe to comment reception event
|
|
131
|
+
* @param callback Callback when comment is received
|
|
132
|
+
*/
|
|
133
|
+
onComment(callback) {
|
|
134
|
+
this.on('comment', callback);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get live chat ID
|
|
138
|
+
* @param liveId Live ID
|
|
139
|
+
* @returns Live chat ID
|
|
140
|
+
*/
|
|
141
|
+
async getLiveChatId(liveId) {
|
|
142
|
+
try {
|
|
143
|
+
const params = {
|
|
144
|
+
part: 'liveStreamingDetails',
|
|
145
|
+
id: liveId,
|
|
146
|
+
key: this.options.apiKey,
|
|
147
|
+
};
|
|
148
|
+
const query = new URLSearchParams(params);
|
|
149
|
+
const response = await fetch(`${ENDPOINT_YOUTUBE_API}/videos?${query}`, {
|
|
150
|
+
method: 'get',
|
|
151
|
+
headers: {
|
|
152
|
+
'Content-Type': 'application/json',
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
const json = await response.json();
|
|
156
|
+
if (!json.items || json.items.length === 0) {
|
|
157
|
+
console.warn('Live broadcast information not found:', json);
|
|
158
|
+
return '';
|
|
159
|
+
}
|
|
160
|
+
const liveStreamingDetails = json.items[0].liveStreamingDetails;
|
|
161
|
+
if (!liveStreamingDetails || !liveStreamingDetails.activeLiveChatId) {
|
|
162
|
+
console.warn('Live chat ID not found:', json.items[0]);
|
|
163
|
+
return '';
|
|
164
|
+
}
|
|
165
|
+
return liveStreamingDetails.activeLiveChatId;
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
console.error('Error fetching live chat ID:', error);
|
|
169
|
+
this.emit('error', error);
|
|
170
|
+
return '';
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Fetch live comments
|
|
175
|
+
* @param liveChatId Live chat ID
|
|
176
|
+
* @param usePageToken Whether to use page token
|
|
177
|
+
* @returns Comments array
|
|
178
|
+
*/
|
|
179
|
+
async retrieveLiveComments(liveChatId, usePageToken = true) {
|
|
180
|
+
try {
|
|
181
|
+
let url = `${ENDPOINT_YOUTUBE_API}/liveChat/messages?liveChatId=` +
|
|
182
|
+
liveChatId +
|
|
183
|
+
'&part=authorDetails%2Csnippet&key=' +
|
|
184
|
+
this.options.apiKey;
|
|
185
|
+
if (usePageToken && this.nextPageToken) {
|
|
186
|
+
url += '&pageToken=' + this.nextPageToken;
|
|
187
|
+
}
|
|
188
|
+
const response = await fetch(url, {
|
|
189
|
+
method: 'get',
|
|
190
|
+
headers: {
|
|
191
|
+
'Content-Type': 'application/json',
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
const json = await response.json();
|
|
195
|
+
if (json.error) {
|
|
196
|
+
console.error('YouTube API error:', json.error);
|
|
197
|
+
this.emit('error', new Error(json.error.message || 'YouTube API error'));
|
|
198
|
+
return [];
|
|
199
|
+
}
|
|
200
|
+
// Save next page token
|
|
201
|
+
if (json.nextPageToken) {
|
|
202
|
+
this.nextPageToken = json.nextPageToken;
|
|
203
|
+
}
|
|
204
|
+
if (!json.items || json.items.length === 0) {
|
|
205
|
+
return [];
|
|
206
|
+
}
|
|
207
|
+
// Extract comment information
|
|
208
|
+
const comments = json.items
|
|
209
|
+
.map((item) => ({
|
|
210
|
+
userName: item.authorDetails.displayName,
|
|
211
|
+
userIconUrl: item.authorDetails.profileImageUrl,
|
|
212
|
+
userComment: item.snippet.textMessageDetails?.messageText ||
|
|
213
|
+
item.snippet.superChatDetails?.userComment ||
|
|
214
|
+
'',
|
|
215
|
+
publishedAt: item.snippet.publishedAt,
|
|
216
|
+
}))
|
|
217
|
+
.filter((comment) => comment.userComment !== '');
|
|
218
|
+
return comments;
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
console.error('Error fetching live comments:', error);
|
|
222
|
+
this.emit('error', error);
|
|
223
|
+
return [];
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Fetch and process comments
|
|
228
|
+
* @param liveChatId Live chat ID
|
|
229
|
+
*/
|
|
230
|
+
async fetchAndProcessComments(liveChatId) {
|
|
231
|
+
try {
|
|
232
|
+
const comments = await this.retrieveLiveComments(liveChatId);
|
|
233
|
+
if (comments.length === 0) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
// Select comment based on selection strategy
|
|
237
|
+
let selectedComment;
|
|
238
|
+
if (this.options.selectionStrategy === 'random') {
|
|
239
|
+
// Random selection
|
|
240
|
+
selectedComment = comments[Math.floor(Math.random() * comments.length)];
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
// Latest comment selection
|
|
244
|
+
selectedComment = comments[comments.length - 1];
|
|
245
|
+
}
|
|
246
|
+
// Emit comment event
|
|
247
|
+
this.emit('comment', selectedComment);
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
console.error('Error processing comments:', error);
|
|
251
|
+
this.emit('error', error);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=YouTubeDataApiService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"YouTubeDataApiService.js","sourceRoot":"","sources":["../../../src/services/youtube/YouTubeDataApiService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YouTube comment type definition
|
|
3
|
+
*/
|
|
4
|
+
export interface YouTubeComment {
|
|
5
|
+
/** User name */
|
|
6
|
+
userName: string;
|
|
7
|
+
/** User icon URL */
|
|
8
|
+
userIconUrl: string;
|
|
9
|
+
/** Comment content */
|
|
10
|
+
userComment: string;
|
|
11
|
+
/** Published time */
|
|
12
|
+
publishedAt?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* YouTube service settings options
|
|
16
|
+
*/
|
|
17
|
+
export interface YouTubeServiceOptions {
|
|
18
|
+
/** YouTube Data API key */
|
|
19
|
+
apiKey: string;
|
|
20
|
+
/** Comment fetch interval (milliseconds) */
|
|
21
|
+
fetchInterval?: number;
|
|
22
|
+
/** Comment selection strategy ('random' or 'latest') */
|
|
23
|
+
selectionStrategy?: 'random' | 'latest';
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* YouTube service interface
|
|
27
|
+
*/
|
|
28
|
+
export interface YouTubeService {
|
|
29
|
+
/**
|
|
30
|
+
* Start watching live comments
|
|
31
|
+
* @param liveId Live ID
|
|
32
|
+
*/
|
|
33
|
+
startWatching(liveId: string): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Stop watching live comments
|
|
36
|
+
*/
|
|
37
|
+
stopWatching(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Return whether currently fetching
|
|
40
|
+
*/
|
|
41
|
+
isWatching(): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Set comment fetch interval
|
|
44
|
+
* @param interval Interval in milliseconds
|
|
45
|
+
*/
|
|
46
|
+
setFetchInterval(interval: number): void;
|
|
47
|
+
/**
|
|
48
|
+
* Set comment selection strategy
|
|
49
|
+
* @param strategy Selection strategy ('random' or 'latest')
|
|
50
|
+
*/
|
|
51
|
+
setSelectionStrategy(strategy: 'random' | 'latest'): void;
|
|
52
|
+
/**
|
|
53
|
+
* Fetch latest comments (for manual retrieval)
|
|
54
|
+
* @param liveId Live ID
|
|
55
|
+
* @returns Comments array
|
|
56
|
+
*/
|
|
57
|
+
fetchLatestComments(liveId: string): Promise<YouTubeComment[]>;
|
|
58
|
+
/**
|
|
59
|
+
* Subscribe to comment reception event
|
|
60
|
+
* @param callback Callback when comment is received
|
|
61
|
+
*/
|
|
62
|
+
onComment(callback: (comment: YouTubeComment) => void): void;
|
|
63
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"YouTubeService.js","sourceRoot":"","sources":["../../../src/services/youtube/YouTubeService.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AITuber OnAir Core type definitions
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Chat message basic type
|
|
6
|
+
*/
|
|
7
|
+
export interface Message {
|
|
8
|
+
role: 'system' | 'user' | 'assistant';
|
|
9
|
+
content: string;
|
|
10
|
+
timestamp?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Message type corresponding to vision (image)
|
|
14
|
+
*/
|
|
15
|
+
export interface MessageWithVision {
|
|
16
|
+
role: 'system' | 'user' | 'assistant';
|
|
17
|
+
content: string | Array<{
|
|
18
|
+
type: 'text' | 'image_url';
|
|
19
|
+
text?: string;
|
|
20
|
+
image_url?: {
|
|
21
|
+
url: string;
|
|
22
|
+
detail: 'low' | 'high';
|
|
23
|
+
};
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Chat type
|
|
28
|
+
* - chatForm: Chat from text input
|
|
29
|
+
* - youtube: Chat from YouTube comments
|
|
30
|
+
* - vision: Chat from vision (image)
|
|
31
|
+
*/
|
|
32
|
+
export type ChatType = 'chatForm' | 'youtube' | 'vision';
|
|
33
|
+
/**
|
|
34
|
+
* Memory storage interface for persistence
|
|
35
|
+
* Implementations can use various storage mechanisms (LocalStorage, IndexedDB, files, etc.)
|
|
36
|
+
*/
|
|
37
|
+
export interface MemoryStorage {
|
|
38
|
+
/**
|
|
39
|
+
* Load memory records from storage
|
|
40
|
+
* @returns Promise resolving to array of memory records
|
|
41
|
+
*/
|
|
42
|
+
load(): Promise<MemoryRecord[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Save memory records to storage
|
|
45
|
+
* @param records Memory records to save
|
|
46
|
+
* @returns Promise resolving when save is complete
|
|
47
|
+
*/
|
|
48
|
+
save(records: MemoryRecord[]): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Clear all stored memory records
|
|
51
|
+
* @returns Promise resolving when clear is complete
|
|
52
|
+
*/
|
|
53
|
+
clear(): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Memory record type
|
|
57
|
+
*/
|
|
58
|
+
export type MemoryType = 'short' | 'mid' | 'long';
|
|
59
|
+
/**
|
|
60
|
+
* Memory record type
|
|
61
|
+
*/
|
|
62
|
+
export interface MemoryRecord {
|
|
63
|
+
type: MemoryType;
|
|
64
|
+
summary: string;
|
|
65
|
+
timestamp: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Screenplay (text with emotion)
|
|
69
|
+
*/
|
|
70
|
+
export interface Screenplay {
|
|
71
|
+
text: string;
|
|
72
|
+
emotion?: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Speech synthesis options
|
|
76
|
+
*/
|
|
77
|
+
export interface SpeakOptions {
|
|
78
|
+
speed?: number;
|
|
79
|
+
pitch?: number;
|
|
80
|
+
intonation?: number;
|
|
81
|
+
volumeScale?: number;
|
|
82
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface VoiceActor {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
nameReading?: string;
|
|
5
|
+
age?: number;
|
|
6
|
+
gender: string;
|
|
7
|
+
birthMonth?: number;
|
|
8
|
+
birthDay?: number;
|
|
9
|
+
smallImageUrl: string;
|
|
10
|
+
mediumImageUrl: string;
|
|
11
|
+
largeImageUrl: string;
|
|
12
|
+
sampleVoiceUrl: string;
|
|
13
|
+
sampleScript: string;
|
|
14
|
+
recommendedVoiceSpeed: number;
|
|
15
|
+
recommendedEmotionalLevel: number;
|
|
16
|
+
recommendedSoundDuration: number;
|
|
17
|
+
voiceStyles: Array<{
|
|
18
|
+
id: number;
|
|
19
|
+
style: string;
|
|
20
|
+
}>;
|
|
21
|
+
}
|
|
22
|
+
export interface VoiceActorResponse {
|
|
23
|
+
voice_actors: VoiceActor[];
|
|
24
|
+
}
|
|
25
|
+
export interface GeneratedVoiceResponse {
|
|
26
|
+
audio_base64: string;
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nijiVoice.js","sourceRoot":"","sources":["../../src/types/nijiVoice.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Screenplay } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Convert text to screenplay (text with emotion)
|
|
4
|
+
* @param text Original text (may contain emotion expressions like [happy])
|
|
5
|
+
* @returns Screenplay object with emotion and text separated
|
|
6
|
+
*/
|
|
7
|
+
export declare function textToScreenplay(text: string): Screenplay;
|
|
8
|
+
/**
|
|
9
|
+
* Convert multiple texts to screenplay array
|
|
10
|
+
* @param texts Text array
|
|
11
|
+
* @returns Array of screenplay objects
|
|
12
|
+
*/
|
|
13
|
+
export declare function textsToScreenplay(texts: string[]): Screenplay[];
|
|
14
|
+
/**
|
|
15
|
+
* Convert screenplay to text with emotion
|
|
16
|
+
* @param screenplay Screenplay object
|
|
17
|
+
* @returns Text with emotion (e.g. [happy] Hello)
|
|
18
|
+
*/
|
|
19
|
+
export declare function screenplayToText(screenplay: Screenplay): string;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract emotion from text using regex
|
|
3
|
+
* Extract emotion from text written in the format [happy], [sad], etc.
|
|
4
|
+
*/
|
|
5
|
+
const EMOTION_REGEX = /^\s*\[([a-z]+)\]\s*/i;
|
|
6
|
+
/**
|
|
7
|
+
* Convert text to screenplay (text with emotion)
|
|
8
|
+
* @param text Original text (may contain emotion expressions like [happy])
|
|
9
|
+
* @returns Screenplay object with emotion and text separated
|
|
10
|
+
*/
|
|
11
|
+
export function textToScreenplay(text) {
|
|
12
|
+
const match = text.match(EMOTION_REGEX);
|
|
13
|
+
if (match) {
|
|
14
|
+
const emotion = match[1].toLowerCase();
|
|
15
|
+
const cleanText = text.replace(EMOTION_REGEX, '');
|
|
16
|
+
return {
|
|
17
|
+
emotion,
|
|
18
|
+
text: cleanText,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return { text };
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Convert multiple texts to screenplay array
|
|
25
|
+
* @param texts Text array
|
|
26
|
+
* @returns Array of screenplay objects
|
|
27
|
+
*/
|
|
28
|
+
export function textsToScreenplay(texts) {
|
|
29
|
+
return texts.map((text) => textToScreenplay(text));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Convert screenplay to text with emotion
|
|
33
|
+
* @param screenplay Screenplay object
|
|
34
|
+
* @returns Text with emotion (e.g. [happy] Hello)
|
|
35
|
+
*/
|
|
36
|
+
export function screenplayToText(screenplay) {
|
|
37
|
+
if (screenplay.emotion) {
|
|
38
|
+
return `[${screenplay.emotion}] ${screenplay.text}`;
|
|
39
|
+
}
|
|
40
|
+
return screenplay.text;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=screenplay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenplay.js","sourceRoot":"","sources":["../../src/utils/screenplay.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,aAAa,GAAG,sBAAsB,CAAC;AAE7C;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAExC,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAClD,OAAO;YACL,OAAO;YACP,IAAI,EAAE,SAAS;SAChB,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAe;IAC/C,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAAsB;IACrD,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;QACvB,OAAO,IAAI,UAAU,CAAC,OAAO,KAAK,UAAU,CAAC,IAAI,EAAE,CAAC;IACtD,CAAC;IACD,OAAO,UAAU,CAAC,IAAI,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screenshot related utilities
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Capture screenshot from video element
|
|
6
|
+
* @param videoElement Video element to capture
|
|
7
|
+
* @param options Capture options
|
|
8
|
+
* @returns DataURL of image (JPEG), null if failed
|
|
9
|
+
*/
|
|
10
|
+
export declare function captureScreenshot(videoElement: HTMLVideoElement, options?: {
|
|
11
|
+
format?: 'image/jpeg' | 'image/png';
|
|
12
|
+
quality?: number;
|
|
13
|
+
}): string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Convert DataURL to Blob
|
|
16
|
+
* @param dataUrl DataURL of image
|
|
17
|
+
* @returns Blob object
|
|
18
|
+
*/
|
|
19
|
+
export declare function dataUrlToBlob(dataUrl: string): Promise<Blob>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screenshot related utilities
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Capture screenshot from video element
|
|
6
|
+
* @param videoElement Video element to capture
|
|
7
|
+
* @param options Capture options
|
|
8
|
+
* @returns DataURL of image (JPEG), null if failed
|
|
9
|
+
*/
|
|
10
|
+
export function captureScreenshot(videoElement, options = {}) {
|
|
11
|
+
try {
|
|
12
|
+
if (!videoElement) {
|
|
13
|
+
console.warn('Video element not provided');
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
const format = options.format || 'image/jpeg';
|
|
17
|
+
const quality = options.quality || 0.9;
|
|
18
|
+
// Create <canvas> and draw <video>
|
|
19
|
+
const canvas = document.createElement('canvas');
|
|
20
|
+
const ctx = canvas.getContext('2d');
|
|
21
|
+
if (!ctx) {
|
|
22
|
+
console.warn('Failed to get canvas context');
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
canvas.width = videoElement.videoWidth;
|
|
26
|
+
canvas.height = videoElement.videoHeight;
|
|
27
|
+
ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
|
|
28
|
+
return canvas.toDataURL(format, quality);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error('Error capturing screenshot:', error);
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Convert DataURL to Blob
|
|
37
|
+
* @param dataUrl DataURL of image
|
|
38
|
+
* @returns Blob object
|
|
39
|
+
*/
|
|
40
|
+
export async function dataUrlToBlob(dataUrl) {
|
|
41
|
+
const response = await fetch(dataUrl);
|
|
42
|
+
return await response.blob();
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=screenshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../src/utils/screenshot.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,YAA8B,EAC9B,UAAqE,EAAE;IAEvE,IAAI,CAAC;QACH,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;YAC3C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,YAAY,CAAC;QAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,GAAG,CAAC;QAEvC,mCAAmC;QACnC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;YAC7C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,CAAC,KAAK,GAAG,YAAY,CAAC,UAAU,CAAC;QACvC,MAAM,CAAC,MAAM,GAAG,YAAY,CAAC,WAAW,CAAC;QACzC,GAAG,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAE/D,OAAO,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe;IACjD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC;IACtC,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { MemoryRecord, MemoryStorage } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* LocalStorage implementation of MemoryStorage
|
|
4
|
+
*/
|
|
5
|
+
export declare class LocalStorageMemoryStorage implements MemoryStorage {
|
|
6
|
+
private storageKey;
|
|
7
|
+
/**
|
|
8
|
+
* Constructor
|
|
9
|
+
* @param storageKey Key to use in localStorage
|
|
10
|
+
*/
|
|
11
|
+
constructor(storageKey: string);
|
|
12
|
+
/**
|
|
13
|
+
* Load memory records from localStorage
|
|
14
|
+
* @returns Promise resolving to array of memory records
|
|
15
|
+
*/
|
|
16
|
+
load(): Promise<MemoryRecord[]>;
|
|
17
|
+
/**
|
|
18
|
+
* Save memory records to localStorage
|
|
19
|
+
* @param records Memory records to save
|
|
20
|
+
* @returns Promise resolving when save is complete
|
|
21
|
+
*/
|
|
22
|
+
save(records: MemoryRecord[]): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Clear all stored memory records
|
|
25
|
+
* @returns Promise resolving when clear is complete
|
|
26
|
+
*/
|
|
27
|
+
clear(): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* IndexedDB implementation of MemoryStorage (example skeleton)
|
|
31
|
+
* This is just a placeholder - would need to be implemented properly
|
|
32
|
+
*/
|
|
33
|
+
export declare class IndexedDBMemoryStorage implements MemoryStorage {
|
|
34
|
+
load(): Promise<MemoryRecord[]>;
|
|
35
|
+
save(records: MemoryRecord[]): Promise<void>;
|
|
36
|
+
clear(): Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Factory function to create appropriate storage based on environment
|
|
40
|
+
* @param storageKey Key to use for storage
|
|
41
|
+
* @param storageType Type of storage to use
|
|
42
|
+
* @returns MemoryStorage implementation
|
|
43
|
+
*/
|
|
44
|
+
export declare function createMemoryStorage(storageKey: string, storageType?: 'localStorage' | 'indexedDB'): MemoryStorage;
|