A self-hosted video streaming solution with support for web browsers, Roku devices, and a desktop application. Stream your personal video collection across all your devices.
- Features
- Requirements
- Installation
- Server Setup
- Desktop App
- Roku App Setup
- Configuration
- Recommended Tools
- 🎬 Stream videos from your local collection
- 📱 Web-based interface accessible from any browser
- 📺 Native Roku app support
- 💻 Cross-platform desktop application (Windows, macOS, Linux)
- 🔐 Password protection
- 🎯 Automatic network IP detection
- 📂 Customizable video directory
- Node.js: Version 18.x or higher recommended
- Check your version:
node --version - Download from: https://nodejs.org/
- Check your version:
- npm: Comes bundled with Node.js
- Check your version:
npm --version
- Check your version:
- Operating System:
- Linux (Ubuntu, Debian, etc.)
- macOS
- Windows 10/11
- macOS (for building macOS apps):
- Xcode Command Line Tools
- Windows (for building Windows apps):
- Windows 10/11
- Linux (for building Linux apps):
- Standard build tools (
build-essentialon Debian/Ubuntu)
- Standard build tools (
-
Clone the repository
git clone https://github.com/mythius/videostream cd videostream -
Install dependencies
npm install
-
Configure the server (optional)
The server will auto-generate a
config.jsonfile on first run, but you can create it manually:{ "serverName": "192.168.1.100:3000", "videoDirectory": "/path/to/your/videos", "password": "your-secure-password", "url": "http://192.168.1.100:3000" }
npm startThe server will start on port 3000 by default. Access it at:
- Local:
http://localhost:3000 - Network:
http://YOUR_LOCAL_IP:3000
-
Install PM2 globally
npm install -g pm2
-
Start the server
pm2 start server.js --name "videostream" -
Enable auto-start on system boot
pm2 startup pm2 save
-
Useful PM2 commands
pm2 status # Check server status pm2 logs videostream # View logs pm2 restart videostream # Restart server pm2 stop videostream # Stop server
-
Create a service file
sudo nano /etc/systemd/system/videostream.service
-
Add the following configuration (adjust paths as needed):
[Unit] Description=Video Stream Server After=network.target [Service] Type=simple User=YOUR_USERNAME WorkingDirectory=/path/to/videostream ExecStart=/usr/bin/node /path/to/videostream/server.js Restart=on-failure RestartSec=10 StandardOutput=syslog StandardError=syslog SyslogIdentifier=videostream [Install] WantedBy=multi-user.target
-
Enable and start the service
sudo systemctl daemon-reload sudo systemctl enable videostream sudo systemctl start videostream -
Useful systemd commands
sudo systemctl status videostream # Check status sudo systemctl restart videostream # Restart sudo systemctl stop videostream # Stop sudo journalctl -u videostream -f # View logs
If you prefer Docker, you can create a Dockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]Then build and run:
docker build -t videostream .
docker run -d -p 3000:3000 -v /path/to/videos:/app/site/videos --name videostream videostreamMake sure port 3000 is open on your server:
Linux (ufw):
sudo ufw allow 3000/tcpLinux (firewalld):
sudo firewall-cmd --permanent --add-port=3000/tcp
sudo firewall-cmd --reloadWindows Firewall:
New-NetFirewallRule -DisplayName "Video Stream" -Direction Inbound -Port 3000 -Protocol TCP -Action AllowThe desktop application bundles the server with an Electron-based GUI.
npm run desktopnpm run buildThe built application will be in the dist/ directory.
macOS:
npm run build:macOutputs:
.dmginstaller.ziparchive
Windows:
npm run build:winOutputs:
- NSIS installer (
.exe) - Portable executable
Linux:
npm run build:linuxOutputs:
- AppImage (universal)
.debpackage (Debian/Ubuntu)
Note: You typically need to build on the target platform:
- macOS apps: Build on macOS
- Windows apps: Build on Windows (or use wine on Linux)
- Linux apps: Build on Linux
The build configuration is in package.json under the build section. The built app is named MatthiasTV and includes:
- The Express server
- Web interface files
- Roku app source
- All dependencies
-
Enable Developer Mode on your Roku
- Press Home 3x, Up 2x, Right, Left, Right, Left, Right
- Set a developer password
- Note your Roku's IP address
-
Configure the Server URL
Update the server URL in two places:
a. Server configuration - config.json:
{ "serverName": "YOUR_SERVER_IP:3000", "url": "http://YOUR_SERVER_IP:3000" }b. Roku app -
rokuapp/components/MainScene.brs:' Update the server URL m.baseURL = "http://YOUR_SERVER_IP:3000"
-
Zip the Roku app
cd rokuapp zip -r ../roku-channel.zip . cd ..
-
Install on Roku
- Open browser to
http://ROKU_IP(where ROKU_IP is your Roku's IP address) - Login with your developer password
- Click "Upload" and select
roku-channel.zip - Click "Install"
- Open browser to
-
Launch the channel on your Roku device
For detailed Roku development instructions, see the Roku Developer Setup Guide.
| Option | Description | Default |
|---|---|---|
serverName |
Server address (IP:port or domain:port) | Auto-detected local IP with port 3000 |
videoDirectory |
Absolute path to your video folder | ./site/videos |
password |
Password for accessing the stream | matthiasmovies |
url |
Full server URL including protocol | http://[local-ip]:3000 |
Edit server.js:
const port = 3000; // Change this to your desired portPlace your video files in the configured videoDirectory. Supported formats:
- MP4 (recommended)
- MKV
- AVI
- MOV
- WebM
If you're building your own video collection from DVDs/Blu-rays:
MakeMKV - Free and open-source disc ripper
- Download: https://www.makemkv.com/
- Supports DVDs and Blu-rays
- Creates lossless MKV files
FFmpeg - Powerful video conversion tool
Installation:
- Windows:
winget install ffmpeg - Linux:
sudo apt install ffmpeg(Ubuntu/Debian) orsudo yum install ffmpeg(RHEL/CentOS) - macOS:
brew install ffmpeg
Example conversion (MKV to MP4):
ffmpeg -i input.mkv -c:v libx264 -c:a aac -strict experimental output.mp4Batch conversion (Linux/macOS):
for file in *.mkv; do
ffmpeg -i "$file" -c:v libx264 -c:a aac "${file%.mkv}.mp4"
done- Check if port 3000 is already in use:
lsof -i :3000(macOS/Linux) ornetstat -ano | findstr :3000(Windows) - Verify Node.js is installed:
node --version - Check file permissions on the video directory
- Verify firewall allows port 3000
- Ensure devices are on the same network
- Check server is binding to
0.0.0.0notlocalhost
- Verify video format is supported
- Check file permissions
- Ensure video files are in the configured directory
- Check browser console for errors
- Clear node_modules:
rm -rf node_modules && npm install - Clear electron cache:
rm -rf ~/.electron - Ensure electron-builder is installed:
npm install --save-dev electron-builder
ISC
Issues and pull requests are welcome! Please see the issues page.
For questions or support, please open an issue on GitHub.