Skip to content

Commit e430be0

Browse files
committed
improve: streamline voice fetching and URL building in FlowerySource
1 parent a9de0be commit e430be0

File tree

1 file changed

+46
-109
lines changed

1 file changed

+46
-109
lines changed

src/sources/flowery.js

Lines changed: 46 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ export default class FlowerySource {
99
this.searchTerms = ['ftts', 'flowery']
1010
this.patterns = [/^ftts:\/\//]
1111
this.priority = 50
12-
this.voiceMap = new Map() // Stores voiceName -> voiceId mapping
13-
this.defaultVoiceId = null // Stores the ID of the default voice
12+
this.voiceMap = new Map()
13+
this.defaultVoiceId = null
1414
}
1515

1616
async setup() {
@@ -25,18 +25,12 @@ export default class FlowerySource {
2525
if (cachedVoices) {
2626
this.voiceMap = new Map(Object.entries(cachedVoices.voiceMap))
2727
this.defaultVoiceId = cachedVoices.defaultVoiceId
28-
logger(
29-
'debug',
30-
'Flowery',
31-
`Loaded ${this.voiceMap.size} voices from CredentialManager.`
32-
)
28+
logger('debug', 'Flowery', `Loaded ${this.voiceMap.size} voices from CredentialManager.`)
3329
return
3430
}
3531

3632
const voicesEndpoint = 'https://api.flowery.pw/v1/tts/voices'
37-
const { body, error, statusCode } = await makeRequest(voicesEndpoint, {
38-
method: 'GET'
39-
})
33+
const { body, error, statusCode } = await makeRequest(voicesEndpoint, { method: 'GET' })
4034

4135
if (error || statusCode !== 200 || !body || !Array.isArray(body.voices)) {
4236
logger(
@@ -49,23 +43,15 @@ export default class FlowerySource {
4943

5044
this.voiceMap.clear()
5145
for (const voice of body.voices) {
52-
this.voiceMap.set(voice.name.toLowerCase(), voice.id)
46+
this.voiceMap.set(String(voice.name).toLowerCase(), voice.id)
5347
}
5448

5549
if (body.default?.id) {
5650
this.defaultVoiceId = body.default.id
57-
logger(
58-
'info',
59-
'Flowery',
60-
`Default voice set to: ${body.default.name} (${body.default.id})`
61-
)
51+
logger('info', 'Flowery', `Default voice set to: ${body.default.name} (${body.default.id})`)
6252
} else if (body.voices.length > 0) {
6353
this.defaultVoiceId = body.voices[0].id
64-
logger(
65-
'info',
66-
'Flowery',
67-
`Using first available voice as default: ${body.voices[0].name} (${body.voices[0].id})`
68-
)
54+
logger('info', 'Flowery', `Using first available voice as default: ${body.voices[0].name} (${body.voices[0].id})`)
6955
}
7056

7157
this.nodelink.credentialManager.set(
@@ -84,9 +70,7 @@ export default class FlowerySource {
8470
}
8571

8672
async search(query) {
87-
if (!query) {
88-
return { loadType: 'empty', data: {} }
89-
}
73+
if (!query) return { loadType: 'empty', data: {} }
9074

9175
try {
9276
const url = this._buildUrl(query)
@@ -97,14 +81,9 @@ export default class FlowerySource {
9781
identifier: `ftts:${query}`
9882
})
9983

100-
return {
101-
loadType: 'track',
102-
data: track
103-
}
84+
return { loadType: 'track', data: track }
10485
} catch (e) {
105-
return {
106-
exception: { message: e.message, severity: 'fault', cause: 'Exception' }
107-
}
86+
return { exception: { message: e.message, severity: 'fault', cause: 'Exception' } }
10887
}
10988
}
11089

@@ -144,9 +123,7 @@ export default class FlowerySource {
144123

145124
return { loadType: 'track', data: track }
146125
} catch (e) {
147-
return {
148-
exception: { message: e.message, severity: 'fault', cause: 'Exception' }
149-
}
126+
return { exception: { message: e.message, severity: 'fault', cause: 'Exception' } }
150127
}
151128
}
152129

@@ -166,46 +143,20 @@ export default class FlowerySource {
166143
if (overrides.speed !== undefined) speed = overrides.speed
167144
}
168145

169-
let voiceId =
170-
this.voiceMap.get(voiceName.toLowerCase()) || this.defaultVoiceId
146+
let voiceId = this.voiceMap.get(String(voiceName).toLowerCase()) || this.defaultVoiceId
171147

172148
if (!voiceId) {
173-
logger(
174-
'warn',
175-
'Flowery',
176-
`Voice "${voiceName}" not found and no default voice available. Using a fallback empty voice ID.`
177-
)
178-
voiceId = 'default' // Fallback to a generic 'default' if no ID is found
179-
}
180-
181-
let audioFormat = 'mp3'
182-
const quality = this.nodelink.options.audio?.quality || 'high'
183-
184-
switch (quality) {
185-
case 'high':
186-
audioFormat = 'wav'
187-
break
188-
case 'medium':
189-
audioFormat = 'flac'
190-
break
191-
case 'low':
192-
audioFormat = 'ogg_opus'
193-
break
194-
case 'lowest':
195-
audioFormat = 'mp3'
196-
break
197-
default:
198-
audioFormat = 'wav'
199-
break
149+
logger('warn', 'Flowery', `Voice "${voiceName}" not found and no default voice available. Using fallback voice ID.`)
150+
voiceId = 'default'
200151
}
201152

202153
const baseUrl = 'https://api.flowery.pw/v1/tts'
203154
const queryParams = new URLSearchParams({
204-
voice: voiceId,
205-
text,
155+
voice: String(voiceId),
156+
text: String(text),
206157
translate: String(translate),
207158
silence: String(silence),
208-
audio_format: audioFormat,
159+
audio_format: 'mp3',
209160
speed: String(speed)
210161
})
211162

@@ -227,11 +178,7 @@ export default class FlowerySource {
227178
sourceName: 'flowery'
228179
}
229180

230-
return {
231-
encoded: encodeTrack(track),
232-
info: track,
233-
pluginInfo: {}
234-
}
181+
return { encoded: encodeTrack(track), info: track, pluginInfo: {} }
235182
}
236183

237184
async getTrackUrl(track, itag, forceRefresh = false) {
@@ -240,47 +187,47 @@ export default class FlowerySource {
240187
if (cached) return cached
241188
}
242189

243-
let format = 'mp3'
190+
const normalized = this._forceMp3Url(track.uri)
191+
244192
try {
245-
const urlObj = new URL(track.uri)
246-
const audioFormat = urlObj.searchParams.get('audio_format')
247-
if (audioFormat) {
248-
if (audioFormat === 'wav') format = 'wav'
249-
else if (audioFormat === 'flac') format = 'flac'
250-
else if (audioFormat === 'ogg_opus') format = 'opus'
251-
else if (audioFormat === 'mp3') format = 'mp3'
252-
}
253-
} catch (_e) {
193+
this.nodelink.trackCacheManager.set('flowery', track.identifier, normalized)
194+
} catch {
254195
// ignore
255196
}
256197

257-
return {
258-
url: track.uri,
259-
protocol: 'https',
260-
format
198+
return normalized
199+
}
200+
201+
_forceMp3Url(uri) {
202+
const out = { url: uri, protocol: 'https', format: 'mp3' }
203+
204+
try {
205+
const urlObj = new URL(uri)
206+
urlObj.searchParams.set('audio_format', 'mp3')
207+
out.url = urlObj.toString()
208+
return out
209+
} catch {
210+
return out
261211
}
262212
}
263213

264214
async loadStream(decodedTrack, url, _protocol, _additionalData) {
265-
logger(
266-
'debug',
267-
'Sources',
268-
`Loading Flowery TTS stream for "${decodedTrack.title}"`
269-
)
215+
logger('debug', 'Sources', `Loading Flowery TTS stream for "${decodedTrack.title}"`)
216+
217+
const finalUrl = this._forceMp3Url(url).url
218+
270219
try {
271-
const response = await makeRequest(url, {
220+
const response = await makeRequest(finalUrl, {
272221
method: 'GET',
273222
streamOnly: true,
274223
headers: {
275-
'User-Agent': 'NodeLink/FloweryTTS'
224+
'User-Agent': 'NodeLink/FloweryTTS',
225+
Accept: '*/*'
276226
}
277227
})
278228

279229
if (response.error || !response.stream) {
280-
throw (
281-
response.error ||
282-
new Error('Failed to get stream, no stream object returned.')
283-
)
230+
throw (response.error || new Error('Failed to get stream, no stream object returned.'))
284231
}
285232

286233
const stream = new PassThrough()
@@ -292,24 +239,14 @@ export default class FlowerySource {
292239

293240
response.stream.on('error', (err) => {
294241
logger('error', 'Sources', `Flowery TTS stream error: ${err.message}`)
295-
if (!stream.destroyed) {
296-
stream.destroy(err)
297-
}
242+
if (!stream.destroyed) stream.destroy(err)
298243
})
299244

300245
return { stream }
301246
} catch (err) {
302-
logger(
303-
'error',
304-
'Sources',
305-
`Failed to load Flowery TTS stream: ${err.message}`
306-
)
247+
logger('error', 'Sources', `Failed to load Flowery TTS stream: ${err.message}`)
307248
return {
308-
exception: {
309-
message: err.message,
310-
severity: 'common',
311-
cause: 'Upstream'
312-
}
249+
exception: { message: err.message, severity: 'common', cause: 'Upstream' }
313250
}
314251
}
315252
}

0 commit comments

Comments
 (0)