chore: update README with enhanced features, add screenshots, and implement auto-updater functionality
This commit is contained in:
148
README.md
148
README.md
@@ -1,54 +1,124 @@
|
|||||||
# VidBee
|
# 🐝 VidBee
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<img src="build/icon.png" alt="VidBee icon" width="120" />
|
<img src="build/icon.png" alt="VidBee icon" width="120" />
|
||||||
<h3>A minimal Electron downloader for video and audio</h3>
|
<h3>Download videos from almost any website worldwide</h3>
|
||||||
|
<p>Best-in-class UI interface - Clean, intuitive, and powerful</p>
|
||||||
<p>Built with Electron, React, TypeScript, Tailwind CSS, and shadcn/ui.</p>
|
<p>Built with Electron, React, TypeScript, Tailwind CSS, and shadcn/ui.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Features
|
## ✨ Core Features
|
||||||
- Download single videos, audio-only tracks, or entire playlists through a unified flow.
|
|
||||||
- Queue multiple jobs with progress tracking, pause, resume, retry, and download history.
|
|
||||||
- Detect platform-friendly formats automatically and store files in custom locations.
|
|
||||||
- Quick actions for popular sites plus manual URL entry for anything yt-dlp supports.
|
|
||||||
- Theme toggle (system, light, dark) and localized interface in English and Simplified Chinese.
|
|
||||||
- Desktop-native touches such as tray integration, update checks, and persistent settings.
|
|
||||||
|
|
||||||
## Tech Stack
|
### 🌍 Global Video Download Support
|
||||||
- **Runtime:** Electron 38, electron-vite, electron-builder.
|
|
||||||
- **Frontend:** React 19, React Router, Jotai, React Hook Form, Tailwind CSS 4, shadcn/ui, Lucide icons.
|
- **1000+ Sites Supported** - Download videos from almost any website worldwide through yt-dlp engine
|
||||||
- **Tooling:** TypeScript 5, pnpm, Biome, dayjs, electron-log, electron-store, electron-updater, i18next, next-themes.
|
- **Smart Platform Detection** - Automatically detect video platforms and optimize download parameters
|
||||||
|
- **Multi-format Support** - Videos, audio tracks, playlists to meet all download needs
|
||||||
|
|
||||||
|
### 🎨 Best-in-class UI Experience
|
||||||
|
|
||||||
|
- **Modern Design** - Clean and beautiful interface
|
||||||
|
- **Intuitive Operations** - One-click pause/resume/retry
|
||||||
|
- **Real-time Progress** - Detailed download progress tracking and status management
|
||||||
|
- **Theme Switching** - Support for system/light/dark themes for comfortable viewing
|
||||||
|
|
||||||
|
### ⚡ Powerful Features
|
||||||
|
|
||||||
|
- 🎯 Automatically detect platform-friendly formats and store files in custom locations
|
||||||
|
- 🎨 Localized interface support in many languages
|
||||||
|
|
||||||
|
## 📥 Download & Install
|
||||||
|
|
||||||
|
1. **Download the latest release** from [GitHub Releases](https://github.com/nexmoe/VidBee/releases)
|
||||||
|
2. **Choose your platform**:
|
||||||
|
- **Windows**: Download `vidbee-x.x.x-setup.exe`
|
||||||
|
- **macOS**: Download `vidbee-x.x.x.dmg`
|
||||||
|
- **Linux**: Download `vidbee-x.x.x.AppImage`
|
||||||
|
3. **Install and run** the application
|
||||||
|
|
||||||
|
## 📸 Screenshots
|
||||||
|
|
||||||
|

|
||||||
|
*Clean and intuitive interface with download queue management*
|
||||||
|
|
||||||
|

|
||||||
|
*Comprehensive download queue with progress tracking and status management*
|
||||||
|
|
||||||
|
## 🌐 Supported Sites
|
||||||
|
|
||||||
|
VidBee supports hundreds of video and audio platforms through yt-dlp. Here are the most popular platforms:
|
||||||
|
|
||||||
|
### 🎬 Video Platforms
|
||||||
|
|
||||||
|
- **📺 YouTube** - Long-form and livestream video from creators worldwide
|
||||||
|
- **🎵 TikTok** - Short-form mobile videos, effects, and live streams
|
||||||
|
- **📘 Facebook** - Feed, Watch, and Reels videos from public pages
|
||||||
|
- **📷 Instagram** - Feed, Stories, Reels, and Highlights content
|
||||||
|
- **🐦 X (Twitter)** - Timeline posts, Spaces recordings, and broadcasts
|
||||||
|
- **🎥 Vimeo** - High-quality creator and business video hosting
|
||||||
|
- **🌍 Dailymotion** - Global news, sports, and entertainment clips
|
||||||
|
- **🎮 Twitch** - Gaming, music, and IRL live streams and VODs
|
||||||
|
- **💼 LinkedIn** - Professional talks, webinars, and learning videos
|
||||||
|
- **📌 Pinterest** - Idea pins, how-to reels, and lifestyle inspiration videos
|
||||||
|
- **🎨 Tumblr** - Creative short-form media and fan edits
|
||||||
|
- **🇯🇵 Niconico** - Japanese animation, music, and live broadcast archive
|
||||||
|
- **⚡ Kick** - Creator live streams and replays on the Kick platform
|
||||||
|
|
||||||
|
### 🎵 Audio Platforms
|
||||||
|
|
||||||
|
- **🎶 YouTube Music** - Official music videos, albums, and live performances
|
||||||
|
- **🎧 SoundCloud** - Music tracks, playlists, and DJ sets
|
||||||
|
- **🎛️ Mixcloud** - DJ mixes, radio shows, and long-form audio
|
||||||
|
- **🎸 Bandcamp** - Independent artist albums and community releases
|
||||||
|
|
||||||
|
### 🔗 Other Platforms
|
||||||
|
|
||||||
|
- **🤖 Reddit** - Embedded clips and hosted videos from communities
|
||||||
|
|
||||||
|
> **💡 Note:** VidBee uses [yt-dlp](https://github.com/yt-dlp/yt-dlp) under the hood, which supports 1000+ sites. For the complete list, visit the [yt-dlp supported sites documentation](https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md).
|
||||||
|
|
||||||
|
## 🛠️ Tech Stack
|
||||||
|
|
||||||
|
- **Runtime:** Electron 38, electron-vite, electron-builder
|
||||||
|
- **Frontend:** React 19, React Router, Jotai, React Hook Form, Tailwind CSS 4, shadcn/ui, Lucide icons
|
||||||
|
- **Tooling:** TypeScript 5, pnpm, Biome, dayjs, electron-log, electron-store, electron-updater, i18next, next-themes
|
||||||
|
|
||||||
|
## 🛠️ Development Setup
|
||||||
|
|
||||||
|
### 📋 Prerequisites
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
### Prerequisites
|
|
||||||
- Node.js 18 or newer
|
- Node.js 18 or newer
|
||||||
- pnpm 8 or newer
|
- pnpm 8 or newer
|
||||||
|
|
||||||
### Install dependencies
|
### 📦 Install dependencies
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm install
|
pnpm install
|
||||||
```
|
```
|
||||||
|
|
||||||
### Run the app in development
|
### 🏃♂️ Run the app in development
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm dev
|
pnpm dev
|
||||||
```
|
```
|
||||||
|
|
||||||
The Electron app and Vite dev server launch together with hot module replacement.
|
The Electron app and Vite dev server launch together with hot module replacement.
|
||||||
|
|
||||||
## Useful Scripts
|
## 📜 Useful Scripts
|
||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `pnpm dev` | Run the Electron and Vite development environment. |
|
| `pnpm dev` | Run the Electron and Vite development environment |
|
||||||
| `pnpm start` | Preview the production build locally. |
|
| `pnpm start` | Preview the production build locally |
|
||||||
| `pnpm run typecheck` | Type-check the main and renderer projects. |
|
| `pnpm run typecheck` | Type-check the main and renderer projects |
|
||||||
| `pnpm build` | Run type checks and produce production bundles. |
|
| `pnpm build` | Run type checks and produce production bundles |
|
||||||
| `pnpm build:win` / `pnpm build:mac` / `pnpm build:linux` | Create platform-specific distributables. |
|
| `pnpm build:win` / `pnpm build:mac` / `pnpm build:linux` | Create platform-specific distributables |
|
||||||
| `pnpm build:unpack` | Produce unpacked output directories. |
|
| `pnpm build:unpack` | Produce unpacked output directories |
|
||||||
| `pnpm run check` | Format and lint the codebase with Biome. |
|
| `pnpm run check` | Format and lint the codebase with Biome |
|
||||||
|
|
||||||
## Project Structure
|
## 📁 Project Structure
|
||||||
```
|
|
||||||
|
```text
|
||||||
src/
|
src/
|
||||||
├─ main/ # Electron main process, IPC services, configuration
|
├─ main/ # Electron main process, IPC services, configuration
|
||||||
├─ preload/ # Context bridge and preload helpers
|
├─ preload/ # Context bridge and preload helpers
|
||||||
@@ -63,15 +133,18 @@ src/
|
|||||||
└─ index.html
|
└─ index.html
|
||||||
```
|
```
|
||||||
|
|
||||||
## Internationalization
|
## 🌍 Internationalization
|
||||||
|
|
||||||
The renderer uses i18next with English (`en`) and Simplified Chinese (`zh-CN`) namespaces. Update strings in `src/renderer/src/locales/en.json`; other locales are maintained separately.
|
The renderer uses i18next with English (`en`) and Simplified Chinese (`zh-CN`) namespaces. Update strings in `src/renderer/src/locales/en.json`; other locales are maintained separately.
|
||||||
|
|
||||||
## Configuration and Storage
|
## ⚙️ Configuration and Storage
|
||||||
- Persistent settings are stored with `electron-store` and exposed through IPC helpers.
|
|
||||||
- User-facing preferences such as download paths and themes live in `src/main/settings.ts` and related services.
|
- Persistent settings are stored with `electron-store` and exposed through IPC helpers
|
||||||
- Logs are recorded with `electron-log` to simplify troubleshooting.
|
- User-facing preferences such as download paths and themes live in `src/main/settings.ts` and related services
|
||||||
|
- Logs are recorded with `electron-log` to simplify troubleshooting
|
||||||
|
|
||||||
|
## 📦 Packaging
|
||||||
|
|
||||||
## Packaging
|
|
||||||
Run one of the following commands after a successful build:
|
Run one of the following commands after a successful build:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -82,13 +155,16 @@ pnpm build:linux
|
|||||||
|
|
||||||
Artifacts are generated under `dist/`. Use `pnpm build:unpack` to create unpacked directories for manual inspection.
|
Artifacts are generated under `dist/`. Use `pnpm build:unpack` to create unpacked directories for manual inspection.
|
||||||
|
|
||||||
## Contributing
|
## 🤝 Contributing
|
||||||
|
|
||||||
Issues and pull requests are welcome. Keep changes focused, document user facing updates, and run `pnpm run check` before opening a PR.
|
Issues and pull requests are welcome. Keep changes focused, document user facing updates, and run `pnpm run check` before opening a PR.
|
||||||
|
|
||||||
## License
|
## 📄 License
|
||||||
|
|
||||||
This project is distributed under the MIT License. See `LICENSE` for details.
|
This project is distributed under the MIT License. See `LICENSE` for details.
|
||||||
|
|
||||||
## Thanks
|
## 🙏 Thanks
|
||||||
|
|
||||||
- [Electron](https://www.electronjs.org/)
|
- [Electron](https://www.electronjs.org/)
|
||||||
- [React](https://react.dev/)
|
- [React](https://react.dev/)
|
||||||
- [Vite](https://vitejs.dev/)
|
- [Vite](https://vitejs.dev/)
|
||||||
|
|||||||
BIN
screenshots/download-queue.png
Normal file
BIN
screenshots/download-queue.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
BIN
screenshots/main-interface.png
Normal file
BIN
screenshots/main-interface.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
@@ -85,6 +85,72 @@ function setupDownloadEvents(): void {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initAutoUpdater(): void {
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
console.log('Skipping auto-updater initialization in development mode')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('Initializing auto-updater...')
|
||||||
|
|
||||||
|
log.transports.file.level = 'info'
|
||||||
|
autoUpdater.logger = log
|
||||||
|
autoUpdater.autoDownload = true
|
||||||
|
autoUpdater.autoInstallOnAppQuit = true
|
||||||
|
|
||||||
|
autoUpdater.on('update-available', (info) => {
|
||||||
|
log.info('Update available:', info.version)
|
||||||
|
console.log('Update available:', info.version)
|
||||||
|
mainWindow?.webContents.send('update:available', info)
|
||||||
|
})
|
||||||
|
|
||||||
|
autoUpdater.on('update-not-available', (info) => {
|
||||||
|
log.info('Update not available:', info.version)
|
||||||
|
console.log('Update not available:', info.version)
|
||||||
|
mainWindow?.webContents.send('update:not-available', info)
|
||||||
|
})
|
||||||
|
|
||||||
|
autoUpdater.on('error', (err) => {
|
||||||
|
log.error('Update error:', err)
|
||||||
|
console.error('Update error:', err)
|
||||||
|
mainWindow?.webContents.send('update:error', err.message)
|
||||||
|
})
|
||||||
|
|
||||||
|
autoUpdater.on('download-progress', (progressObj) => {
|
||||||
|
log.info('Download progress:', progressObj.percent)
|
||||||
|
console.log('Download progress:', progressObj.percent)
|
||||||
|
mainWindow?.webContents.send('update:download-progress', progressObj)
|
||||||
|
})
|
||||||
|
|
||||||
|
autoUpdater.on('update-downloaded', (info) => {
|
||||||
|
log.info('Update downloaded:', info.version)
|
||||||
|
console.log('Update downloaded:', info.version)
|
||||||
|
mainWindow?.webContents.send('update:downloaded', info)
|
||||||
|
|
||||||
|
if (mainWindow) {
|
||||||
|
mainWindow.webContents.send('update:show-notification', {
|
||||||
|
title: 'Update Ready',
|
||||||
|
body: `Version ${info.version} has been downloaded and will be installed on restart.`,
|
||||||
|
icon: 'app-icon'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (settingsManager.get('autoUpdate')) {
|
||||||
|
log.info('Auto-update is enabled, checking for updates...')
|
||||||
|
console.log('Auto-update is enabled, checking for updates...')
|
||||||
|
void autoUpdater.checkForUpdatesAndNotify()
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info('Auto-updater initialized successfully')
|
||||||
|
console.log('Auto-updater initialized successfully')
|
||||||
|
} catch (error) {
|
||||||
|
log.error('Failed to initialize auto-updater:', error)
|
||||||
|
console.error('Failed to initialize auto-updater:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This method will be called when Electron has finished
|
// This method will be called when Electron has finished
|
||||||
// initialization and is ready to create browser windows.
|
// initialization and is ready to create browser windows.
|
||||||
// Some APIs can only be used after this event occurs.
|
// Some APIs can only be used after this event occurs.
|
||||||
@@ -110,84 +176,10 @@ app.whenReady().then(async () => {
|
|||||||
console.error('Failed to initialize yt-dlp:', error)
|
console.error('Failed to initialize yt-dlp:', error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize auto-updater (only in production)
|
|
||||||
if (process.env.NODE_ENV === 'production') {
|
|
||||||
try {
|
|
||||||
console.log('Initializing auto-updater...')
|
|
||||||
|
|
||||||
// Configure logging
|
|
||||||
log.transports.file.level = 'info'
|
|
||||||
autoUpdater.logger = log
|
|
||||||
|
|
||||||
// Configure auto-updater for production
|
|
||||||
autoUpdater.autoDownload = true // Auto download updates
|
|
||||||
autoUpdater.autoInstallOnAppQuit = true // Auto install on quit
|
|
||||||
|
|
||||||
// Set up event listeners
|
|
||||||
autoUpdater.on('update-available', (info) => {
|
|
||||||
log.info('Update available:', info.version)
|
|
||||||
console.log('Update available:', info.version)
|
|
||||||
// Send notification to renderer
|
|
||||||
mainWindow?.webContents.send('update:available', info)
|
|
||||||
})
|
|
||||||
|
|
||||||
autoUpdater.on('update-not-available', (info) => {
|
|
||||||
log.info('Update not available:', info.version)
|
|
||||||
console.log('Update not available:', info.version)
|
|
||||||
// Send notification to renderer
|
|
||||||
mainWindow?.webContents.send('update:not-available', info)
|
|
||||||
})
|
|
||||||
|
|
||||||
autoUpdater.on('error', (err) => {
|
|
||||||
log.error('Update error:', err)
|
|
||||||
console.error('Update error:', err)
|
|
||||||
// Send error to renderer
|
|
||||||
mainWindow?.webContents.send('update:error', err.message)
|
|
||||||
})
|
|
||||||
|
|
||||||
autoUpdater.on('download-progress', (progressObj) => {
|
|
||||||
log.info('Download progress:', progressObj.percent)
|
|
||||||
console.log('Download progress:', progressObj.percent)
|
|
||||||
// Send progress to renderer
|
|
||||||
mainWindow?.webContents.send('update:download-progress', progressObj)
|
|
||||||
})
|
|
||||||
|
|
||||||
autoUpdater.on('update-downloaded', (info) => {
|
|
||||||
log.info('Update downloaded:', info.version)
|
|
||||||
console.log('Update downloaded:', info.version)
|
|
||||||
// Send notification to renderer
|
|
||||||
mainWindow?.webContents.send('update:downloaded', info)
|
|
||||||
|
|
||||||
// Show system notification
|
|
||||||
if (mainWindow) {
|
|
||||||
mainWindow.webContents.send('update:show-notification', {
|
|
||||||
title: 'Update Ready',
|
|
||||||
body: `Version ${info.version} has been downloaded and will be installed on restart.`,
|
|
||||||
icon: 'app-icon'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Check for updates on startup if auto-update is enabled
|
|
||||||
if (settingsManager.get('autoUpdate')) {
|
|
||||||
log.info('Auto-update is enabled, checking for updates...')
|
|
||||||
console.log('Auto-update is enabled, checking for updates...')
|
|
||||||
// Use checkForUpdatesAndNotify for automatic notifications
|
|
||||||
await autoUpdater.checkForUpdatesAndNotify()
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info('Auto-updater initialized successfully')
|
|
||||||
console.log('Auto-updater initialized successfully')
|
|
||||||
} catch (error) {
|
|
||||||
log.error('Failed to initialize auto-updater:', error)
|
|
||||||
console.error('Failed to initialize auto-updater:', error)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('Skipping auto-updater initialization in development mode')
|
|
||||||
}
|
|
||||||
|
|
||||||
createWindow()
|
createWindow()
|
||||||
|
|
||||||
|
initAutoUpdater()
|
||||||
|
|
||||||
// Create system tray
|
// Create system tray
|
||||||
createTray()
|
createTray()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user