junr-plugin-minimax 0.0.1
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 +94 -0
- package/dist/_assets/icon_l_en.png +0 -0
- package/dist/_assets/icon_s_en.png +0 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/llm/abab5-chat.yaml +38 -0
- package/dist/llm/abab5.5-chat.yaml +53 -0
- package/dist/llm/abab5.5s-chat.yaml +44 -0
- package/dist/llm/abab6-chat.yaml +46 -0
- package/dist/llm/abab6.5-chat.yaml +46 -0
- package/dist/llm/abab6.5s-chat.yaml +46 -0
- package/dist/llm/abab6.5t-chat.yaml +44 -0
- package/dist/llm/abab7-chat-preview.yaml +46 -0
- package/dist/llm/llm.d.ts +12 -0
- package/dist/llm/llm.d.ts.map +1 -0
- package/dist/llm/llm.js +48 -0
- package/dist/llm/minimax-m1.yaml +37 -0
- package/dist/llm/minimax-m2.5-lightning.yaml +37 -0
- package/dist/llm/minimax-m2.5.yaml +37 -0
- package/dist/llm/minimax-m2.yaml +37 -0
- package/dist/llm/minimax-text-01.yaml +46 -0
- package/dist/manifest.yaml +36 -0
- package/dist/minimax.module.d.ts +3 -0
- package/dist/minimax.module.d.ts.map +1 -0
- package/dist/minimax.module.js +16 -0
- package/dist/provider.strategy.d.ts +8 -0
- package/dist/provider.strategy.d.ts.map +1 -0
- package/dist/provider.strategy.js +34 -0
- package/dist/text-embedding/embo-01.yaml +9 -0
- package/dist/text-embedding/text-embedding.d.ts +31 -0
- package/dist/text-embedding/text-embedding.d.ts.map +1 -0
- package/dist/text-embedding/text-embedding.js +132 -0
- package/dist/tts/speech-01-hd.yaml +151 -0
- package/dist/tts/speech-01-turbo.yaml +151 -0
- package/dist/tts/speech-02-hd.yaml +151 -0
- package/dist/tts/speech-02-turbo.yaml +151 -0
- package/dist/tts/tts.d.ts +24 -0
- package/dist/tts/tts.d.ts.map +1 -0
- package/dist/tts/tts.js +207 -0
- package/dist/types.d.ts +21 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +39 -0
- package/package.json +48 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
model: speech-01-turbo
|
|
2
|
+
model_type: tts
|
|
3
|
+
model_properties:
|
|
4
|
+
default_voice: 'male-qn-qingse'
|
|
5
|
+
voices:
|
|
6
|
+
- name: "青涩青年音色"
|
|
7
|
+
mode: "male-qn-qingse"
|
|
8
|
+
language: ['zh-Hans']
|
|
9
|
+
- name: "精英青年音色"
|
|
10
|
+
mode: "male-qn-jingying"
|
|
11
|
+
language: ['zh-Hans']
|
|
12
|
+
- name: "霸道青年音色"
|
|
13
|
+
mode: "male-qn-badao"
|
|
14
|
+
language: ['zh-Hans']
|
|
15
|
+
- name: "青年大学生音色"
|
|
16
|
+
mode: "male-qn-daxuesheng"
|
|
17
|
+
language: ['zh-Hans']
|
|
18
|
+
- name: "少女音色"
|
|
19
|
+
mode: "female-shaonv"
|
|
20
|
+
language: ['zh-Hans']
|
|
21
|
+
- name: "御姐音色"
|
|
22
|
+
mode: "female-yujie"
|
|
23
|
+
language: ['zh-Hans']
|
|
24
|
+
- name: "成熟女性音色"
|
|
25
|
+
mode: "female-chengshu"
|
|
26
|
+
language: ['zh-Hans']
|
|
27
|
+
- name: "甜美女性音色"
|
|
28
|
+
mode: "female-tianmei"
|
|
29
|
+
language: ['zh-Hans']
|
|
30
|
+
- name: "男性主持人"
|
|
31
|
+
mode: "presenter_male"
|
|
32
|
+
language: ['zh-Hans']
|
|
33
|
+
- name: "女性主持人"
|
|
34
|
+
mode: "presenter_female"
|
|
35
|
+
language: ['zh-Hans']
|
|
36
|
+
- name: "男性有声书1"
|
|
37
|
+
mode: "audiobook_male_1"
|
|
38
|
+
language: ['zh-Hans']
|
|
39
|
+
- name: "男性有声书2"
|
|
40
|
+
mode: "audiobook_male_2"
|
|
41
|
+
language: ['zh-Hans']
|
|
42
|
+
- name: "女性有声书1"
|
|
43
|
+
mode: "audiobook_female_1"
|
|
44
|
+
language: ['zh-Hans']
|
|
45
|
+
- name: "女性有声书2"
|
|
46
|
+
mode: "audiobook_female_2"
|
|
47
|
+
language: ['zh-Hans']
|
|
48
|
+
- name: "青涩青年音色(精品版)"
|
|
49
|
+
mode: "male-qn-qingse-jingpin"
|
|
50
|
+
language: ['zh-Hans']
|
|
51
|
+
- name: "精英青年音色(精品版)"
|
|
52
|
+
mode: "male-qn-jingying-jingpin"
|
|
53
|
+
language: ['zh-Hans']
|
|
54
|
+
- name: "霸道青年音色(精品版)"
|
|
55
|
+
mode: "male-qn-badao-jingpin"
|
|
56
|
+
language: ['zh-Hans']
|
|
57
|
+
- name: "青年大学生音色(精品版)"
|
|
58
|
+
mode: "male-qn-daxuesheng-jingpin"
|
|
59
|
+
language: ['zh-Hans']
|
|
60
|
+
- name: "少女音色(精品版)"
|
|
61
|
+
mode: "female-shaonv-jingpin"
|
|
62
|
+
language: ['zh-Hans']
|
|
63
|
+
- name: "御姐音色(精品版)"
|
|
64
|
+
mode: "female-yujie-jingpin"
|
|
65
|
+
language: ['zh-Hans']
|
|
66
|
+
- name: "成熟女性音色(精品版)"
|
|
67
|
+
mode: "female-chengshu-jingpin"
|
|
68
|
+
language: ['zh-Hans']
|
|
69
|
+
- name: "甜美女性音色(精品版)"
|
|
70
|
+
mode: "female-tianmei-jingpin"
|
|
71
|
+
language: ['zh-Hans']
|
|
72
|
+
- name: "聪明男童"
|
|
73
|
+
mode: "clever_boy"
|
|
74
|
+
language: ['zh-Hans']
|
|
75
|
+
- name: "可爱男童"
|
|
76
|
+
mode: "cute_boy"
|
|
77
|
+
language: ['zh-Hans']
|
|
78
|
+
- name: "萌萌女童"
|
|
79
|
+
mode: "lovely_girl"
|
|
80
|
+
language: ['zh-Hans']
|
|
81
|
+
- name: "卡通猪小琪"
|
|
82
|
+
mode: "cartoon_pig"
|
|
83
|
+
language: ['zh-Hans']
|
|
84
|
+
- name: "病娇弟弟"
|
|
85
|
+
mode: "bingjiao_didi"
|
|
86
|
+
language: ['zh-Hans']
|
|
87
|
+
- name: "俊朗男友"
|
|
88
|
+
mode: "junlang_nanyou"
|
|
89
|
+
language: ['zh-Hans']
|
|
90
|
+
- name: "纯真学弟"
|
|
91
|
+
mode: "chunzhen_xuedi"
|
|
92
|
+
language: ['zh-Hans']
|
|
93
|
+
- name: "冷淡学长"
|
|
94
|
+
mode: "lengdan_xiongzhang"
|
|
95
|
+
language: ['zh-Hans']
|
|
96
|
+
- name: "霸道少爷"
|
|
97
|
+
mode: "badao_shaoye"
|
|
98
|
+
language: ['zh-Hans']
|
|
99
|
+
- name: "甜心小玲"
|
|
100
|
+
mode: "tianxin_xiaoling"
|
|
101
|
+
language: ['zh-Hans']
|
|
102
|
+
- name: "俏皮萌妹"
|
|
103
|
+
mode: "qiaopi_mengmei"
|
|
104
|
+
language: ['zh-Hans']
|
|
105
|
+
- name: "妩媚御姐"
|
|
106
|
+
mode: "wumei_yujie"
|
|
107
|
+
language: ['zh-Hans']
|
|
108
|
+
- name: "嗲嗲学妹"
|
|
109
|
+
mode: "diadia_xuemei"
|
|
110
|
+
language: ['zh-Hans']
|
|
111
|
+
- name: "淡雅学姐"
|
|
112
|
+
mode: "danya_xuejie"
|
|
113
|
+
language: ['zh-Hans']
|
|
114
|
+
- name: "Santa Claus"
|
|
115
|
+
mode: "Santa_Claus"
|
|
116
|
+
language: ['en-US']
|
|
117
|
+
- name: "Grinch"
|
|
118
|
+
mode: "Grinch"
|
|
119
|
+
language: ['en-US']
|
|
120
|
+
- name: "Rudolph"
|
|
121
|
+
mode: "Rudolph"
|
|
122
|
+
language: ['en-US']
|
|
123
|
+
- name: "Arnold"
|
|
124
|
+
mode: "Arnold"
|
|
125
|
+
language: ['en-US']
|
|
126
|
+
- name: "Charming Santa"
|
|
127
|
+
mode: "Charming_Santa"
|
|
128
|
+
language: ['en-US']
|
|
129
|
+
- name: "Charming Lady"
|
|
130
|
+
mode: "Charming_Lady"
|
|
131
|
+
language: ['en-US']
|
|
132
|
+
- name: "Sweet Girl"
|
|
133
|
+
mode: "Sweet_Girl"
|
|
134
|
+
language: ['en-US']
|
|
135
|
+
- name: "Cute Elf"
|
|
136
|
+
mode: "Cute_Elf"
|
|
137
|
+
language: ['en-US']
|
|
138
|
+
- name: "Attractive Girl"
|
|
139
|
+
mode: "Attractive_Girl"
|
|
140
|
+
language: ['en-US']
|
|
141
|
+
- name: "Serene Woman"
|
|
142
|
+
mode: "Serene_Woman"
|
|
143
|
+
language: ['en-US']
|
|
144
|
+
word_limit: 8000
|
|
145
|
+
audio_type: 'mp3'
|
|
146
|
+
max_workers: 5
|
|
147
|
+
pricing:
|
|
148
|
+
input: '1'
|
|
149
|
+
output: '0'
|
|
150
|
+
unit: '0.0001'
|
|
151
|
+
currency: RMB
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
model: speech-02-hd
|
|
2
|
+
model_type: tts
|
|
3
|
+
model_properties:
|
|
4
|
+
default_voice: 'male-qn-qingse'
|
|
5
|
+
voices:
|
|
6
|
+
- name: "青涩青年音色"
|
|
7
|
+
mode: "male-qn-qingse"
|
|
8
|
+
language: ['zh-Hans']
|
|
9
|
+
- name: "精英青年音色"
|
|
10
|
+
mode: "male-qn-jingying"
|
|
11
|
+
language: ['zh-Hans']
|
|
12
|
+
- name: "霸道青年音色"
|
|
13
|
+
mode: "male-qn-badao"
|
|
14
|
+
language: ['zh-Hans']
|
|
15
|
+
- name: "青年大学生音色"
|
|
16
|
+
mode: "male-qn-daxuesheng"
|
|
17
|
+
language: ['zh-Hans']
|
|
18
|
+
- name: "少女音色"
|
|
19
|
+
mode: "female-shaonv"
|
|
20
|
+
language: ['zh-Hans']
|
|
21
|
+
- name: "御姐音色"
|
|
22
|
+
mode: "female-yujie"
|
|
23
|
+
language: ['zh-Hans']
|
|
24
|
+
- name: "成熟女性音色"
|
|
25
|
+
mode: "female-chengshu"
|
|
26
|
+
language: ['zh-Hans']
|
|
27
|
+
- name: "甜美女性音色"
|
|
28
|
+
mode: "female-tianmei"
|
|
29
|
+
language: ['zh-Hans']
|
|
30
|
+
- name: "男性主持人"
|
|
31
|
+
mode: "presenter_male"
|
|
32
|
+
language: ['zh-Hans']
|
|
33
|
+
- name: "女性主持人"
|
|
34
|
+
mode: "presenter_female"
|
|
35
|
+
language: ['zh-Hans']
|
|
36
|
+
- name: "男性有声书1"
|
|
37
|
+
mode: "audiobook_male_1"
|
|
38
|
+
language: ['zh-Hans']
|
|
39
|
+
- name: "男性有声书2"
|
|
40
|
+
mode: "audiobook_male_2"
|
|
41
|
+
language: ['zh-Hans']
|
|
42
|
+
- name: "女性有声书1"
|
|
43
|
+
mode: "audiobook_female_1"
|
|
44
|
+
language: ['zh-Hans']
|
|
45
|
+
- name: "女性有声书2"
|
|
46
|
+
mode: "audiobook_female_2"
|
|
47
|
+
language: ['zh-Hans']
|
|
48
|
+
- name: "青涩青年音色(精品版)"
|
|
49
|
+
mode: "male-qn-qingse-jingpin"
|
|
50
|
+
language: ['zh-Hans']
|
|
51
|
+
- name: "精英青年音色(精品版)"
|
|
52
|
+
mode: "male-qn-jingying-jingpin"
|
|
53
|
+
language: ['zh-Hans']
|
|
54
|
+
- name: "霸道青年音色(精品版)"
|
|
55
|
+
mode: "male-qn-badao-jingpin"
|
|
56
|
+
language: ['zh-Hans']
|
|
57
|
+
- name: "青年大学生音色(精品版)"
|
|
58
|
+
mode: "male-qn-daxuesheng-jingpin"
|
|
59
|
+
language: ['zh-Hans']
|
|
60
|
+
- name: "少女音色(精品版)"
|
|
61
|
+
mode: "female-shaonv-jingpin"
|
|
62
|
+
language: ['zh-Hans']
|
|
63
|
+
- name: "御姐音色(精品版)"
|
|
64
|
+
mode: "female-yujie-jingpin"
|
|
65
|
+
language: ['zh-Hans']
|
|
66
|
+
- name: "成熟女性音色(精品版)"
|
|
67
|
+
mode: "female-chengshu-jingpin"
|
|
68
|
+
language: ['zh-Hans']
|
|
69
|
+
- name: "甜美女性音色(精品版)"
|
|
70
|
+
mode: "female-tianmei-jingpin"
|
|
71
|
+
language: ['zh-Hans']
|
|
72
|
+
- name: "聪明男童"
|
|
73
|
+
mode: "clever_boy"
|
|
74
|
+
language: ['zh-Hans']
|
|
75
|
+
- name: "可爱男童"
|
|
76
|
+
mode: "cute_boy"
|
|
77
|
+
language: ['zh-Hans']
|
|
78
|
+
- name: "萌萌女童"
|
|
79
|
+
mode: "lovely_girl"
|
|
80
|
+
language: ['zh-Hans']
|
|
81
|
+
- name: "卡通猪小琪"
|
|
82
|
+
mode: "cartoon_pig"
|
|
83
|
+
language: ['zh-Hans']
|
|
84
|
+
- name: "病娇弟弟"
|
|
85
|
+
mode: "bingjiao_didi"
|
|
86
|
+
language: ['zh-Hans']
|
|
87
|
+
- name: "俊朗男友"
|
|
88
|
+
mode: "junlang_nanyou"
|
|
89
|
+
language: ['zh-Hans']
|
|
90
|
+
- name: "纯真学弟"
|
|
91
|
+
mode: "chunzhen_xuedi"
|
|
92
|
+
language: ['zh-Hans']
|
|
93
|
+
- name: "冷淡学长"
|
|
94
|
+
mode: "lengdan_xiongzhang"
|
|
95
|
+
language: ['zh-Hans']
|
|
96
|
+
- name: "霸道少爷"
|
|
97
|
+
mode: "badao_shaoye"
|
|
98
|
+
language: ['zh-Hans']
|
|
99
|
+
- name: "甜心小玲"
|
|
100
|
+
mode: "tianxin_xiaoling"
|
|
101
|
+
language: ['zh-Hans']
|
|
102
|
+
- name: "俏皮萌妹"
|
|
103
|
+
mode: "qiaopi_mengmei"
|
|
104
|
+
language: ['zh-Hans']
|
|
105
|
+
- name: "妩媚御姐"
|
|
106
|
+
mode: "wumei_yujie"
|
|
107
|
+
language: ['zh-Hans']
|
|
108
|
+
- name: "嗲嗲学妹"
|
|
109
|
+
mode: "diadia_xuemei"
|
|
110
|
+
language: ['zh-Hans']
|
|
111
|
+
- name: "淡雅学姐"
|
|
112
|
+
mode: "danya_xuejie"
|
|
113
|
+
language: ['zh-Hans']
|
|
114
|
+
- name: "Santa Claus"
|
|
115
|
+
mode: "Santa_Claus"
|
|
116
|
+
language: ['en-US']
|
|
117
|
+
- name: "Grinch"
|
|
118
|
+
mode: "Grinch"
|
|
119
|
+
language: ['en-US']
|
|
120
|
+
- name: "Rudolph"
|
|
121
|
+
mode: "Rudolph"
|
|
122
|
+
language: ['en-US']
|
|
123
|
+
- name: "Arnold"
|
|
124
|
+
mode: "Arnold"
|
|
125
|
+
language: ['en-US']
|
|
126
|
+
- name: "Charming Santa"
|
|
127
|
+
mode: "Charming_Santa"
|
|
128
|
+
language: ['en-US']
|
|
129
|
+
- name: "Charming Lady"
|
|
130
|
+
mode: "Charming_Lady"
|
|
131
|
+
language: ['en-US']
|
|
132
|
+
- name: "Sweet Girl"
|
|
133
|
+
mode: "Sweet_Girl"
|
|
134
|
+
language: ['en-US']
|
|
135
|
+
- name: "Cute Elf"
|
|
136
|
+
mode: "Cute_Elf"
|
|
137
|
+
language: ['en-US']
|
|
138
|
+
- name: "Attractive Girl"
|
|
139
|
+
mode: "Attractive_Girl"
|
|
140
|
+
language: ['en-US']
|
|
141
|
+
- name: "Serene Woman"
|
|
142
|
+
mode: "Serene_Woman"
|
|
143
|
+
language: ['en-US']
|
|
144
|
+
word_limit: 8000
|
|
145
|
+
audio_type: 'mp3'
|
|
146
|
+
max_workers: 5
|
|
147
|
+
pricing:
|
|
148
|
+
input: '1'
|
|
149
|
+
output: '0'
|
|
150
|
+
unit: '0.0001'
|
|
151
|
+
currency: RMB
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
model: speech-02-turbo
|
|
2
|
+
model_type: tts
|
|
3
|
+
model_properties:
|
|
4
|
+
default_voice: 'male-qn-qingse'
|
|
5
|
+
voices:
|
|
6
|
+
- name: "青涩青年音色"
|
|
7
|
+
mode: "male-qn-qingse"
|
|
8
|
+
language: ['zh-Hans']
|
|
9
|
+
- name: "精英青年音色"
|
|
10
|
+
mode: "male-qn-jingying"
|
|
11
|
+
language: ['zh-Hans']
|
|
12
|
+
- name: "霸道青年音色"
|
|
13
|
+
mode: "male-qn-badao"
|
|
14
|
+
language: ['zh-Hans']
|
|
15
|
+
- name: "青年大学生音色"
|
|
16
|
+
mode: "male-qn-daxuesheng"
|
|
17
|
+
language: ['zh-Hans']
|
|
18
|
+
- name: "少女音色"
|
|
19
|
+
mode: "female-shaonv"
|
|
20
|
+
language: ['zh-Hans']
|
|
21
|
+
- name: "御姐音色"
|
|
22
|
+
mode: "female-yujie"
|
|
23
|
+
language: ['zh-Hans']
|
|
24
|
+
- name: "成熟女性音色"
|
|
25
|
+
mode: "female-chengshu"
|
|
26
|
+
language: ['zh-Hans']
|
|
27
|
+
- name: "甜美女性音色"
|
|
28
|
+
mode: "female-tianmei"
|
|
29
|
+
language: ['zh-Hans']
|
|
30
|
+
- name: "男性主持人"
|
|
31
|
+
mode: "presenter_male"
|
|
32
|
+
language: ['zh-Hans']
|
|
33
|
+
- name: "女性主持人"
|
|
34
|
+
mode: "presenter_female"
|
|
35
|
+
language: ['zh-Hans']
|
|
36
|
+
- name: "男性有声书1"
|
|
37
|
+
mode: "audiobook_male_1"
|
|
38
|
+
language: ['zh-Hans']
|
|
39
|
+
- name: "男性有声书2"
|
|
40
|
+
mode: "audiobook_male_2"
|
|
41
|
+
language: ['zh-Hans']
|
|
42
|
+
- name: "女性有声书1"
|
|
43
|
+
mode: "audiobook_female_1"
|
|
44
|
+
language: ['zh-Hans']
|
|
45
|
+
- name: "女性有声书2"
|
|
46
|
+
mode: "audiobook_female_2"
|
|
47
|
+
language: ['zh-Hans']
|
|
48
|
+
- name: "青涩青年音色(精品版)"
|
|
49
|
+
mode: "male-qn-qingse-jingpin"
|
|
50
|
+
language: ['zh-Hans']
|
|
51
|
+
- name: "精英青年音色(精品版)"
|
|
52
|
+
mode: "male-qn-jingying-jingpin"
|
|
53
|
+
language: ['zh-Hans']
|
|
54
|
+
- name: "霸道青年音色(精品版)"
|
|
55
|
+
mode: "male-qn-badao-jingpin"
|
|
56
|
+
language: ['zh-Hans']
|
|
57
|
+
- name: "青年大学生音色(精品版)"
|
|
58
|
+
mode: "male-qn-daxuesheng-jingpin"
|
|
59
|
+
language: ['zh-Hans']
|
|
60
|
+
- name: "少女音色(精品版)"
|
|
61
|
+
mode: "female-shaonv-jingpin"
|
|
62
|
+
language: ['zh-Hans']
|
|
63
|
+
- name: "御姐音色(精品版)"
|
|
64
|
+
mode: "female-yujie-jingpin"
|
|
65
|
+
language: ['zh-Hans']
|
|
66
|
+
- name: "成熟女性音色(精品版)"
|
|
67
|
+
mode: "female-chengshu-jingpin"
|
|
68
|
+
language: ['zh-Hans']
|
|
69
|
+
- name: "甜美女性音色(精品版)"
|
|
70
|
+
mode: "female-tianmei-jingpin"
|
|
71
|
+
language: ['zh-Hans']
|
|
72
|
+
- name: "聪明男童"
|
|
73
|
+
mode: "clever_boy"
|
|
74
|
+
language: ['zh-Hans']
|
|
75
|
+
- name: "可爱男童"
|
|
76
|
+
mode: "cute_boy"
|
|
77
|
+
language: ['zh-Hans']
|
|
78
|
+
- name: "萌萌女童"
|
|
79
|
+
mode: "lovely_girl"
|
|
80
|
+
language: ['zh-Hans']
|
|
81
|
+
- name: "卡通猪小琪"
|
|
82
|
+
mode: "cartoon_pig"
|
|
83
|
+
language: ['zh-Hans']
|
|
84
|
+
- name: "病娇弟弟"
|
|
85
|
+
mode: "bingjiao_didi"
|
|
86
|
+
language: ['zh-Hans']
|
|
87
|
+
- name: "俊朗男友"
|
|
88
|
+
mode: "junlang_nanyou"
|
|
89
|
+
language: ['zh-Hans']
|
|
90
|
+
- name: "纯真学弟"
|
|
91
|
+
mode: "chunzhen_xuedi"
|
|
92
|
+
language: ['zh-Hans']
|
|
93
|
+
- name: "冷淡学长"
|
|
94
|
+
mode: "lengdan_xiongzhang"
|
|
95
|
+
language: ['zh-Hans']
|
|
96
|
+
- name: "霸道少爷"
|
|
97
|
+
mode: "badao_shaoye"
|
|
98
|
+
language: ['zh-Hans']
|
|
99
|
+
- name: "甜心小玲"
|
|
100
|
+
mode: "tianxin_xiaoling"
|
|
101
|
+
language: ['zh-Hans']
|
|
102
|
+
- name: "俏皮萌妹"
|
|
103
|
+
mode: "qiaopi_mengmei"
|
|
104
|
+
language: ['zh-Hans']
|
|
105
|
+
- name: "妩媚御姐"
|
|
106
|
+
mode: "wumei_yujie"
|
|
107
|
+
language: ['zh-Hans']
|
|
108
|
+
- name: "嗲嗲学妹"
|
|
109
|
+
mode: "diadia_xuemei"
|
|
110
|
+
language: ['zh-Hans']
|
|
111
|
+
- name: "淡雅学姐"
|
|
112
|
+
mode: "danya_xuejie"
|
|
113
|
+
language: ['zh-Hans']
|
|
114
|
+
- name: "Santa Claus"
|
|
115
|
+
mode: "Santa_Claus"
|
|
116
|
+
language: ['en-US']
|
|
117
|
+
- name: "Grinch"
|
|
118
|
+
mode: "Grinch"
|
|
119
|
+
language: ['en-US']
|
|
120
|
+
- name: "Rudolph"
|
|
121
|
+
mode: "Rudolph"
|
|
122
|
+
language: ['en-US']
|
|
123
|
+
- name: "Arnold"
|
|
124
|
+
mode: "Arnold"
|
|
125
|
+
language: ['en-US']
|
|
126
|
+
- name: "Charming Santa"
|
|
127
|
+
mode: "Charming_Santa"
|
|
128
|
+
language: ['en-US']
|
|
129
|
+
- name: "Charming Lady"
|
|
130
|
+
mode: "Charming_Lady"
|
|
131
|
+
language: ['en-US']
|
|
132
|
+
- name: "Sweet Girl"
|
|
133
|
+
mode: "Sweet_Girl"
|
|
134
|
+
language: ['en-US']
|
|
135
|
+
- name: "Cute Elf"
|
|
136
|
+
mode: "Cute_Elf"
|
|
137
|
+
language: ['en-US']
|
|
138
|
+
- name: "Attractive Girl"
|
|
139
|
+
mode: "Attractive_Girl"
|
|
140
|
+
language: ['en-US']
|
|
141
|
+
- name: "Serene Woman"
|
|
142
|
+
mode: "Serene_Woman"
|
|
143
|
+
language: ['en-US']
|
|
144
|
+
word_limit: 8000
|
|
145
|
+
audio_type: 'mp3'
|
|
146
|
+
max_workers: 5
|
|
147
|
+
pricing:
|
|
148
|
+
input: '1'
|
|
149
|
+
output: '0'
|
|
150
|
+
unit: '0.0001'
|
|
151
|
+
currency: RMB
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { TextToSpeechModel, TChatModelOptions } from '@xpert-ai/plugin-sdk';
|
|
2
|
+
import { MiniMaxProviderStrategy } from '../provider.strategy.js';
|
|
3
|
+
import { MiniMaxModelCredentials } from '../types.js';
|
|
4
|
+
export interface MiniMaxTTSOptions {
|
|
5
|
+
voice?: string;
|
|
6
|
+
speed?: number;
|
|
7
|
+
format?: 'mp3' | 'opus' | 'aac' | 'flac' | 'wav';
|
|
8
|
+
language?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface MiniMaxTTSResponse {
|
|
11
|
+
audioData: ArrayBuffer;
|
|
12
|
+
contentType: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class MiniMaxTTSModel extends TextToSpeechModel {
|
|
15
|
+
constructor(modelProvider: MiniMaxProviderStrategy);
|
|
16
|
+
synthesizeSpeech(model: string, text: string, credentials: MiniMaxModelCredentials, options?: MiniMaxTTSOptions): Promise<MiniMaxTTSResponse>;
|
|
17
|
+
getTTSInstance(model: string, credentials: MiniMaxModelCredentials, options?: TChatModelOptions): {
|
|
18
|
+
model: string;
|
|
19
|
+
synthesizeSpeech: (text: string, ttsOptions?: MiniMaxTTSOptions) => Promise<MiniMaxTTSResponse>;
|
|
20
|
+
};
|
|
21
|
+
validateCredentials(model: string, credentials: MiniMaxModelCredentials): Promise<void>;
|
|
22
|
+
static getSupportedModels(): string[];
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=tts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tts.d.ts","sourceRoot":"","sources":["../../src/tts/tts.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAA4C,MAAM,aAAa,CAAC;AAEhG,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,WAAW,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAaD,qBACa,eAAgB,SAAQ,iBAAiB;gBACxC,aAAa,EAAE,uBAAuB;IAI5C,gBAAgB,CACpB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,uBAAuB,EACpC,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,kBAAkB,CAAC;IAgM9B,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,uBAAuB,EAAE,OAAO,CAAC,EAAE,iBAAiB;;iCAIlE,MAAM,eAAe,iBAAiB;;IAK7D,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAY7F,MAAM,CAAC,kBAAkB;CAG1B"}
|
package/dist/tts/tts.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { __decorate, __metadata } from "tslib";
|
|
2
|
+
import { Injectable } from '@nestjs/common';
|
|
3
|
+
import { AiModelTypeEnum } from '@metad/contracts';
|
|
4
|
+
import { CredentialsValidateFailedError, mergeCredentials, TextToSpeechModel } from '@xpert-ai/plugin-sdk';
|
|
5
|
+
import { MiniMaxProviderStrategy } from '../provider.strategy.js';
|
|
6
|
+
import { SUPPORTED_TTS_MODELS, toCredentialKwargs } from '../types.js';
|
|
7
|
+
let MiniMaxTTSModel = class MiniMaxTTSModel extends TextToSpeechModel {
|
|
8
|
+
constructor(modelProvider) {
|
|
9
|
+
super(modelProvider, AiModelTypeEnum.TTS);
|
|
10
|
+
}
|
|
11
|
+
async synthesizeSpeech(model, text, credentials, options) {
|
|
12
|
+
const params = toCredentialKwargs(credentials, model);
|
|
13
|
+
// Remove /v1 from baseURL if present, then add it back
|
|
14
|
+
const baseURL = params.configuration.baseURL.replace(/\/v1$/, '').replace(/\/$/, '');
|
|
15
|
+
const url = `${baseURL}/v1/t2a_v2?GroupId=${params.groupId}`;
|
|
16
|
+
const payload = {
|
|
17
|
+
model,
|
|
18
|
+
text,
|
|
19
|
+
stream: true, // MiniMax TTS always uses streaming
|
|
20
|
+
voice_setting: {
|
|
21
|
+
voice_id: options?.voice ?? 'male-qn-qingse',
|
|
22
|
+
speed: options?.speed ?? 1.0,
|
|
23
|
+
vol: 1.0,
|
|
24
|
+
pitch: 0
|
|
25
|
+
},
|
|
26
|
+
audio_setting: {
|
|
27
|
+
sample_rate: 32000,
|
|
28
|
+
bitrate: 128000,
|
|
29
|
+
format: (options?.format ?? 'mp3'), // Ensure format is a string
|
|
30
|
+
channel: 1
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const response = await fetch(url, {
|
|
34
|
+
method: 'POST',
|
|
35
|
+
headers: {
|
|
36
|
+
Authorization: `Bearer ${params.apiKey}`,
|
|
37
|
+
'Content-Type': 'application/json'
|
|
38
|
+
},
|
|
39
|
+
body: JSON.stringify(payload)
|
|
40
|
+
});
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
const errorText = await response.text();
|
|
43
|
+
throw new Error(`MiniMax TTS request failed: ${response.status} ${errorText}`);
|
|
44
|
+
}
|
|
45
|
+
// Check content type to determine response format
|
|
46
|
+
const responseContentType = response.headers.get('content-type') || '';
|
|
47
|
+
// If response is JSON (non-streaming), handle it directly
|
|
48
|
+
if (responseContentType.includes('application/json')) {
|
|
49
|
+
const result = (await response.json());
|
|
50
|
+
if (result.base_resp?.status_code !== 0) {
|
|
51
|
+
const code = result.base_resp?.status_code;
|
|
52
|
+
const msg = result.base_resp?.status_msg || 'Unknown error';
|
|
53
|
+
throw new Error(`MiniMax TTS API error: ${code} ${msg}`);
|
|
54
|
+
}
|
|
55
|
+
// Extract audio from JSON response
|
|
56
|
+
let audioData;
|
|
57
|
+
if (result.data?.audio) {
|
|
58
|
+
const audioHex = result.data.audio;
|
|
59
|
+
const audioBytes = new Uint8Array(audioHex.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16)) || []);
|
|
60
|
+
audioData = new ArrayBuffer(audioBytes.length);
|
|
61
|
+
new Uint8Array(audioData).set(audioBytes);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
throw new Error('No audio data in MiniMax TTS JSON response');
|
|
65
|
+
}
|
|
66
|
+
const audioContentType = options?.format === 'wav' ? 'audio/wav' :
|
|
67
|
+
options?.format === 'flac' ? 'audio/flac' :
|
|
68
|
+
options?.format === 'opus' ? 'audio/opus' :
|
|
69
|
+
options?.format === 'aac' ? 'audio/aac' :
|
|
70
|
+
'audio/mpeg';
|
|
71
|
+
return { audioData, contentType: audioContentType };
|
|
72
|
+
}
|
|
73
|
+
// MiniMax TTS returns streaming response with data: prefix
|
|
74
|
+
// Collect all audio chunks from the stream
|
|
75
|
+
const reader = response.body?.getReader();
|
|
76
|
+
if (!reader) {
|
|
77
|
+
throw new Error('Failed to get response reader');
|
|
78
|
+
}
|
|
79
|
+
const decoder = new TextDecoder();
|
|
80
|
+
const audioChunks = [];
|
|
81
|
+
let buffer = '';
|
|
82
|
+
try {
|
|
83
|
+
while (true) {
|
|
84
|
+
const { done, value } = await reader.read();
|
|
85
|
+
if (done)
|
|
86
|
+
break;
|
|
87
|
+
buffer += decoder.decode(value, { stream: true });
|
|
88
|
+
const lines = buffer.split('\n');
|
|
89
|
+
// Keep the last incomplete line in buffer
|
|
90
|
+
buffer = lines.pop() || '';
|
|
91
|
+
for (const line of lines) {
|
|
92
|
+
const trimmedLine = line.trim();
|
|
93
|
+
if (!trimmedLine)
|
|
94
|
+
continue; // Skip empty lines
|
|
95
|
+
if (trimmedLine.startsWith('data:')) {
|
|
96
|
+
try {
|
|
97
|
+
const jsonStr = trimmedLine.slice(5).trim();
|
|
98
|
+
if (!jsonStr || jsonStr === '[DONE]')
|
|
99
|
+
continue; // Skip empty or done markers
|
|
100
|
+
const data = JSON.parse(jsonStr);
|
|
101
|
+
// Check for audio data in different possible locations
|
|
102
|
+
if (data.data?.audio) {
|
|
103
|
+
// Audio is in hex format
|
|
104
|
+
const audioHex = data.data.audio;
|
|
105
|
+
const audioBytes = new Uint8Array(audioHex.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16)) || []);
|
|
106
|
+
audioChunks.push(audioBytes);
|
|
107
|
+
}
|
|
108
|
+
else if (data.audio) {
|
|
109
|
+
// Direct audio in data object
|
|
110
|
+
const audioHex = typeof data.audio === 'string' ? data.audio : '';
|
|
111
|
+
if (audioHex) {
|
|
112
|
+
const audioBytes = new Uint8Array(audioHex.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16)) || []);
|
|
113
|
+
audioChunks.push(audioBytes);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
// Skip invalid JSON chunks - might be non-JSON data
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else if (trimmedLine.startsWith('{')) {
|
|
123
|
+
// Try to parse as JSON even without 'data:' prefix
|
|
124
|
+
try {
|
|
125
|
+
const data = JSON.parse(trimmedLine);
|
|
126
|
+
if (data.data?.audio) {
|
|
127
|
+
const audioHex = data.data.audio;
|
|
128
|
+
const audioBytes = new Uint8Array(audioHex.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16)) || []);
|
|
129
|
+
audioChunks.push(audioBytes);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (e) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Process any remaining buffer
|
|
139
|
+
if (buffer.trim()) {
|
|
140
|
+
const trimmedBuffer = buffer.trim();
|
|
141
|
+
if (trimmedBuffer.startsWith('data:')) {
|
|
142
|
+
try {
|
|
143
|
+
const jsonStr = trimmedBuffer.slice(5).trim();
|
|
144
|
+
if (jsonStr) {
|
|
145
|
+
const data = JSON.parse(jsonStr);
|
|
146
|
+
if (data.data?.audio) {
|
|
147
|
+
const audioHex = data.data.audio;
|
|
148
|
+
const audioBytes = new Uint8Array(audioHex.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16)) || []);
|
|
149
|
+
audioChunks.push(audioBytes);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch (e) {
|
|
154
|
+
// Ignore parse errors for remaining buffer
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
finally {
|
|
160
|
+
reader.releaseLock();
|
|
161
|
+
}
|
|
162
|
+
if (audioChunks.length === 0) {
|
|
163
|
+
throw new Error('No audio data received from MiniMax TTS. Check if the API response format matches expectations.');
|
|
164
|
+
}
|
|
165
|
+
// Combine all audio chunks into a single ArrayBuffer
|
|
166
|
+
const totalLength = audioChunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
167
|
+
const audioData = new ArrayBuffer(totalLength);
|
|
168
|
+
const audioView = new Uint8Array(audioData);
|
|
169
|
+
let offset = 0;
|
|
170
|
+
for (const chunk of audioChunks) {
|
|
171
|
+
audioView.set(chunk, offset);
|
|
172
|
+
offset += chunk.length;
|
|
173
|
+
}
|
|
174
|
+
const contentType = options?.format === 'wav' ? 'audio/wav' :
|
|
175
|
+
options?.format === 'flac' ? 'audio/flac' :
|
|
176
|
+
options?.format === 'opus' ? 'audio/opus' :
|
|
177
|
+
options?.format === 'aac' ? 'audio/aac' :
|
|
178
|
+
'audio/mpeg';
|
|
179
|
+
return { audioData, contentType };
|
|
180
|
+
}
|
|
181
|
+
getTTSInstance(model, credentials, options) {
|
|
182
|
+
const merged = mergeCredentials(credentials, options?.modelProperties);
|
|
183
|
+
return {
|
|
184
|
+
model,
|
|
185
|
+
synthesizeSpeech: (text, ttsOptions) => this.synthesizeSpeech(model, text, merged, ttsOptions)
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
async validateCredentials(model, credentials) {
|
|
189
|
+
if (!model || !SUPPORTED_TTS_MODELS.includes(model)) {
|
|
190
|
+
throw new CredentialsValidateFailedError(`TTS model ${model} is not supported`);
|
|
191
|
+
}
|
|
192
|
+
if (!credentials.api_key) {
|
|
193
|
+
throw new CredentialsValidateFailedError('API key is required');
|
|
194
|
+
}
|
|
195
|
+
if (!credentials.group_id) {
|
|
196
|
+
throw new CredentialsValidateFailedError('Group ID is required');
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
static getSupportedModels() {
|
|
200
|
+
return SUPPORTED_TTS_MODELS;
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
MiniMaxTTSModel = __decorate([
|
|
204
|
+
Injectable(),
|
|
205
|
+
__metadata("design:paramtypes", [MiniMaxProviderStrategy])
|
|
206
|
+
], MiniMaxTTSModel);
|
|
207
|
+
export { MiniMaxTTSModel };
|