A complete React Native playground that allows you to stream your mobile app's view in real-time to a web browser using WebSocket and ffmpeg.
This project consists of three main components:
- Backend Server - Node.js WebSocket server with ffmpeg streaming
- Expo Mobile App - React Native app that captures and streams views
- Next.js Frontend - Web interface to view the live stream
โโโโโโโโโโโโโโโโโโโ WebSocket โโโโโโโโโโโโโโโโโโโโ
โ Expo Mobile โ โโโโโโโ (Base64 PNG) โโโโ> โ Backend Server โ
โ App โ โ (Node.js + WS) โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ
ffmpeg pipe
โ
โผ
MJPEG Stream
โ
โผ
โโโโโโโโโโโโโโโโโโโโ
โ Next.js Web UI โ
โ (Stream Viewer) โ
โโโโโโโโโโโโโโโโโโโโ
- Node.js 18+ and npm
- ffmpeg installed and available in PATH
# macOS brew install ffmpeg # Ubuntu/Debian sudo apt-get install ffmpeg # Windows # Download from https://ffmpeg.org/download.html
- Expo CLI (optional, for easier development)
npm install -g expo-cli
- iOS Simulator or Android Emulator or Physical Device
cd react_native_playground_backend
# Install dependencies
npm install
# Start the server
npm run devThe server will start on:
- HTTP:
http://localhost:3000 - WebSocket:
ws://localhost:3001 - MJPEG Stream:
http://localhost:3000/stream.mjpeg
cd expo-stream-app
# Install dependencies
npm install
# Start Expo
npx expo startImportant: Update the server IP in app/index.tsx:
const [serverIP, setServerIP] = useState("YOUR_COMPUTER_IP"); // e.g., "192.168.1.100"To find your IP:
# macOS/Linux
ifconfig | grep "inet "
# Windows
ipconfigThen:
- Scan QR code with Expo Go app (iOS/Android)
- Or press
ifor iOS simulator /afor Android emulator - Enter your server IP in the app
- Press "Start Streaming"
cd react-native-playground-frontend
# Install dependencies
npm install
# Start development server
npm run devOpen http://localhost:3000 in your browser to see the live stream!
-
Start Backend Server
cd react_native_playground_backend npm run dev -
Start Mobile App
cd expo-stream-app npx expo start- Open in Expo Go or simulator
- Enter your computer's IP address
- Tap "Start Streaming"
-
View Stream in Browser
cd react-native-playground-frontend npm run dev- Open http://localhost:3000
- Stream will appear in the Preview panel
You can also view the MJPEG stream directly:
In VLC:
- Media โ Open Network Stream
- Enter:
http://YOUR_IP:3000/stream.mjpeg
In Browser:
- Navigate to:
http://YOUR_IP:3000/stream.mjpeg - (Some browsers support MJPEG natively)
native_playground/
โโโ react_native_playground_backend/
โ โโโ server.ts # WebSocket + ffmpeg server
โ โโโ package.json
โ โโโ tsconfig.json
โ
โโโ expo-stream-app/
โ โโโ app/
โ โ โโโ _layout.tsx # App layout
โ โ โโโ index.tsx # Main streaming screen
โ โโโ app.json
โ โโโ package.json
โ โโโ tsconfig.json
โ
โโโ react-native-playground-frontend/
โโโ src/
โ โโโ app/
โ โ โโโ page.tsx
โ โโโ components/
โ โโโ PlaygroundLayout.tsx
โ โโโ StreamViewer.tsx # Stream display component
โ โโโ ...
โโโ package.json
โโโ next.config.ts
Edit react_native_playground_backend/server.ts:
const HTTP_PORT = 3000; // HTTP server port
const WS_PORT = 3001; // WebSocket port
// ffmpeg settings
"-r", "10", // Frame rate (FPS)
"-vf", "scale=640:-2", // Video scale
"-q:v", "5", // JPEG quality (2-31, lower = better)Edit expo-stream-app/app/index.tsx:
const intervalMs = 100; // Capture interval (100ms = 10 FPS)
// Capture settings
format: "png",
quality: 0.7, // Image quality (0-1)
result: "base64",Edit react-native-playground-frontend/src/components/PlaygroundLayout.tsx:
<StreamViewer
serverUrl="http://localhost:3000" // Backend URL
theme={currentSettings.theme}
/>- Node.js + TypeScript
- Express.js - HTTP server
- ws - WebSocket server
- ffmpeg - Video encoding
- CORS - Cross-origin support
- Expo ~52.0.0
- React Native 0.76.5
- react-native-view-shot - View capture
- expo-router - Navigation
- Next.js 15.5.3
- React 19.1.0
- Monaco Editor - Code editor
- TailwindCSS - Styling
- Lucide React - Icons
- โ WebSocket server for receiving frames
- โ ffmpeg integration for MJPEG encoding
- โ HTTP endpoint for stream delivery
- โ Status monitoring endpoints
- โ Graceful shutdown handling
- โ Real-time view capture at 10 FPS
- โ WebSocket streaming
- โ Configurable server IP
- โ Beautiful UI with live preview
- โ Connection status indicators
- โ Works in Expo Go (no native build needed)
- โ Live MJPEG stream display
- โ Device frame UI
- โ Connection status monitoring
- โ Auto-refresh capability
- โ Dark/Light theme support
- โ Responsive layout
-
Check ffmpeg installation:
ffmpeg -version
-
Verify server is running:
curl http://localhost:3000/status
-
Check mobile app connection:
- Ensure mobile device and computer are on same network
- Verify IP address is correct
- Check firewall settings
-
Test stream directly:
curl http://localhost:3000/stream.mjpeg
- Ensure backend server is running on port 3001
- Check that mobile device can reach server IP
- Verify no firewall blocking WebSocket connections
- Reduce capture quality in mobile app
- Decrease image resolution in ffmpeg settings
- Check network bandwidth
// Mobile app - increase quality
quality: 0.9,
// Backend - better JPEG quality
"-q:v", "2",// Mobile app - lower quality
quality: 0.5,
// Backend - smaller resolution
"-vf", "scale=480:-2",
// Reduce frame rate
"-r", "5",| Endpoint | Method | Description |
|---|---|---|
/ |
GET | Health check |
/status |
GET | Server status (ffmpeg, clients) |
/stream.mjpeg |
GET | MJPEG video stream |
ws://localhost:3001 |
WebSocket | Frame receiver |
From Mobile App:
{
"type": "frame",
"data": "<base64-encoded-png>"
}{
"type": "stop"
}- Live Coding Demos - Show React Native development in real-time
- Remote Debugging - Share app state with team members
- Presentations - Display mobile app on larger screens
- Testing - Monitor app behavior during automated tests
- Education - Teaching React Native development
- Binary frame transmission (reduce overhead)
- HLS/RTMP output for CDN streaming
- Multiple device support
- Recording capability
- Audio streaming
- Touch event overlay
- Performance metrics display
ISC
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Open a Pull Request
- Built with inspiration from the React Native community
- Uses ffmpeg for efficient video encoding
- Powered by Expo for seamless mobile development
Happy Streaming! ๐ฅ