@@ -29,7 +29,6 @@ import toast from 'react-hot-toast';
2929import { useParams } from 'next/navigation' ;
3030
3131import { useConfig } from '@/contexts/ConfigContext' ;
32- import { audioBufferToURL } from '@/utils/audio' ;
3332import { useAudioCache } from '@/hooks/audio/useAudioCache' ;
3433import { useVoiceManagement } from '@/hooks/audio/useVoiceManagement' ;
3534import { useMediaSession } from '@/hooks/audio/useMediaSession' ;
@@ -488,7 +487,13 @@ export function TTSProvider({ children }: { children: ReactNode }) {
488487 const processPromise = ( async ( ) => {
489488 try {
490489 const audioBuffer = await getAudio ( sentence ) ;
491- return audioBufferToURL ( audioBuffer ! ) ;
490+ if ( ! audioBuffer ) throw new Error ( 'No audio data generated' ) ;
491+
492+ // Convert to base64 data URI
493+ const bytes = new Uint8Array ( audioBuffer ) ;
494+ const binaryString = bytes . reduce ( ( acc , byte ) => acc + String . fromCharCode ( byte ) , '' ) ;
495+ const base64String = btoa ( binaryString ) ;
496+ return `data:audio/mp3;base64,${ base64String } ` ;
492497 } catch ( error ) {
493498 setIsProcessing ( false ) ;
494499 throw error ;
@@ -520,9 +525,10 @@ export function TTSProvider({ children }: { children: ReactNode }) {
520525 }
521526
522527 try {
523- const audioUrl = await processSentence ( sentence ) ;
524- if ( ! audioUrl ) {
525- throw new Error ( 'No audio URL generated' ) ;
528+ // Get the processed audio data URI directly from processSentence
529+ const audioDataUri = await processSentence ( sentence ) ;
530+ if ( ! audioDataUri ) {
531+ throw new Error ( 'No audio data generated' ) ;
526532 }
527533
528534 // Force unload any previous Howl instance to free up resources
@@ -531,7 +537,7 @@ export function TTSProvider({ children }: { children: ReactNode }) {
531537 }
532538
533539 const howl = new Howl ( {
534- src : [ audioUrl ] ,
540+ src : [ audioDataUri ] ,
535541 format : [ 'mp3' ] ,
536542 html5 : true ,
537543 preload : true ,
@@ -548,7 +554,6 @@ export function TTSProvider({ children }: { children: ReactNode }) {
548554 }
549555 } ,
550556 onend : ( ) => {
551- URL . revokeObjectURL ( audioUrl ) ;
552557 howl . unload ( ) ;
553558 setActiveHowl ( null ) ;
554559 if ( isPlaying ) {
@@ -559,13 +564,11 @@ export function TTSProvider({ children }: { children: ReactNode }) {
559564 console . warn ( 'Error loading audio:' , error ) ;
560565 setIsProcessing ( false ) ;
561566 setActiveHowl ( null ) ;
562- URL . revokeObjectURL ( audioUrl ) ;
563567 howl . unload ( ) ;
564568 setIsPlaying ( false ) ;
565569 } ,
566570 onstop : ( ) => {
567571 setIsProcessing ( false ) ;
568- URL . revokeObjectURL ( audioUrl ) ;
569572 howl . unload ( ) ;
570573 }
571574 } ) ;
@@ -590,7 +593,7 @@ export function TTSProvider({ children }: { children: ReactNode }) {
590593 advance ( ) ;
591594 return null ;
592595 }
593- } , [ isPlaying , processSentence , advance , activeHowl ] ) ;
596+ } , [ isPlaying , advance , activeHowl , processSentence ] ) ;
594597
595598 const playAudio = useCallback ( async ( ) => {
596599 const howl = await playSentenceWithHowl ( sentences [ currentIndex ] ) ;
0 commit comments