z-astro-web-audio-stream
v1.4.0
Published
Astro integration for Web Audio Stream with separated download/storage optimization and automatic worklet deployment
Maintainers
Readme
z-astro-z-web-audio-stream
Astro integration for Web Audio Stream with automatic worklet deployment.
🍎 What This Fixes
This integration automatically sets up iOS Safari-safe audio streaming that fixes:
- Sample Rate Mismatches - High-pitched/fast audio playback
- Memory Pressure - Page reloads from large audio files
- IndexedDB Failures - Safari connection issues
- Broken AudioContext - iOS-specific Web Audio bugs
📦 Installation
npm install z-astro-z-web-audio-stream z-web-audio-stream
# or
pnpm add z-astro-z-web-audio-stream z-web-audio-stream🚀 Setup
Add the integration to your astro.config.mjs:
import { defineConfig } from 'astro/config';
import webAudioStream from 'z-astro-z-web-audio-stream';
export default defineConfig({
integrations: [
webAudioStream({
// Optional configuration
workletPath: '/audio-worklet-processor.js',
publicDir: 'public',
autoDeploy: true,
verbose: true
})
]
});⚙️ Configuration
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| workletPath | string | '/audio-worklet-processor.js' | URL path where worklet will be served |
| publicDir | string | 'public' | Public directory relative to project root |
| autoDeploy | boolean | true | Automatically copy worklet during build |
| verbose | boolean | true | Log deployment information |
🎵 Usage in Components
Astro Component
---
// src/components/AudioPlayer.astro
---
<div id="audio-player">
<button id="play-btn">Play</button>
<button id="pause-btn">Pause</button>
</div>
<script>
import { setupWebAudio } from 'z-web-audio-stream';
// Initialize with iOS-safe defaults
const manager = await setupWebAudio({
workletPath: '/audio-worklet-processor.js', // Automatically deployed!
onTimeUpdate: (currentTime, duration) => {
console.log(`Playing: ${currentTime}s / ${duration}s`);
},
onEnded: () => {
console.log('Playback finished');
}
});
// Control buttons
document.getElementById('play-btn')?.addEventListener('click', async () => {
await manager.loadAndPlay('/audio/song.mp3', 'song-1', 'My Song');
});
document.getElementById('pause-btn')?.addEventListener('click', async () => {
await manager.pause();
});
</script>React Component (in Astro)
// src/components/ReactAudioPlayer.tsx
import { useEffect, useState } from 'react';
import { setupWebAudio, type WebAudioManager } from 'z-web-audio-stream';
export default function ReactAudioPlayer() {
const [manager, setManager] = useState<WebAudioManager | null>(null);
const [isPlaying, setIsPlaying] = useState(false);
const [currentTime, setCurrentTime] = useState(0);
const [duration, setDuration] = useState(0);
useEffect(() => {
setupWebAudio({
workletPath: '/audio-worklet-processor.js', // Auto-deployed by integration
onTimeUpdate: (time, dur) => {
setCurrentTime(time);
setDuration(dur);
},
onEnded: () => {
setIsPlaying(false);
}
}).then(setManager);
return () => {
manager?.cleanup();
};
}, []);
const handlePlay = async () => {
if (!manager) return;
await manager.loadAndPlay('/audio/song.mp3', 'song-1', 'My Song');
setIsPlaying(true);
};
const handlePause = async () => {
if (!manager) return;
await manager.pause();
setIsPlaying(false);
};
return (
<div className="audio-player">
<button onClick={isPlaying ? handlePause : handlePlay}>
{isPlaying ? 'Pause' : 'Play'}
</button>
{duration > 0 && (
<div className="progress">
<div
className="progress-bar"
style={{ width: `${(currentTime / duration) * 100}%` }}
/>
</div>
)}
<span>{Math.floor(currentTime)}s / {Math.floor(duration)}s</span>
</div>
);
}🏗️ Build Process
During build, the integration:
- ✅ Finds the iOS-safe audio worklet processor
- ✅ Copies it to your public directory
- ✅ Configures the correct path automatically
- ✅ Logs deployment status (if verbose enabled)
Build Output:
🎵 Web Audio Stream integration loaded
🍎 iOS Safari audio fixes will be applied automatically
✅ Audio worklet deployed to: /path/to/public/audio-worklet-processor.js
🔧 Use in your app: setupWebAudio({ workletPath: "/audio-worklet-processor.js" })🔧 Manual Deployment
If you prefer manual control:
// astro.config.mjs
export default defineConfig({
integrations: [
webAudioStream({
autoDeploy: false // Disable automatic deployment
})
]
});Then deploy manually:
npx z-web-audio-stream-cli deploy🍎 iOS Safari Benefits
This integration ensures your Astro site works perfectly on iOS Safari:
- ✅ No High-Pitched Audio - Sample rate monitoring and correction
- ✅ No Page Reloads - Memory-safe 1-2MB chunks on iOS
- ✅ Reliable Caching - IndexedDB retry logic for Safari
- ✅ Instant Playback - Progressive loading with first chunk
- ✅ Zero Configuration - Works out of the box
📱 Mobile-First Examples
Progressive Loading with Preloading
<script>
import { setupWebAudio } from 'z-web-audio-stream';
const manager = await setupWebAudio();
// Preload next tracks for seamless transitions
await manager.preloadAudio('/audio/song1.mp3', 'song-1', 'Song 1');
await manager.preloadAudio('/audio/song2.mp3', 'song-2', 'Song 2');
// Play immediately (loads from cache)
await manager.loadAndPlay('/audio/song1.mp3', 'song-1', 'Song 1');
</script>Playlist with iOS Optimizations
function Playlist({ songs }) {
const [manager, setManager] = useState<WebAudioManager | null>(null);
const [currentSong, setCurrentSong] = useState(0);
useEffect(() => {
setupWebAudio({
onEnded: () => {
// Auto-advance to next song
setCurrentSong(prev => (prev + 1) % songs.length);
}
}).then(async (audioManager) => {
setManager(audioManager);
// Preload all songs for iOS-safe smooth playback
for (const song of songs) {
await audioManager.preloadAudio(song.url, song.id, song.name);
}
});
}, [songs]);
const playSong = async (index: number) => {
if (!manager) return;
const song = songs[index];
await manager.loadAndPlay(song.url, song.id, song.name);
setCurrentSong(index);
};
return (
<div className="playlist">
{songs.map((song, index) => (
<button
key={song.id}
onClick={() => playSong(index)}
className={currentSong === index ? 'active' : ''}
>
{song.name}
</button>
))}
</div>
);
}🔍 Troubleshooting
Integration not found
npm install z-astro-z-web-audio-streamWorklet file not deployed
- Check that
autoDeploy: true(default) - Verify
z-web-audio-streamis installed - Check build logs for error messages
iOS audio still has issues
- Ensure you're using the deployed worklet path
- Check browser console for iOS-specific logs
- Verify the integration ran during build
📄 License
MIT License - Part of the Web Audio Stream package suite.
