{#if $voiceStore.transcript}
Transcript:
{$voiceStore.transcript}
{/if}
{#if $voiceStore.error}
{$voiceStore.error}
{/if}
{#if $voiceStore.permissionDenied}
Microphone access denied
{/if}
```
### Browser Permissions
Voice input requires microphone permissions. Handle permission flow:
```typescript
// Check permission before recording
if ($voiceStore.permissionDenied) {
// Show permission request UI
alert('Please grant microphone access to use voice input');
}
```
---
## AUDIO MANAGER
**Purpose**: Low-level audio management for custom implementations.
### API
```typescript
import {
AudioManager,
createAudioManager,
getAudioManager,
deleteAudioManager
} from '@composable-svelte/media';
// Create manager
const manager = createAudioManager({
id: 'my-player',
onTimeUpdate: (time) => console.log('Time:', time),
onEnded: () => console.log('Ended'),
onError: (error) => console.error('Error:', error)
});
// Load and play
await manager.load('/audio/track.mp3');
manager.play();
// Get existing manager
const existing = getAudioManager('my-player');
// Cleanup
deleteAudioManager('my-player');
```
---
## COMPONENT SELECTION GUIDE
**When to use each component**:
**AudioPlayer**:
- Music streaming apps
- Podcast players
- Audio courses
- Meditation apps
- Need playlist management
**VideoEmbed**:
- Blog posts with videos
- Video galleries
- Educational content
- Marketing pages
- Platform-agnostic video
**VoiceInput**:
- Voice commands
- Audio messages
- Voice notes
- Transcription apps
- Accessibility features
---
## CROSS-REFERENCES
**Related Skills**:
- **composable-svelte-core**: Store, reducer, Effect system
- **composable-svelte-chat**: StreamingChat (can integrate with VoiceInput)
- **composable-svelte-code**: CodeEditor, syntax highlighting
- **composable-svelte-components**: UI components (Button, Input, etc.)
**When to Use Each Package**:
- **media**: Audio players, video embeds, voice input
- **chat**: Real-time chat, streaming responses
- **code**: Code editors, syntax highlighting, visual programming
- **graphics**: 3D scenes, WebGPU/WebGL rendering
- **charts**: 2D data visualization
---
## TESTING PATTERNS
### AudioPlayer Testing
```typescript
import { TestStore } from '@composable-svelte/core';
import { audioPlayerReducer, createInitialAudioPlayerState } from '@composable-svelte/media';
const store = new TestStore({
initialState: createInitialAudioPlayerState({
tracks: [
{ id: '1', title: 'Track 1', url: '/audio/1.mp3', duration: 180 }
]
}),
reducer: audioPlayerReducer,
dependencies: {}
});
// Test play
await store.send({ type: 'play' }, (state) => {
expect(state.isPlaying).toBe(true);
});
// Test track change
await store.send({ type: 'nextTrack' }, (state) => {
expect(state.currentTrackIndex).toBe(1);
});
```
### VoiceInput Testing
```typescript
import { TestStore } from '@composable-svelte/core';
import { voiceInputReducer, createInitialVoiceInputState } from '@composable-svelte/media';
const store = new TestStore({
initialState: createInitialVoiceInputState(),
reducer: voiceInputReducer,
dependencies: {
onAudioData: vi.fn((blob) => Promise.resolve('Test transcript'))
}
});
// Test recording start
await store.send({ type: 'startRecording' });
await store.receive({ type: 'recordingStarted' }, (state) => {
expect(state.isRecording).toBe(true);
});
```
---
## TROUBLESHOOTING
**AudioPlayer not playing**:
- Check audio URL is accessible
- Verify browser autoplay policy (may require user interaction)
- Ensure audio format is supported (mp3, wav, ogg recommended)
**VideoEmbed not loading**:
- Verify URL format matches platform requirements
- Check platform embed permissions (some require API keys)
- Ensure platform allows embedding (some videos are restricted)
**VoiceInput permission denied**:
- User must grant microphone access
- HTTPS required (except localhost)
- Check browser compatibility (MediaRecorder API)