@@ -20,6 +20,7 @@ import { SpineItem } from 'epubjs/types/section';
2020import { useParams } from 'next/navigation' ;
2121import { useConfig } from './ConfigContext' ;
2222import { combineAudioChunks } from '@/utils/audio' ;
23+ import { withRetry } from '@/utils/audio' ;
2324
2425interface EPUBContextType {
2526 currDocData : ArrayBuffer | undefined ;
@@ -202,15 +203,14 @@ export function EPUBProvider({ children }: { children: ReactNode }) {
202203
203204 // Get TOC for chapter titles
204205 const chapters = tocRef . current || [ ] ;
205- console . log ( 'Chapter map :' , chapters ) ;
206+ console . log ( 'Chapters :' , chapters ) ;
206207
207208 // Create a map of section hrefs to their chapter titles
208209 const sectionTitleMap = new Map < string , string > ( ) ;
209210
210211 // First, loop through all chapters to create the mapping
211212 for ( const chapter of chapters ) {
212213 if ( ! chapter . href ) continue ;
213-
214214 const chapterBaseHref = chapter . href . split ( '#' ) [ 0 ] ;
215215 const chapterTitle = chapter . label . trim ( ) ;
216216
@@ -240,29 +240,40 @@ export function EPUBProvider({ children }: { children: ReactNode }) {
240240 if ( ! trimmedText ) continue ;
241241
242242 try {
243- const ttsResponse = await fetch ( '/api/tts' , {
244- method : 'POST' ,
245- headers : {
246- 'x-openai-key' : apiKey ,
247- 'x-openai-base-url' : baseUrl ,
243+ const audioBuffer = await withRetry (
244+ async ( ) => {
245+ const ttsResponse = await fetch ( '/api/tts' , {
246+ method : 'POST' ,
247+ headers : {
248+ 'x-openai-key' : apiKey ,
249+ 'x-openai-base-url' : baseUrl ,
250+ } ,
251+ body : JSON . stringify ( {
252+ text : trimmedText ,
253+ voice : voice ,
254+ speed : voiceSpeed ,
255+ format : format === 'm4b' ? 'aac' : 'mp3' ,
256+ } ) ,
257+ signal
258+ } ) ;
259+
260+ if ( ! ttsResponse . ok ) {
261+ throw new Error ( `TTS processing failed with status ${ ttsResponse . status } ` ) ;
262+ }
263+
264+ const buffer = await ttsResponse . arrayBuffer ( ) ;
265+ if ( buffer . byteLength === 0 ) {
266+ throw new Error ( 'Received empty audio buffer from TTS' ) ;
267+ }
268+ return buffer ;
248269 } ,
249- body : JSON . stringify ( {
250- text : trimmedText ,
251- voice : voice ,
252- speed : voiceSpeed ,
253- format : format === 'm4b' ? 'aac' : 'mp3' ,
254- } ) ,
255- signal
256- } ) ;
257-
258- if ( ! ttsResponse . ok ) {
259- throw new Error ( `TTS processing failed with status ${ ttsResponse . status } ` ) ;
260- }
261-
262- const audioBuffer = await ttsResponse . arrayBuffer ( ) ;
263- if ( audioBuffer . byteLength === 0 ) {
264- throw new Error ( 'Received empty audio buffer from TTS' ) ;
265- }
270+ {
271+ maxRetries : 2 ,
272+ initialDelay : 5000 ,
273+ maxDelay : 10000 ,
274+ backoffFactor : 2
275+ }
276+ ) ;
266277
267278 // Get the chapter title from our pre-computed map
268279 let chapterTitle = sectionTitleMap . get ( section . href ) ;
0 commit comments