Skip to content

Commit 4e07e73

Browse files
committed
Stop using audio blobs
1 parent 4aaa744 commit 4e07e73

File tree

3 files changed

+14
-21
lines changed

3 files changed

+14
-21
lines changed

.github/workflows/playwright.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
NEXT_PUBLIC_NODE_ENV: test
2323
API_BASE: https://tts.richardr.dev/v1
2424
API_KEY: not-needed
25-
run: npx playwright test --reporter=github,html
25+
run: npx playwright test --reporter=list,github,html
2626
- uses: actions/upload-artifact@v4
2727
if: ${{ !cancelled() }}
2828
with:

src/contexts/TTSContext.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import toast from 'react-hot-toast';
2929
import { useParams } from 'next/navigation';
3030

3131
import { useConfig } from '@/contexts/ConfigContext';
32-
import { audioBufferToURL } from '@/utils/audio';
3332
import { useAudioCache } from '@/hooks/audio/useAudioCache';
3433
import { useVoiceManagement } from '@/hooks/audio/useVoiceManagement';
3534
import { 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]);

src/utils/audio.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,6 @@ interface AudioChunk {
88
startTime: number;
99
}
1010

11-
/**
12-
* Creates a URL from an ArrayBuffer containing MP3 audio data
13-
* @param buffer The ArrayBuffer containing MP3 audio data
14-
* @returns A blob URL that can be used for audio playback
15-
*/
16-
export const audioBufferToURL = (buffer: ArrayBuffer): string => {
17-
const blob = new Blob([buffer], { type: 'audio/mp3' });
18-
return URL.createObjectURL(blob);
19-
};
20-
2111
/**
2212
* Combines audio chunks into a single audio file
2313
* @param audioChunks Array of audio chunks with metadata

0 commit comments

Comments
 (0)