mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-22 19:58:05 +00:00
8.1 KiB
8.1 KiB
Voice Message Playback - Web Speech API Integration
✅ Implementation Complete
Voice messages in the phone-chat minigame can now be clicked to play using the Web Speech API!
What Was Added
1. Speech Synthesis Setup (phone-chat-ui.js constructor)
// Speech synthesis setup for voice messages
this.speechSynthesis = window.speechSynthesis;
this.currentUtterance = null;
this.isPlaying = false;
this.speechAvailable = !!this.speechSynthesis;
this.selectedVoice = null;
this.voiceSettings = {
rate: 0.9,
pitch: 1.0,
volume: 0.8
};
// Setup voice selection
if (this.speechAvailable) {
this.setupVoiceSelection();
}
2. Voice Selection Methods
setupVoiceSelection()
- Waits for voices to load (async on Chrome)
- Handles
voiceschangedevent - Fallback delay for delayed voice loading
selectBestVoice()
- Prefers natural-sounding voices:
- Google UK/US English
- Microsoft voices (Zira, David, etc.)
- Falls back to first English voice
- Logs selected voice for debugging
3. Playback Methods
playVoiceMessage(text, playButton)
- Checks speech availability
- Toggles play/stop on repeated clicks
- Creates
SpeechSynthesisUtterancewith text - Configures rate, pitch, volume
- Sets selected voice
- Updates button on start/end/error
- Handles errors gracefully
stopVoiceMessage(playButton)
- Cancels current speech synthesis
- Updates button to play state
updatePlayButton(playButton, playing)
- Playing: Shows black square (stop icon)
- Not playing: Shows play.png icon
- Updates title attribute for tooltips
4. UI Integration
In addMessage() method:
// Add click handler to audio controls
audioControls.addEventListener('click', () => {
this.playVoiceMessage(transcript, playButton);
});
// Make cursor pointer to indicate clickability
audioControls.style.cursor = 'pointer';
5. Cleanup
In cleanup() method:
// Stop any playing voice messages
if (this.speechSynthesis && this.isPlaying) {
this.speechSynthesis.cancel();
this.isPlaying = false;
}
How It Works
User Flow
- User opens phone-chat minigame
- Sees voice message with play button + waveform
- Clicks audio controls → Voice starts playing
- Play button changes to stop square
- Clicks again → Voice stops
- Button returns to play icon
Technical Flow
Click Audio Controls
↓
playVoiceMessage(text, playButton)
↓
Create SpeechSynthesisUtterance
↓
Configure voice settings
↓
speechSynthesis.speak(utterance)
↓
Update button (play → stop)
↓
On end: Update button (stop → play)
Voice Selection Priority
The system tries voices in this order:
- Google UK English Female (best quality)
- Google UK English Male
- Google US English
- Microsoft Zira Desktop
- Microsoft David Desktop
- Any voice with
en-USoren-GB - First available English voice (fallback)
Visual Indicators
Play State (Default)
┌─────────────────────────────────┐
│ ▶ ~~~~~~~~~~~~~~~~~~~ │ ← Play icon
│ │
│ 📄 Transcript: Message text... │
└─────────────────────────────────┘
Cursor: pointer
Title: "Play"
Playing State
┌─────────────────────────────────┐
│ ■ ~~~~~~~~~~~~~~~~~~~ │ ← Stop square
│ │
│ 📄 Transcript: Message text... │
└─────────────────────────────────┘
Cursor: pointer
Title: "Stop"
Voice Settings
Default configuration:
- Rate: 0.9 (slightly slower than normal)
- Pitch: 1.0 (normal pitch)
- Volume: 0.8 (80% volume)
These match the original phone-messages minigame for consistency.
Error Handling
Speech Not Available
if (!this.speechAvailable) {
console.warn('🎤 Speech synthesis not available');
return;
}
- Gracefully fails if Web Speech API not supported
- No visual error (transcript still readable)
- Logs warning to console
Speech Synthesis Error
this.currentUtterance.onerror = (event) => {
console.error('🎤 Speech synthesis error:', event);
this.isPlaying = false;
this.updatePlayButton(playButton, false);
};
- Common on Linux systems (synthesis-failed)
- Resets button to play state
- User can still read transcript
Browser Compatibility
✅ Fully Supported
- Chrome/Chromium: Excellent voice quality
- Edge: Microsoft voices available
- Safari: Good support on macOS/iOS
- Firefox: Basic support
⚠️ Limited Support
- Linux Chrome: Often fails with "synthesis-failed"
- Transcript still visible
- No blocking errors
❌ Not Supported
- Very old browsers (pre-2015)
- Falls back gracefully (no playback, transcript readable)
Testing
Manual Test Steps
- Open
test-phone-chat-minigame.html - Click "Initialize Systems"
- Click "Register Test NPCs"
- Click "📱 Open Phone"
- Open "IT Team" contact (voice message)
- Click the audio controls
- Expected: Voice plays "Hi, this is the IT Team..."
- Click again: Voice stops
- Open "David - Tech Support"
- Choose "Tell me more"
- Click audio controls on voice response
- Expected: Voice plays code message
Console Output
🎤 Initial voices count: 0
🎤 Voices changed, count: 47
🎤 Available voices: [array of voice names]
🎤 Selected voice: Google UK English Female
🎤 Added voice message: Hi, this is the IT Team...
🎤 Playing voice message
🎤 Stopped voice message
Differences from Original Phone Minigame
Same
- ✅ Uses Web Speech API
- ✅ Voice selection logic
- ✅ Rate/pitch/volume settings
- ✅ Error handling
- ✅ Play/stop toggle behavior
Different
- ✅ Integrated into conversation view (not separate detail view)
- ✅ Multiple voice messages can exist in same conversation
- ✅ Play button uses square for stop (no stop.png asset)
- ✅ Cleaner integration with message bubbles
- ✅ Works with Ink stories (not just phone objects)
Future Enhancements
Possible Improvements
-
Visual Feedback
- Animate waveform during playback
- Add progress indicator
- Highlight currently speaking text
-
Voice Selection UI
- Let user choose voice from dropdown
- Remember voice preference
- Per-NPC voice assignment
-
Playback Controls
- Speed control (0.5x, 1x, 1.5x, 2x)
- Pause/resume (currently only play/stop)
- Skip forward/backward
-
Accessibility
- Keyboard shortcuts (Space to play/stop)
- Screen reader announcements
- ARIA labels
Code Locations
Files Modified
js/minigames/phone-chat/phone-chat-ui.js- Constructor: Speech synthesis setup
setupVoiceSelection(): Voice loadingselectBestVoice(): Voice selection logicplayVoiceMessage(): Main playback methodstopVoiceMessage(): Stop playbackupdatePlayButton(): Visual feedbackaddMessage(): Click handler integrationcleanup(): Stop on close
Assets Required
- ✅
assets/icons/play.png(exists) - ✅
assets/mini-games/audio.png(exists) - ❌
assets/icons/stop.png(not needed - using square div)
Summary
Question: How do I make voice messages clickable to play?
Answer: Just click the audio controls! 🎤
Features
- ✅ Click to play/stop voice messages
- ✅ Uses Web Speech API (built-in browser TTS)
- ✅ Automatic voice selection (best quality)
- ✅ Visual feedback (play ↔ stop button)
- ✅ Graceful error handling
- ✅ Cleanup on close
Usage
- Voice message appears with play button
- Click audio controls → Voice plays
- Click again → Voice stops
- Transcript always visible (fallback)
It just works! 🔊
Version: 1.0
Date: 2025-10-30
Status: Complete & Tested
Based On: js/minigames/phone/phone-messages-minigame.js