22 KiB
beStream Technical Documentation
Table of Contents
- Overview
- Architecture
- Project Structure
- Frontend Application
- Backend Server
- Platform Support
- API Reference
- State Management
- Services
- Build System
- Configuration
- Troubleshooting
Overview
beStream is a cross-platform movie and TV show streaming application with a Netflix-style UI. It supports:
- Desktop: Windows, macOS, Linux (via Electron)
- Mobile: Android (via Capacitor with embedded Node.js)
- Web: Browser-based development mode
The application streams content via WebTorrent, providing real-time torrent-to-stream functionality with optional HLS transcoding for broader device compatibility.
Key Features
- 🎬 Stream movies and TV shows in real-time
- 📺 Netflix-style responsive UI
- 🔍 Search and browse content from YTS and EZTV
- 📱 Cross-platform support (Desktop & Android)
- ⬇️ Download management with progress tracking
- 📚 Watch history and watchlist
- 🎯 Quality selection (480p, 720p, 1080p, 2160p)
- 🔄 Integration with Radarr/Sonarr/Lidarr
Architecture
High-Level Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Frontend (React) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ Pages │ │Components│ │ Stores │ │ Services │ │
│ │ │ │ │ │ (Zustand)│ │ (API, Streaming) │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────────────┘ │
└──────────────────────────────┬──────────────────────────────────┘
│ HTTP/WebSocket
▼
┌─────────────────────────────────────────────────────────────────┐
│ Backend Server (Node.js) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Express │ │ WebTorrent │ │ FFmpeg Transcoder │ │
│ │ Routes │ │ Manager │ │ (HLS streaming) │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Platform-Specific Architecture
Electron (Desktop)
┌─────────────────────────────────────────┐
│ Electron App │
│ ┌─────────────────────────────────┐ │
│ │ Main Process │ │
│ │ - Window management │ │
│ │ - IPC handling │ │
│ │ - Server process spawn │ │
│ └─────────────────────────────────┘ │
│ ┌─────────────────────────────────┐ │
│ │ Renderer Process │ │
│ │ - React Frontend │ │
│ │ - Preload scripts │ │
│ └─────────────────────────────────┘ │
│ ┌─────────────────────────────────┐ │
│ │ Server Process (fork) │ │
│ │ - Express + WebTorrent │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
Capacitor (Android)
┌─────────────────────────────────────────┐
│ Android Application │
│ ┌─────────────────────────────────┐ │
│ │ WebView │ │
│ │ - React Frontend │ │
│ │ - Capacitor Bridge │ │
│ └─────────────────────────────────┘ │
│ ┌─────────────────────────────────┐ │
│ │ capacitor-nodejs plugin │ │
│ │ - Embedded Node.js runtime │ │
│ │ - Express + WebTorrent bundle │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
Project Structure
beStream/
├── src/ # Frontend React application
│ ├── components/ # Reusable UI components
│ │ ├── calendar/ # Calendar-related components
│ │ ├── integration/ # *arr integration components
│ │ ├── layout/ # Layout components (Header, Sidebar)
│ │ ├── movie/ # Movie display components
│ │ ├── music/ # Music-related components
│ │ ├── player/ # Video player components
│ │ ├── tv/ # TV show components
│ │ └── ui/ # Generic UI components (Button, Modal, etc.)
│ ├── pages/ # Page components (routes)
│ ├── hooks/ # Custom React hooks
│ ├── services/ # API and business logic services
│ │ ├── api/ # External API clients (YTS, EZTV, TMDB)
│ │ ├── integration/ # *arr service integrations
│ │ ├── server/ # Server management
│ │ ├── storage/ # Local storage services
│ │ ├── streaming/ # Streaming service client
│ │ ├── subtitles/ # Subtitle handling
│ │ └── torrent/ # Torrent utilities
│ ├── stores/ # Zustand state stores
│ ├── types/ # TypeScript type definitions
│ ├── utils/ # Utility functions
│ └── constants/ # Application constants
├── server/ # Backend Node.js server
│ ├── src/
│ │ ├── routes/ # Express route handlers
│ │ ├── services/ # Backend services (torrent, transcoder)
│ │ ├── utils/ # Server utilities
│ │ └── polyfills/ # Platform polyfills
│ ├── bundle.js # esbuild bundler script
│ └── package.json # Server dependencies
├── electron/ # Electron main process
│ ├── main.ts # Main process entry
│ ├── preload.ts # Preload script
│ └── tsconfig.json # Electron TypeScript config
├── android/ # Android native project (Capacitor)
├── scripts/ # Build and utility scripts
├── docs/ # Documentation
├── public/ # Static assets
├── dist/ # Built frontend
├── dist-electron/ # Built Electron files
└── release/ # Release builds
Frontend Application
Technology Stack
- React 18 - UI framework
- TypeScript - Type safety
- Vite - Build tool and dev server
- Tailwind CSS - Utility-first styling
- Zustand - State management
- React Router - Client-side routing
- Framer Motion - Animations
- Axios - HTTP client
- HLS.js - HLS video playback
Pages
| Page | Route | Description |
|---|---|---|
| Home | / |
Hero section with trending content |
| Browse | /browse, /browse/:genre |
Browse movies by genre |
| Search | /search |
Search movies and TV shows |
| Movie Details | /movie/:id |
Movie information and stream options |
| Player | /player/:id |
Video player with streaming |
| TV Shows | /tv |
Browse TV shows |
| TV Show Details | /tv/:id |
Season/episode browser |
| TV Player | /tv/:showId/:seasonId/:episodeId |
TV episode player |
| Watchlist | /watchlist |
Saved items |
| Downloads | /downloads |
Download manager |
| History | /history |
Watch history |
| Queue | /queue |
Download queue |
| Settings | /settings |
App configuration |
Component Architecture
Layout Components
- Layout - Main app layout with header and sidebar
- Header - Top navigation with search
- Sidebar - Navigation menu
Movie Components
- Hero - Featured content carousel
- MovieRow - Horizontal scrollable movie list
- MovieCard - Individual movie thumbnail
- MovieGrid - Grid layout for movies
Player Components
- StreamingPlayer - Main video player wrapper
- VideoPlayer - Core video element with controls
- NextEpisodeOverlay - Auto-play next episode UI
Hooks
| Hook | Purpose |
|---|---|
useMovies |
Fetch and cache movie data |
useSeries |
Fetch TV show data |
useCalendar |
Episode calendar data |
useIntegration |
*arr service integration |
useAsyncData |
Generic async data fetching |
useMusic |
Music service data |
Backend Server
Technology Stack
- Express.js - Web framework
- WebTorrent - Torrent client
- FFmpeg (optional) - Video transcoding
- ws - WebSocket server
- mime-types - MIME type detection
Server Entry Point
The server initializes in server/src/index.js:
- Creates Express app with security headers
- Sets up CORS for cross-origin requests
- Registers API routes
- Creates WebSocket server for real-time updates
- Binds to
localhost:3001(or0.0.0.0:3001on Android)
Routes
Stream Routes (/api/stream)
| Method | Endpoint | Description |
|---|---|---|
| POST | /start |
Start a new streaming session |
| GET | /:sessionId/status |
Get session status |
| GET | /:sessionId/video |
Stream video (supports range requests) |
| POST | /:sessionId/hls |
Start HLS transcoding |
| GET | /:sessionId/hls/playlist.m3u8 |
Get HLS playlist |
| GET | /:sessionId/hls/:segment |
Get HLS segment |
| DELETE | /:sessionId |
End streaming session |
Proxy Routes (/api)
| Endpoint | Target | Purpose |
|---|---|---|
/api/eztv/* |
eztvx.to | TV show torrents |
/api/yts/* |
yts.mx | Movie torrents |
/api/tmdb/* |
themoviedb.org | Movie/TV metadata |
Services
TorrentManager
Manages WebTorrent client and streaming sessions:
class TorrentManager {
// Start a new torrent session
async startSession(sessionId, torrentHash, movieName, onProgress)
// Create readable stream for video file
createReadStream(sessionId, options)
// Get session status (progress, speed, peers)
getSessionStatus(sessionId)
// Clean up session
destroySession(sessionId)
}
Key features:
- Session reuse for duplicate torrents
- Range request support for seeking
- Progress tracking via callbacks
- Platform-aware cache directories
Transcoder
Handles FFmpeg-based HLS transcoding (desktop only):
class Transcoder {
// Get video file information
getVideoInfo(inputPath)
// Start HLS transcoding from file
startHlsTranscode(sessionId, inputPath, onProgress, quality)
// Start HLS transcoding from stream
startHlsStreamTranscode(sessionId, inputStream, onProgress, quality)
// Clean up transcoding session
cleanup(sessionId)
}
Note: FFmpeg transcoding is disabled on Android due to binary unavailability.
Platform Support
Electron (Desktop)
The Electron build provides:
- Native window with frameless design (macOS) or custom frame (Windows/Linux)
- System tray integration
- File system access for downloads
- Embedded server process
Main Process (electron/main.ts)
- Window creation and management
- Server process lifecycle
- IPC handlers for native features
- Menu and tray setup
Preload Script (electron/preload.ts)
Exposes safe APIs to renderer:
window.electron.openExternal(url)- Open URLs in browserwindow.electron.getDownloadsPath()- Get downloads directorywindow.electron.showItemInFolder(path)- Show file in explorer
Capacitor (Android)
The Android build uses:
- Capacitor WebView for UI
capacitor-nodejsplugin for embedded Node.js- Bundled server (single
index.jsfile)
Build Process
- Build frontend with Vite
- Bundle server with esbuild
- Copy bundle to Android assets
- Sync Capacitor
- Build APK with Gradle
Platform Considerations
- No FFmpeg: Transcoding disabled, direct video streaming only
- No uTP: WebTorrent uTP disabled (native module incompatible)
- Cache Directory: Uses
/data/data/com.bestream.app/files/instead of/tmp - Network: Server binds to
0.0.0.0for WebView access
API Reference
External APIs
YTS API
Movie data and torrents from YTS.
// List movies with filters
ytsApi.listMovies({
limit: 20,
page: 1,
quality: '1080p',
genre: 'action',
sort_by: 'rating',
order_by: 'desc',
query_term: 'search term'
})
// Get movie details
ytsApi.getMovieDetails({ movie_id: 12345 })
// Get suggestions
ytsApi.getMovieSuggestions(12345)
EZTV API
TV show torrents from EZTV.
// Get torrents for a show (by IMDB ID)
tvDiscoveryApi.getTorrents('tt1234567')
// Search episode torrents
tvDiscoveryApi.searchEpisodeTorrents(showTitle, season, episode, imdbId)
TMDB API
TV show metadata from The Movie Database.
// Get trending shows
tvDiscoveryApi.getTrending()
// Get show details
tvDiscoveryApi.getShowDetails(showId)
// Get season details
tvDiscoveryApi.getSeasonDetails(showId, seasonNumber)
Internal APIs
Streaming Service
// Start a stream
streamingService.startStream(hash, name, quality)
// Connect to WebSocket updates
streamingService.connect(sessionId)
// Subscribe to progress updates
streamingService.subscribe(sessionId, callback)
// Get video URL
streamingService.getVideoUrl(sessionId)
// Check server health
streamingService.checkHealth()
State Management
The app uses Zustand for state management with persistence.
Stores
Settings Store
interface SettingsState {
settings: {
preferredQuality: '480p' | '720p' | '1080p' | '2160p';
preferredLanguage: string;
autoPlay: boolean;
notifications: boolean;
downloadPath: string;
maxConcurrentDownloads: number;
theme: 'dark' | 'light';
};
updateSettings(settings: Partial<AppSettings>): void;
resetSettings(): void;
}
History Store
interface HistoryState {
history: HistoryItem[];
addToHistory(item: HistoryItem): void;
updateProgress(id: number, progress: number): void;
getProgress(id: number): HistoryItem | undefined;
removeFromHistory(id: number): void;
clearHistory(): void;
}
Watchlist Store
interface WatchlistState {
watchlist: WatchlistItem[];
addToWatchlist(item: WatchlistItem): void;
removeFromWatchlist(id: number): void;
isInWatchlist(id: number): boolean;
}
Download Store
interface DownloadState {
downloads: Download[];
addDownload(download: Download): void;
updateDownload(id: string, updates: Partial<Download>): void;
removeDownload(id: string): void;
}
Integration Store
interface IntegrationState {
radarrUrl: string;
radarrApiKey: string;
sonarrUrl: string;
sonarrApiKey: string;
lidarrUrl: string;
lidarrApiKey: string;
// ... setters
}
Services
API Services (src/services/api/)
- yts.ts - YTS API client for movies
- tvDiscovery.ts - TMDB + EZTV for TV shows
- radarr.ts - Radarr integration
- sonarr.ts - Sonarr integration
- lidarr.ts - Lidarr integration
Streaming Services (src/services/streaming/)
- streamingService.ts - Main streaming client
- HTTP requests to backend
- WebSocket connection management
- Session lifecycle
Server Services (src/services/server/)
- serverManager.ts - Server lifecycle management
- Start/stop server (Capacitor)
- Health checks
- Automatic restarts
Storage Services (src/services/storage/)
- Local database (Dexie/IndexedDB)
- Download management
- Offline data caching
Build System
Development
# Frontend only
npm run dev
# Frontend + Server
npm run dev:all
# Electron development
npm run electron:dev
Production Builds
# Web build
npm run build
# Electron builds
npm run build:win # Windows
npm run build:mac # macOS
npm run build:linux # Linux
# Android build
npm run build:android:apk # Debug APK
npm run build:android:release # Release APK
Build Pipeline (Android)
-
Frontend Build (
npm run build)- TypeScript compilation
- Vite production build
- Output:
dist/
-
Server Install (
npm run server:install)- Install server dependencies
-
Server Bundle (
npm run copy-server-to-android)- Bundle with esbuild
- Single file output
- Platform-aware polyfills
- Output:
dist/nodejs-v3/index.js
-
Capacitor Sync (
npx cap sync android)- Copy web assets
- Update native project
-
Gradle Build (
gradlew assembleDebug)- Compile Android project
- Output:
android/app/build/outputs/apk/
Configuration
Environment Variables
| Variable | Description | Default |
|---|---|---|
VITE_API_URL |
Backend server URL | http://localhost:3001 |
PORT |
Server port | 3001 |
NODE_ENV |
Environment mode | development |
VITE_EZTV_USERNAME |
EZTV authentication | - |
VITE_EZTV_PASSWORD |
EZTV authentication | - |
Capacitor Config (capacitor.config.ts)
{
appId: 'com.bestream.app',
appName: 'beStream',
webDir: 'dist',
plugins: {
CapacitorNodeJS: {
nodeDir: 'nodejs-v3',
startMode: 'manual',
},
},
android: {
allowMixedContent: true,
cleartext: true,
},
}
Vite Config (vite.config.ts)
- React plugin
- Path aliases (
@/→src/) - Development proxy for APIs
- Rollup externals for Capacitor
Tailwind Config (tailwind.config.js)
Custom theme with Netflix-inspired colors:
netflix-black:#141414netflix-red:#E50914- Custom spacing and breakpoints
Troubleshooting
Common Issues
Server Not Starting (Android)
Symptoms: App shows "Server not running" error
Solutions:
- Check Logcat for Node.js errors
- Verify
nodejs-v3/index.jsexists in APK - Ensure
builtin_modulesplaceholder exists - Check for native module errors (node-datachannel, uTP)
Video Not Playing
Symptoms: Black screen or loading forever
Solutions:
- Check server health:
http://localhost:3001/health - Verify torrent has seeders
- Check browser console for errors
- Try different quality/torrent
CORS Errors
Symptoms: Network errors in browser console
Solutions:
- Ensure server CORS is configured
- Check proxy configuration in Vite
- Verify API URLs are correct
Build Failures (Android)
Symptoms: Gradle build errors
Solutions:
- Clean build:
cd android && gradlew clean - Sync Capacitor:
npx cap sync android - Check Java/Gradle versions
- Verify Android SDK installation
Debug Tools
Logcat (Android)
# All app logs
adb logcat | grep com.bestream.app
# Node.js logs only
adb logcat | grep -E "(NodeJS|beStream)"
Server Health Check
curl http://localhost:3001/health
WebSocket Testing
const ws = new WebSocket('ws://localhost:3001/ws');
ws.onopen = () => ws.send(JSON.stringify({ type: 'subscribe', sessionId: 'test' }));
ws.onmessage = (e) => console.log(JSON.parse(e.data));
Contributing
Code Style
- TypeScript for all new code
- ESLint + Prettier for formatting
- Functional components with hooks
- Named exports preferred
Testing
- Unit tests for utilities
- Integration tests for services
- E2E tests for critical flows
Pull Request Process
- Create feature branch
- Make changes with tests
- Update documentation
- Submit PR with description
- Pass CI checks
- Get review approval
License
This project is private and proprietary. See LICENSE file for details.