A React Native/Expo audio streaming app for the ShoutingFire Icecast2 radio station. The app provides a complete radio listening experience with live chat and schedule integration.
- Live Audio Streaming - Streams from ShoutingFire Icecast2 station via
/live
endpoint - Current Song Display - Shows currently playing track information with real-time updates
- Song History - Scrolling panel showing recent songs with the latest at the top (no duplicates)
- Live Chat Integration - Embedded Minnit chatroom for listener interaction
- Schedule Display - Google Calendar integration showing today and tomorrow's shows
- Cross-Platform - Works on web (Vercel), Android, and iOS
- Persistent State - Remembers playback state, active tab, and song history across sessions
- Dark Theme - Black background with yellow text for radio station aesthetic
The app is functional with three main tabs:
- Listen - Audio player with play/pause controls and current song info
- Chat - Embedded Minnit chatroom
- Schedule - Google Calendar showing upcoming shows
- ✅ Current Song Display Fixed - Now fetches metadata from Icecast status page instead of stream headers
- ✅ Stream Loading Error Improved - Better error handling for browser autoplay policies and network issues
- Stream URL:
https://shoutingfire-ice.streamguys1.com/smartmetadata-live
- Metadata endpoint: Same URL with HEAD request to extract ICY headers
- Chat: Embedded Minnit chat at
https://minnit.chat/ShoutingFireChat
- Calendar: Google Calendar embed for
shoutingfirehq@gmail.com
shoutingfire_app/
├── App.tsx # Main app component with tab navigation
├── package.json # Dependencies and scripts
├── app.json # Expo configuration
├── babel.config.js # Babel configuration
├── tsconfig.json # TypeScript configuration
└── README.md # This file
- Node.js (v16 or higher)
- npm or yarn
- Expo CLI (
npm install -g @expo/cli
)
-
Clone the repository
-
Install dependencies:
npm install
# Start development server
npm run web # Web development
npm start # General Expo development
expo
- React Native frameworkexpo-av
- Audio playback@react-native-async-storage/async-storage
- State persistencereact-native-web
- Web support
The app uses expo-av
for audio streaming with the following features:
- Auto-resume playback on app reload
- Persistent play state across sessions
- Error handling for stream issues
- Metadata fetching from ICY headers
Uses AsyncStorage
for cross-platform state persistence:
- Audio playback state (playing/paused)
- Active tab selection
- App preferences
The app is configured for Vercel deployment with Expo web support.
- Android: Use Expo Go app or build APK
- iOS: Use Expo Go app or build IPA
- CORS Errors - Some metadata fetching may be blocked in web browsers
- Audio Playback - Mobile devices may require user interaction before audio can play
- Stream Loading - Network issues or server availability may affect streaming
- Minnit Chat - Customize with black background and image background and still play stream
- Schedule - is still not showing today.
# Clear Expo cache
expo r -c
# Reset Metro bundler
npm start -- --reset-cache
- ✅ Current Song Display - Fixed by fetching from Icecast status page
- ✅ Stream Loading - Improved error handling and autoplay policy support
- ✅ Song History - Implemented scrolling panel with latest songs and no duplicates
- Add Error Recovery - Better handling of network issues
- Mobile Optimization - Ensure smooth experience on mobile devices
- Testing - Test on various devices and browsers
For issues or questions about the ShoutingFire radio station, contact the station directly.
# Start with tunnel (recommended for tethered devices)
npx expo start --tunnel
# Start locally
npx expo start
# Start with specific platform
npx expo start --android
npx expo start --ios
npx expo start --web
# Start with cleared cache
npx expo start --clear
# Create a development build for testing
npx expo run:android
npx expo run:ios
# Build for specific platform
npx expo build:android
npx expo build:ios
# Install EAS CLI
npm install -g @expo/eas-cli
# Login to Expo
eas login
# Configure EAS
eas build:configure
# Build for production
eas build --platform android
eas build --platform ios
eas build --platform all
# Build with specific profile
eas build --profile production --platform android
# Build APK/IPA files
expo build:android
expo build:ios
# Build with specific type
expo build:android -t apk
expo build:android -t app-bundle
expo build:ios -t archive
# Submit to stores
eas submit --platform android
eas submit --platform ios
# Submit with specific build
eas submit --platform android --latest
# Publish updates
expo publish
# Publish with specific channel
expo publish --release-channel production
# Install Expo packages (recommended)
npx expo install package-name
# Install with dependency resolution
npx expo install --fix
# Regular npm install
npm install
# Install with legacy peer deps
npm install --legacy-peer-deps
# Update Expo SDK
npx expo install expo@latest
# Update all Expo packages
npx expo install --fix
# Update npm packages
npm update
package.json
- Dependencies and scriptsapp.json
/app.config.js
- Expo configurationeas.json
- EAS Build configurationmetro.config.js
- Metro bundler configuration
{
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"build": "expo build",
"eject": "expo eject"
}
}
- Uses
adb
for device communication - APK/AAB files for distribution
- Google Play Store deployment
- Requires macOS for builds
- IPA files for distribution
- App Store deployment
- Uses webpack bundler
- Static file deployment
- No app store required
- Use EAS Build instead of classic build
- Use tunnel mode for tethered device testing
- Clear cache when experiencing issues
- Use
npx expo install
for Expo packages - Test on real devices before deployment
The main difference is that modern Expo projects use EAS Build for production builds and deployments, while the classic expo build
commands are deprecated.