chore: update doc
This commit is contained in:
19
README-zh.md
19
README-zh.md
@@ -30,7 +30,7 @@
|
||||
- **搜索功能**:支持在本地库中搜索视频,或在线搜索 YouTube 视频。
|
||||
- **收藏夹**:创建自定义收藏夹以整理您的视频。
|
||||
- **订阅功能**:订阅您喜爱的频道,并在新视频发布时自动下载。
|
||||
- **登录保护**:通过密码登录页面保护您的应用。
|
||||
- **登录保护**:支持密码登录并可选使用通行密钥 (WebAuthn)。
|
||||
- **国际化**:支持多种语言,包括英语、中文、西班牙语、法语、德语、日语、韩语、阿拉伯语、葡萄牙语和俄语。
|
||||
- **分页功能**:支持分页浏览,高效管理大量视频。
|
||||
- **视频评分**:使用 5 星评级系统为您的视频评分。
|
||||
@@ -39,9 +39,10 @@
|
||||
- **视图模式**:在主页上切换收藏夹视图和视频视图。
|
||||
- **Cookie 管理**:支持上传 `cookies.txt` 以启用年龄限制或会员内容的下载。
|
||||
- **yt-dlp 配置**: 通过用户界面自定义全局 `yt-dlp` 参数、网络代理及其他高级设置。
|
||||
- **访客模式**:启用只读模式,允许查看视频但无法进行修改。非常适合与他人分享您的视频库。
|
||||
- **访客用户**:启用只读角色,便于分享但不允许修改。
|
||||
- **云存储集成**:下载后自动将视频和缩略图上传到云存储(OpenList/Alist)。
|
||||
- **Cloudflare Tunnel 集成**: 内置 Cloudflare Tunnel 支持,无需端口转发即可轻松将本地 MyTube 实例暴露到互联网。
|
||||
- **任务钩子**: 在下载任务的各个阶段(开始、成功、失败、取消)执行自定义 Shell 脚本,以实现集成和自动化。详见 [任务钩子指南](documents/zh/hooks-guide.md)。
|
||||
|
||||
## 目录结构
|
||||
|
||||
@@ -89,23 +90,19 @@
|
||||
### 前端 (`frontend/.env`)
|
||||
|
||||
```env
|
||||
VITE_API_URL=http://localhost:5551/api
|
||||
VITE_BACKEND_URL=http://localhost:5551
|
||||
VITE_API_URL=/api
|
||||
VITE_BACKEND_URL=
|
||||
```
|
||||
|
||||
### 后端 (`backend/.env`)
|
||||
|
||||
```env
|
||||
PORT=5551
|
||||
UPLOAD_DIR=uploads
|
||||
VIDEO_DIR=uploads/videos
|
||||
IMAGE_DIR=uploads/images
|
||||
SUBTITLES_DIR=uploads/subtitles
|
||||
DATA_DIR=data
|
||||
MAX_FILE_SIZE=500000000
|
||||
```
|
||||
|
||||
复制前端和后端目录中的 `.env.example` 文件以创建您自己的 `.env` 文件。
|
||||
默认数据与上传路径位于 `backend/data` 和 `backend/uploads`(相对于后端工作目录)。
|
||||
|
||||
将 `backend/.env.example` 复制为 `backend/.env` 并按需调整。前端已提供 `frontend/.env`,可使用 `frontend/.env.local` 覆盖默认值。
|
||||
|
||||
## 数据库
|
||||
|
||||
|
||||
19
README.md
19
README.md
@@ -29,7 +29,7 @@ Self-hosted downloader and player for YouTube, Bilibili, MissAV, and [yt-dlp sit
|
||||
- **Auto Subtitles**: Automatically download YouTube / Bilibili default language subtitles.
|
||||
- **Search**: Search for videos locally in your library or online via YouTube.
|
||||
- **Collections**: Organize videos into custom collections for easy access.
|
||||
- **Login Protection**: Secure your application with a password login page.
|
||||
- **Login Protection**: Secure your application with password login and optional passkeys (WebAuthn).
|
||||
- **Internationalization**: Support for multiple languages including English, Chinese, Spanish, French, German, Japanese, Korean, Arabic, Portuguese, and Russian.
|
||||
- **Pagination**: Efficiently browse large libraries with pagination support.
|
||||
- **Subscriptions**: Manage subscriptions to channels or creators to automatically download new content.
|
||||
@@ -39,9 +39,10 @@ Self-hosted downloader and player for YouTube, Bilibili, MissAV, and [yt-dlp sit
|
||||
- **View Modes**: Toggle between Collection View and Video View on the home page.
|
||||
- **Cookie Management**: Support for uploading `cookies.txt` to enable downloading of age-restricted or premium content.
|
||||
- **yt-dlp Configuration**: Customize global `yt-dlp` arguments, network proxy, and other advanced settings via settings page.
|
||||
- **Visitor Mode**: Enable read-only mode to allow viewing videos without modification capabilities. Perfect for sharing your library with others.
|
||||
- **Visitor User**: Enable a read-only role for safe sharing without modification capabilities.
|
||||
- **Cloud Storage Integration**: Automatically upload videos and thumbnails to cloud storage (OpenList/Alist) after download.
|
||||
- **Cloudflare Tunnel Integration**: Built-in Cloudflare Tunnel support to easily expose your local MyTube instance to the internet without port forwarding.
|
||||
- **Task Hooks**: Execute custom shell scripts at various stages of a download task (start, success, fail, cancel) for integration and automation. See [Task Hooks Guide](documents/en/hooks-guide.md).
|
||||
|
||||
## Directory Structure
|
||||
|
||||
@@ -89,23 +90,19 @@ The application uses environment variables for configuration.
|
||||
### Frontend (`frontend/.env`)
|
||||
|
||||
```env
|
||||
VITE_API_URL=http://localhost:5551/api
|
||||
VITE_BACKEND_URL=http://localhost:5551
|
||||
VITE_API_URL=/api
|
||||
VITE_BACKEND_URL=
|
||||
```
|
||||
|
||||
### Backend (`backend/.env`)
|
||||
|
||||
```env
|
||||
PORT=5551
|
||||
UPLOAD_DIR=uploads
|
||||
VIDEO_DIR=uploads/videos
|
||||
IMAGE_DIR=uploads/images
|
||||
SUBTITLES_DIR=uploads/subtitles
|
||||
DATA_DIR=data
|
||||
MAX_FILE_SIZE=500000000
|
||||
```
|
||||
|
||||
Copy the `.env.example` files in both frontend and backend directories to create your own `.env` files.
|
||||
Data and uploads are stored under `backend/data` and `backend/uploads` by default (relative to the backend working directory).
|
||||
|
||||
Copy `backend/.env.example` to `backend/.env` and adjust as needed. The frontend ships with `frontend/.env`; use `frontend/.env.local` to override defaults.
|
||||
|
||||
## Database
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
# API Endpoints
|
||||
|
||||
All API routes are mounted under `/api` unless noted otherwise.
|
||||
|
||||
## Video Download & Search
|
||||
|
||||
- `GET /api/search` - Search for videos online (YouTube)
|
||||
- `GET /api/search` - Search videos online (YouTube)
|
||||
- Query params: `query` (required), `limit` (optional, default: 8), `offset` (optional, default: 1)
|
||||
- `POST /api/download` - Download a video from supported platforms
|
||||
- Body: `{ url: string, ...options }`
|
||||
- Body: `{ youtubeUrl: string, ...options }`
|
||||
- Supports: YouTube, Bilibili, MissAV, and all yt-dlp supported sites
|
||||
- `GET /api/check-video-download` - Check if a video has already been downloaded
|
||||
- Query params: `url` (required)
|
||||
@@ -16,8 +18,8 @@
|
||||
- Query params: `url` (required)
|
||||
- `GET /api/check-playlist` - Check if a URL is a supported playlist
|
||||
- Query params: `url` (required)
|
||||
- `GET /api/download-status` - Get status of active downloads
|
||||
- Returns: `{ active: [], queued: [] }`
|
||||
- `GET /api/download-status` - Get active/queued download status
|
||||
- Returns: `{ activeDownloads: DownloadInfo[], queuedDownloads: DownloadInfo[] }`
|
||||
|
||||
## Video Management
|
||||
|
||||
@@ -40,7 +42,6 @@
|
||||
- `GET /api/videos/author-channel-url` - Get author channel URL for a video
|
||||
- Query params: `sourceUrl` (required)
|
||||
- Returns: `{ success: boolean, channelUrl: string | null }`
|
||||
- Checks database first, then fetches from YouTube/Bilibili API if not found
|
||||
|
||||
## Download Management
|
||||
|
||||
@@ -80,25 +81,54 @@
|
||||
- `DELETE /api/subscriptions/tasks/:id/delete` - Delete a task record
|
||||
- `DELETE /api/subscriptions/tasks/clear-finished` - Clear all finished tasks
|
||||
|
||||
## Settings & System
|
||||
## Settings & Passwords
|
||||
|
||||
- `GET /api/settings` - Get application settings
|
||||
- `POST /api/settings` - Update application settings
|
||||
- Body: `{ [key: string]: any }` - Settings object
|
||||
- Supports: `visitorMode`, `cloudDriveEnabled`, `openListApiUrl`, `openListToken`, `openListPublicUrl`, `cloudDrivePath`, and other settings
|
||||
- `GET /api/settings/cloudflared/status` - Get Cloudflare Tunnel status
|
||||
- `GET /api/settings/password-enabled` - Check if password protection is enabled
|
||||
- `POST /api/settings/verify-password` - Verify login password
|
||||
- Body: `{ password: string }`
|
||||
- `POST /api/settings/reset-password` - Reset login password
|
||||
- Body: `{ oldPassword: string, newPassword: string }`
|
||||
- `POST /api/settings/migrate` - Migrate data from JSON to SQLite
|
||||
- `POST /api/settings/delete-legacy` - Delete legacy JSON data files
|
||||
- `POST /api/settings/format-filenames` - Format video filenames according to settings
|
||||
- `GET /api/settings/password-enabled` - Check if password protection is enabled
|
||||
- `GET /api/settings/reset-password-cooldown` - Get cooldown time for password reset
|
||||
- `POST /api/settings/verify-admin-password` - Verify admin password
|
||||
- Body: `{ password: string }`
|
||||
- `POST /api/settings/verify-visitor-password` - Verify visitor password
|
||||
- Body: `{ password: string }`
|
||||
- `POST /api/settings/verify-password` - Verify login password (deprecated)
|
||||
- Body: `{ password: string }`
|
||||
- `POST /api/settings/reset-password` - Reset login password
|
||||
- Body: `{ oldPassword: string, newPassword: string }`
|
||||
- `POST /api/settings/logout` - Logout current session
|
||||
|
||||
## Passkey Management
|
||||
|
||||
- `GET /api/settings/passkeys` - Get all registered passkeys
|
||||
- `GET /api/settings/passkeys/exists` - Check if any passkeys are registered
|
||||
- `POST /api/settings/passkeys/register` - Start passkey registration
|
||||
- `POST /api/settings/passkeys/register/verify` - Verify passkey registration
|
||||
- `POST /api/settings/passkeys/authenticate` - Start passkey authentication
|
||||
- `POST /api/settings/passkeys/authenticate/verify` - Verify passkey authentication
|
||||
- `DELETE /api/settings/passkeys` - Remove all passkeys
|
||||
|
||||
## Cookies
|
||||
|
||||
- `POST /api/settings/upload-cookies` - Upload cookies.txt for yt-dlp
|
||||
- Multipart form data: `file` (cookies.txt)
|
||||
- `POST /api/settings/delete-cookies` - Delete cookies.txt
|
||||
- `GET /api/settings/check-cookies` - Check if cookies.txt exists
|
||||
|
||||
## Task Hooks
|
||||
|
||||
- `GET /api/settings/hooks/status` - Get status of all hooks
|
||||
- `POST /api/settings/hooks/:name` - Upload a hook script
|
||||
- Multipart form data: `file` (script file)
|
||||
- Params: `name` (hook name, e.g., `task_success`)
|
||||
- `DELETE /api/settings/hooks/:name` - Delete a hook script
|
||||
|
||||
## Database Backups
|
||||
|
||||
- `GET /api/settings/export-database` - Export database as backup file
|
||||
- `POST /api/settings/import-database` - Import database from backup file
|
||||
- Multipart form data: `file` (database backup file)
|
||||
@@ -113,6 +143,15 @@
|
||||
|
||||
## Cloud Storage
|
||||
|
||||
- `GET /cloud/videos/:filename` - Proxy endpoint to stream videos from cloud storage (OpenList/Alist)
|
||||
- `GET /cloud/images/:filename` - Proxy endpoint to serve images from cloud storage (OpenList/Alist)
|
||||
- Note: These endpoints require cloud storage to be configured in settings
|
||||
- `GET /api/cloud/signed-url` - Get a signed URL for cloud storage
|
||||
- Query params: `filename` (required), `type` (optional: `video` or `thumbnail`)
|
||||
- `POST /api/cloud/sync` - Sync local videos to cloud storage (streams JSON lines)
|
||||
- `DELETE /api/cloud/thumbnail-cache` - Clear local thumbnail cache
|
||||
- `GET /api/cloud/thumbnail-cache/:filename` - Serve a cached cloud thumbnail
|
||||
- `GET /cloud/videos/:filename` - Redirect to signed URL for cloud videos
|
||||
- `GET /cloud/images/:filename` - Redirect to signed URL (or cached file) for cloud thumbnails
|
||||
|
||||
## System
|
||||
|
||||
- `GET /api/system/version` - Get current and latest version info
|
||||
- Returns: `{ currentVersion, latestVersion, releaseUrl, hasUpdate }`
|
||||
|
||||
@@ -2,269 +2,84 @@
|
||||
|
||||
```
|
||||
mytube/
|
||||
├── backend/ # Express.js backend (TypeScript)
|
||||
│ ├── src/ # Source code
|
||||
│ │ ├── __tests__/ # Test files
|
||||
│ │ │ ├── controllers/ # Controller tests
|
||||
│ │ │ ├── middleware/ # Middleware tests
|
||||
│ │ │ ├── services/ # Service tests
|
||||
│ │ │ └── utils/ # Utility tests
|
||||
│ │ ├── config/ # Configuration files
|
||||
│ │ │ └── paths.ts # Path configuration
|
||||
│ │ ├── controllers/ # Route controllers
|
||||
│ │ │ ├── cleanupController.ts # Cleanup operations
|
||||
├── backend/ # Express.js backend (TypeScript)
|
||||
│ ├── src/ # Source code
|
||||
│ │ ├── __tests__/ # Test files
|
||||
│ │ ├── config/ # Configuration (paths, etc.)
|
||||
│ │ ├── controllers/ # Route controllers
|
||||
│ │ │ ├── cleanupController.ts
|
||||
│ │ │ ├── cloudStorageController.ts
|
||||
│ │ │ ├── collectionController.ts
|
||||
│ │ │ ├── cookieController.ts
|
||||
│ │ │ ├── downloadController.ts
|
||||
│ │ │ ├── hookController.ts
|
||||
│ │ │ ├── passkeyController.ts
|
||||
│ │ │ ├── passwordController.ts
|
||||
│ │ │ ├── scanController.ts
|
||||
│ │ │ ├── settingsController.ts
|
||||
│ │ │ ├── subscriptionController.ts
|
||||
│ │ │ ├── systemController.ts
|
||||
│ │ │ ├── videoController.ts
|
||||
│ │ │ ├── videoDownloadController.ts
|
||||
│ │ │ └── videoMetadataController.ts
|
||||
│ │ ├── db/ # Database layer
|
||||
│ │ │ ├── index.ts # Database connection (Drizzle ORM)
|
||||
│ │ │ ├── migrate.ts # Migration runner
|
||||
│ │ │ └── schema.ts # Database schema definitions
|
||||
│ │ ├── errors/ # Custom error classes
|
||||
│ │ │ └── DownloadErrors.ts
|
||||
│ │ ├── middleware/ # Express middleware
|
||||
│ │ │ ├── errorHandler.ts # Error handling middleware
|
||||
│ │ │ ├── visitorModeMiddleware.ts # Visitor mode (read-only) middleware
|
||||
│ │ │ └── visitorModeSettingsMiddleware.ts # Visitor mode settings middleware
|
||||
│ │ ├── routes/ # API route definitions
|
||||
│ │ │ ├── api.ts # Main API routes
|
||||
│ │ │ └── settingsRoutes.ts # Settings-specific routes
|
||||
│ │ ├── scripts/ # Utility scripts
|
||||
│ │ │ ├── cleanVttFiles.ts
|
||||
│ │ │ └── rescanSubtitles.ts
|
||||
│ │ ├── services/ # Business logic services
|
||||
│ │ │ ├── downloaders/ # Downloader implementations
|
||||
│ │ │ │ ├── BaseDownloader.ts # Abstract base class
|
||||
│ │ │ │ ├── BilibiliDownloader.ts
|
||||
│ │ │ │ ├── MissAVDownloader.ts
|
||||
│ │ │ │ ├── YtDlpDownloader.ts
|
||||
│ │ │ │ ├── bilibili/ # Bilibili-specific modules
|
||||
│ │ │ │ │ ├── bilibiliApi.ts
|
||||
│ │ │ │ │ ├── bilibiliCollection.ts
|
||||
│ │ │ │ │ ├── bilibiliCookie.ts
|
||||
│ │ │ │ │ ├── bilibiliSubtitle.ts
|
||||
│ │ │ │ │ ├── bilibiliVideo.ts
|
||||
│ │ │ │ │ └── types.ts
|
||||
│ │ │ │ └── ytdlp/ # yt-dlp-specific modules
|
||||
│ │ │ │ ├── types.ts
|
||||
│ │ │ │ ├── ytdlpChannel.ts
|
||||
│ │ │ │ ├── ytdlpConfig.ts
|
||||
│ │ │ │ ├── ytdlpHelpers.ts
|
||||
│ │ │ │ ├── ytdlpMetadata.ts
|
||||
│ │ │ │ ├── ytdlpSearch.ts
|
||||
│ │ │ │ ├── ytdlpSubtitle.ts
|
||||
│ │ │ │ └── ytdlpVideo.ts
|
||||
│ │ │ ├── storageService/ # Modular storage service
|
||||
│ │ │ │ ├── index.ts # Main export file
|
||||
│ │ │ │ ├── types.ts # Type definitions
|
||||
│ │ │ │ ├── initialization.ts # Database initialization
|
||||
│ │ │ │ ├── downloadStatus.ts # Active/queued downloads
|
||||
│ │ │ │ ├── downloadHistory.ts # Download history
|
||||
│ │ │ │ ├── videoDownloadTracking.ts # Duplicate prevention
|
||||
│ │ │ │ ├── settings.ts # Application settings
|
||||
│ │ │ │ ├── videos.ts # Video CRUD operations
|
||||
│ │ │ │ ├── collections.ts # Collection operations
|
||||
│ │ │ │ └── fileHelpers.ts # File system utilities
|
||||
│ │ │ ├── CloudStorageService.ts
|
||||
│ │ │ ├── commentService.ts
|
||||
│ │ │ ├── downloadManager.ts # Download queue management
|
||||
│ │ │ ├── downloadService.ts
|
||||
│ │ │ ├── loginAttemptService.ts
|
||||
│ │ │ ├── metadataService.ts
|
||||
│ │ │ ├── migrationService.ts
|
||||
│ │ │ ├── storageService.ts # Legacy compatibility export
|
||||
│ │ │ ├── subscriptionService.ts
|
||||
│ │ │ ├── subtitleService.ts
|
||||
│ │ │ └── thumbnailService.ts
|
||||
│ │ ├── utils/ # Utility functions
|
||||
│ │ │ ├── bccToVtt.ts # Subtitle conversion
|
||||
│ │ │ ├── downloadUtils.ts
|
||||
│ │ │ ├── helpers.ts
|
||||
│ │ │ ├── logger.ts
|
||||
│ │ │ ├── progressTracker.ts
|
||||
│ │ │ ├── response.ts
|
||||
│ │ │ └── ytDlpUtils.ts
|
||||
│ │ ├── server.ts # Main server file
|
||||
│ │ └── version.ts # Version information
|
||||
│ ├── bgutil-ytdlp-pot-provider/ # PO Token provider plugin
|
||||
│ │ ├── plugin/ # Python plugin
|
||||
│ │ │ └── yt_dlp_plugins/
|
||||
│ │ └── server/ # TypeScript server
|
||||
│ │ └── src/
|
||||
│ ├── data/ # Data directory
|
||||
│ │ ├── mytube.db # SQLite database
|
||||
│ │ ├── cookies.txt # yt-dlp cookies (optional)
|
||||
│ │ └── login-attempts.json # Login attempt tracking
|
||||
│ ├── drizzle/ # Database migrations
|
||||
│ │ └── meta/ # Migration metadata
|
||||
│ ├── uploads/ # Uploaded files directory
|
||||
│ │ ├── videos/ # Downloaded videos
|
||||
│ │ ├── images/ # Downloaded thumbnails
|
||||
│ │ └── subtitles/ # Downloaded subtitles
|
||||
│ ├── dist/ # Compiled JavaScript
|
||||
│ ├── coverage/ # Test coverage reports
|
||||
│ ├── Dockerfile # Backend Docker image
|
||||
│ ├── drizzle.config.ts # Drizzle ORM configuration
|
||||
│ ├── nodemon.json # Nodemon configuration
|
||||
│ ├── package.json # Backend dependencies
|
||||
│ ├── tsconfig.json # TypeScript configuration
|
||||
│ └── vitest.config.ts # Vitest test configuration
|
||||
├── frontend/ # React.js frontend (Vite + TypeScript)
|
||||
│ ├── src/ # Source code
|
||||
│ │ ├── __tests__/ # Test files
|
||||
│ │ ├── assets/ # Static assets
|
||||
│ │ │ └── logo.svg
|
||||
│ │ ├── components/ # React components
|
||||
│ │ │ ├── Header/ # Header component group
|
||||
│ │ │ │ ├── ActionButtons.tsx
|
||||
│ │ │ │ ├── DownloadsMenu.tsx
|
||||
│ │ │ │ ├── index.tsx
|
||||
│ │ │ │ ├── Logo.tsx
|
||||
│ │ │ │ ├── ManageMenu.tsx
|
||||
│ │ │ │ ├── MobileMenu.tsx
|
||||
│ │ │ │ ├── SearchInput.tsx
|
||||
│ │ │ │ └── types.ts
|
||||
│ │ │ ├── ManagePage/ # Management page components
|
||||
│ │ │ │ ├── CollectionsTable.tsx
|
||||
│ │ │ │ └── VideosTable.tsx
|
||||
│ │ │ ├── Settings/ # Settings page components
|
||||
│ │ │ │ ├── AdvancedSettings.tsx
|
||||
│ │ │ │ ├── CloudDriveSettings.tsx
|
||||
│ │ │ │ ├── CookieSettings.tsx
|
||||
│ │ │ │ ├── DatabaseSettings.tsx
|
||||
│ │ │ │ ├── DownloadSettings.tsx
|
||||
│ │ │ │ ├── GeneralSettings.tsx
|
||||
│ │ │ │ ├── SecuritySettings.tsx
|
||||
│ │ │ │ ├── TagsSettings.tsx
|
||||
│ │ │ │ ├── VideoDefaultSettings.tsx
|
||||
│ │ │ │ └── YtDlpSettings.tsx
|
||||
│ │ │ ├── VideoPlayer/ # Video player components
|
||||
│ │ │ │ ├── CommentsSection.tsx
|
||||
│ │ │ │ ├── UpNextSidebar.tsx
|
||||
│ │ │ │ ├── VideoControls.tsx
|
||||
│ │ │ │ ├── VideoInfo.tsx
|
||||
│ │ │ │ └── VideoInfo/ # Video info subcomponents
|
||||
│ │ │ │ ├── EditableTitle.tsx
|
||||
│ │ │ │ ├── VideoActionButtons.tsx
|
||||
│ │ │ │ ├── VideoAuthorInfo.tsx
|
||||
│ │ │ │ ├── VideoDescription.tsx
|
||||
│ │ │ │ ├── VideoMetadata.tsx
|
||||
│ │ │ │ ├── VideoRating.tsx
|
||||
│ │ │ │ └── VideoTags.tsx
|
||||
│ │ │ ├── AlertModal.tsx
|
||||
│ │ │ ├── AnimatedRoutes.tsx
|
||||
│ │ │ ├── AuthorsList.tsx
|
||||
│ │ │ ├── BatchDownloadModal.tsx
|
||||
│ │ │ ├── BilibiliPartsModal.tsx
|
||||
│ │ │ ├── CollectionCard.tsx
|
||||
│ │ │ ├── CollectionModal.tsx
|
||||
│ │ │ ├── Collections.tsx
|
||||
│ │ │ ├── ConfirmationModal.tsx
|
||||
│ │ │ ├── DeleteCollectionModal.tsx
|
||||
│ │ │ ├── Disclaimer.tsx
|
||||
│ │ │ ├── Footer.tsx
|
||||
│ │ │ ├── PageTransition.tsx
|
||||
│ │ │ ├── SubscribeModal.tsx
|
||||
│ │ │ ├── TagsList.tsx
|
||||
│ │ │ ├── UploadModal.tsx
|
||||
│ │ │ └── VideoCard.tsx
|
||||
│ │ ├── contexts/ # React contexts for state management
|
||||
│ │ │ ├── AuthContext.tsx
|
||||
│ │ │ ├── CollectionContext.tsx
|
||||
│ │ │ ├── DownloadContext.tsx
|
||||
│ │ │ ├── LanguageContext.tsx
|
||||
│ │ │ ├── SnackbarContext.tsx
|
||||
│ │ │ ├── ThemeContext.tsx
|
||||
│ │ │ └── VideoContext.tsx
|
||||
│ │ ├── hooks/ # Custom React hooks
|
||||
│ │ │ ├── useDebounce.ts
|
||||
│ │ │ ├── useShareVideo.ts
|
||||
│ │ │ └── useVideoResolution.ts
|
||||
│ │ ├── pages/ # Page components
|
||||
│ │ │ ├── AuthorVideos.tsx
|
||||
│ │ │ ├── CollectionPage.tsx
|
||||
│ │ │ ├── DownloadPage/ # Download page components
|
||||
│ │ │ │ ├── ActiveDownloadsTab.tsx
|
||||
│ │ │ │ ├── CustomTabPanel.tsx
|
||||
│ │ │ │ ├── HistoryItem.tsx
|
||||
│ │ │ │ ├── HistoryTab.tsx
|
||||
│ │ │ │ ├── index.tsx
|
||||
│ │ │ │ └── QueueTab.tsx
|
||||
│ │ │ ├── Home.tsx
|
||||
│ │ │ ├── InstructionPage.tsx
|
||||
│ │ │ ├── LoginPage.tsx
|
||||
│ │ │ ├── ManagePage.tsx
|
||||
│ │ │ ├── SearchPage.tsx
|
||||
│ │ │ ├── SearchResults.tsx
|
||||
│ │ │ ├── SettingsPage.tsx
|
||||
│ │ │ ├── SubscriptionsPage.tsx
|
||||
│ │ │ └── VideoPlayer.tsx
|
||||
│ │ ├── utils/ # Utilities and locales
|
||||
│ │ │ ├── locales/ # Internationalization files
|
||||
│ │ │ │ ├── ar.ts # Arabic
|
||||
│ │ │ │ ├── de.ts # German
|
||||
│ │ │ │ ├── en.ts # English
|
||||
│ │ │ │ ├── es.ts # Spanish
|
||||
│ │ │ │ ├── fr.ts # French
|
||||
│ │ │ │ ├── ja.ts # Japanese
|
||||
│ │ │ │ ├── ko.ts # Korean
|
||||
│ │ │ │ ├── pt.ts # Portuguese
|
||||
│ │ │ │ ├── ru.ts # Russian
|
||||
│ │ │ │ └── zh.ts # Chinese
|
||||
│ │ │ ├── consoleManager.ts
|
||||
│ │ │ ├── constants.ts
|
||||
│ │ │ ├── formatUtils.ts
|
||||
│ │ │ ├── recommendations.ts
|
||||
│ │ │ └── translations.ts
|
||||
│ │ ├── App.tsx # Main application component
|
||||
│ │ ├── App.css
|
||||
│ │ ├── index.css
|
||||
│ │ ├── main.tsx # Application entry point
|
||||
│ │ ├── setupTests.ts
|
||||
│ │ ├── theme.ts # Material-UI theme configuration
|
||||
│ │ ├── types.ts # TypeScript type definitions
|
||||
│ │ ├── version.ts # Version information
|
||||
│ │ └── vite-env.d.ts
|
||||
│ ├── dist/ # Production build output
|
||||
│ ├── public/ # Public static files
|
||||
│ ├── Dockerfile # Frontend Docker image
|
||||
│ ├── entrypoint.sh # Docker entrypoint script
|
||||
│ ├── eslint.config.js # ESLint configuration
|
||||
│ ├── index.html # HTML template
|
||||
│ ├── nginx.conf # Nginx configuration
|
||||
│ ├── package.json # Frontend dependencies
|
||||
│ ├── tsconfig.json # TypeScript configuration
|
||||
│ │ ├── db/ # Drizzle ORM + SQLite
|
||||
│ │ ├── errors/ # Custom error classes
|
||||
│ │ ├── middleware/ # Express middleware
|
||||
│ │ │ ├── authMiddleware.ts
|
||||
│ │ │ ├── roleBasedAuthMiddleware.ts
|
||||
│ │ │ ├── roleBasedSettingsMiddleware.ts
|
||||
│ │ │ └── errorHandler.ts
|
||||
│ │ ├── routes/ # Route definitions
|
||||
│ │ │ ├── api.ts # Main API routes
|
||||
│ │ │ └── settingsRoutes.ts # Settings-specific routes
|
||||
│ │ ├── scripts/ # Utility scripts (VTT cleanup, rescans)
|
||||
│ │ ├── services/ # Business logic
|
||||
│ │ │ ├── cloudStorage/ # Cloud storage helpers and cache
|
||||
│ │ │ ├── continuousDownload/ # Subscription task engine
|
||||
│ │ │ ├── downloaders/ # Platform downloaders (yt-dlp, Bilibili, MissAV)
|
||||
│ │ │ ├── storageService/ # Modular storage service
|
||||
│ │ │ └── *.ts # Other services (auth, metadata, etc.)
|
||||
│ │ ├── utils/ # Shared utilities
|
||||
│ │ ├── server.ts # Server bootstrap
|
||||
│ │ └── version.ts # Version info
|
||||
│ ├── bgutil-ytdlp-pot-provider/ # PO Token provider plugin
|
||||
│ ├── data/ # Runtime data (db, hooks, backups)
|
||||
│ ├── drizzle/ # Database migrations
|
||||
│ ├── uploads/ # Media storage (videos, images, subtitles, cache)
|
||||
│ ├── scripts/ # Maintenance scripts (reset-password, migrate, verify)
|
||||
│ ├── Dockerfile
|
||||
│ ├── drizzle.config.ts
|
||||
│ ├── nodemon.json
|
||||
│ ├── package.json
|
||||
│ ├── tsconfig.json
|
||||
│ └── vitest.config.ts
|
||||
├── frontend/ # React frontend (Vite + TypeScript)
|
||||
│ ├── src/ # Source code
|
||||
│ │ ├── __tests__/ # Test files
|
||||
│ │ ├── assets/ # Static assets
|
||||
│ │ ├── components/ # UI components by feature
|
||||
│ │ ├── contexts/ # React Context state
|
||||
│ │ ├── hooks/ # Custom hooks (player, settings, data)
|
||||
│ │ ├── pages/ # Route pages
|
||||
│ │ ├── utils/ # API client, helpers, i18n
|
||||
│ │ ├── App.tsx
|
||||
│ │ ├── main.tsx
|
||||
│ │ ├── theme.ts
|
||||
│ │ └── version.ts
|
||||
│ ├── public/ # Public assets
|
||||
│ ├── Dockerfile
|
||||
│ ├── entrypoint.sh
|
||||
│ ├── nginx.conf
|
||||
│ ├── package.json
|
||||
│ ├── tsconfig.json
|
||||
│ ├── tsconfig.node.json
|
||||
│ └── vite.config.js # Vite configuration
|
||||
├── documents/ # Documentation
|
||||
│ ├── en/ # English documentation
|
||||
│ │ ├── api-endpoints.md
|
||||
│ │ ├── directory-structure.md
|
||||
│ │ ├── docker-guide.md
|
||||
│ │ └── getting-started.md
|
||||
│ └── zh/ # Chinese documentation
|
||||
│ ├── api-endpoints.md
|
||||
│ ├── directory-structure.md
|
||||
│ ├── docker-guide.md
|
||||
│ └── getting-started.md
|
||||
├── data/ # Root data directory (optional)
|
||||
│ └── mytube.db
|
||||
├── build-and-push.sh # Docker build and push script
|
||||
├── docker-compose.yml # Docker Compose configuration
|
||||
├── CHANGELOG.md # Changelog
|
||||
├── CODE_OF_CONDUCT.md # Code of conduct
|
||||
├── CONTRIBUTING.md # Contributing guidelines
|
||||
├── LICENSE # MIT License
|
||||
├── README.md # English README
|
||||
├── README-zh.md # Chinese README
|
||||
├── RELEASING.md # Release process guide
|
||||
├── SECURITY.md # Security policy
|
||||
└── package.json # Root package.json for running both apps
|
||||
│ └── vite.config.js
|
||||
├── documents/ # Documentation (EN/ZH)
|
||||
├── docker-compose.yml # Compose for standard deployments
|
||||
├── docker-compose.host-network.yml # Host-network compose for OpenWrt/iStoreOS
|
||||
├── README.md
|
||||
├── README-zh.md
|
||||
└── package.json # Root scripts
|
||||
```
|
||||
|
||||
## Architecture Overview
|
||||
@@ -273,28 +88,25 @@ mytube/
|
||||
|
||||
The backend follows a **layered architecture** pattern:
|
||||
|
||||
1. **Routes Layer** (`routes/`): Defines API endpoints and maps them to controllers
|
||||
2. **Controllers Layer** (`controllers/`): Handles HTTP requests/responses and delegates to services
|
||||
3. **Services Layer** (`services/`): Contains business logic
|
||||
- **Downloaders**: Abstract base class pattern for platform-specific downloaders
|
||||
- **Storage Service**: Modular service split into focused modules
|
||||
- **Supporting Services**: Download management, subscriptions, metadata, etc.
|
||||
4. **Database Layer** (`db/`): Drizzle ORM with SQLite for data persistence
|
||||
5. **Utils Layer** (`utils/`): Shared utility functions
|
||||
1. **Routes** (`routes/`): Define API endpoints and map them to controllers
|
||||
2. **Controllers** (`controllers/`): HTTP request/response handling
|
||||
3. **Services** (`services/`): Business logic (downloaders, storage, cloud, subscriptions)
|
||||
4. **Database** (`db/`): Drizzle ORM + SQLite
|
||||
5. **Utilities** (`utils/`): Shared helpers and infrastructure
|
||||
|
||||
### Frontend Architecture
|
||||
|
||||
The frontend follows a **component-based architecture**:
|
||||
|
||||
1. **Pages** (`pages/`): Top-level route components
|
||||
2. **Components** (`components/`): Reusable UI components organized by feature
|
||||
3. **Contexts** (`contexts/`): React Context API for global state management
|
||||
4. **Hooks** (`hooks/`): Custom React hooks for reusable logic
|
||||
5. **Utils** (`utils/`): Helper functions and internationalization
|
||||
2. **Components** (`components/`): Feature-oriented UI building blocks
|
||||
3. **Contexts** (`contexts/`): React Context global state
|
||||
4. **Hooks** (`hooks/`): Reusable logic and data access
|
||||
5. **Utils** (`utils/`): API client, formatting, and i18n helpers
|
||||
|
||||
### Database Schema
|
||||
|
||||
The application uses **SQLite** with **Drizzle ORM** for data persistence. Key tables include:
|
||||
Key tables include:
|
||||
|
||||
- `videos`: Video metadata and file paths
|
||||
- `collections`: Video collections/playlists
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Docker Deployment Guide for MyTube
|
||||
|
||||
This guide provides step-by-step instructions to deploy [MyTube](https://github.com/franklioxygen/MyTube "null") using Docker and Docker Compose. This setup is designed for standard environments (Linux, macOS, Windows) and modifies the original QNAP-specific configurations for general use.
|
||||
This guide provides step-by-step instructions to deploy [MyTube](https://github.com/franklioxygen/MyTube "null") using Docker and Docker Compose. The repository includes QNAP-oriented compose files; update the volume paths to match your environment or use the sample below.
|
||||
|
||||
> [!NOTE]
|
||||
> **Multi-Architecture Support:** The official images support both **amd64** (x86_64) and **arm64** (Apple Silicon, Raspberry Pi, etc.) architectures. Docker will automatically pull the correct image for your system.
|
||||
@@ -22,7 +22,7 @@ cd mytube-deploy
|
||||
|
||||
Create a file named `docker-compose.yml` inside your folder and paste the following content.
|
||||
|
||||
**Note:** This version uses standard relative paths (`./data`, `./uploads`) instead of the QNAP-specific paths found in the original repository.
|
||||
**Note:** This version uses standard relative paths (`./data`, `./uploads`). If you copy the repo’s `docker-compose.yml`, update the volume paths to match your host.
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
@@ -39,8 +39,6 @@ services:
|
||||
- mytube-network
|
||||
environment:
|
||||
- PORT=5551
|
||||
# Optional: Set a custom upload directory inside container if needed
|
||||
# - VIDEO_DIR=/app/uploads/videos
|
||||
volumes:
|
||||
- ./uploads:/app/uploads
|
||||
- ./data:/app/data
|
||||
@@ -217,4 +215,10 @@ If you prefer to build the images yourself (e.g., to modify code), follow these
|
||||
2. Uncomment `network_mode: host` for both `backend` and `frontend`.
|
||||
3. Remove (or comment out) the `ports` and `networks` sections for both services.
|
||||
4. Set `NGINX_BACKEND_URL=http://localhost:5551` in the `frontend` environment variables.
|
||||
5. Restart containers: `docker-compose up -d`
|
||||
5. Restart containers: `docker-compose up -d`
|
||||
|
||||
Alternatively, the repo includes `docker-compose.host-network.yml` for host-network deployments:
|
||||
|
||||
```
|
||||
docker-compose -f docker-compose.host-network.yml up -d
|
||||
```
|
||||
|
||||
@@ -52,23 +52,21 @@ Create a `.env` file in the `backend/` directory:
|
||||
|
||||
```env
|
||||
PORT=5551
|
||||
UPLOAD_DIR=uploads
|
||||
VIDEO_DIR=uploads/videos
|
||||
IMAGE_DIR=uploads/images
|
||||
SUBTITLES_DIR=uploads/subtitles
|
||||
DATA_DIR=data
|
||||
MAX_FILE_SIZE=500000000
|
||||
```
|
||||
|
||||
Data and uploads are stored under `backend/data` and `backend/uploads` by default (relative to the backend working directory).
|
||||
|
||||
#### Frontend Configuration
|
||||
|
||||
Create a `.env` file in the `frontend/` directory:
|
||||
|
||||
```env
|
||||
VITE_API_URL=http://localhost:5551/api
|
||||
VITE_BACKEND_URL=http://localhost:5551
|
||||
VITE_API_URL=/api
|
||||
VITE_BACKEND_URL=
|
||||
```
|
||||
|
||||
`backend/.env.example` is provided. Copy it to `backend/.env` and adjust as needed. The frontend ships with `frontend/.env`; use `frontend/.env.local` to override defaults.
|
||||
|
||||
### 4. Database Setup
|
||||
|
||||
The application uses **SQLite** with **Drizzle ORM**. The database will be automatically created and migrated on first startup:
|
||||
@@ -92,7 +90,7 @@ This will start:
|
||||
- **Frontend**: http://localhost:5556 (Vite dev server with hot reload)
|
||||
- **Backend API**: http://localhost:5551 (Express server with nodemon)
|
||||
|
||||
### Production Mode
|
||||
### Production Mode (Local)
|
||||
|
||||
Build and start in production mode:
|
||||
|
||||
@@ -100,10 +98,19 @@ Build and start in production mode:
|
||||
# Build frontend
|
||||
npm run build
|
||||
|
||||
# Start both services
|
||||
# Start backend
|
||||
cd backend
|
||||
npm run start
|
||||
|
||||
# In another terminal, preview the frontend build
|
||||
cd frontend
|
||||
npm run preview
|
||||
```
|
||||
|
||||
For Docker-based production, follow the [Docker Deployment Guide](docker-guide.md).
|
||||
|
||||
`npm run start` at the repo root is a convenience command that runs the backend start script and the frontend dev server together.
|
||||
|
||||
### Individual Services
|
||||
|
||||
You can also run services individually:
|
||||
@@ -126,9 +133,12 @@ From the root directory:
|
||||
|
||||
```bash
|
||||
npm run dev # Start both frontend and backend in development mode
|
||||
npm run start # Start both frontend and backend in production mode
|
||||
npm run start # Start backend + frontend dev server (convenience)
|
||||
npm run build # Build the frontend for production
|
||||
npm run install:all # Install dependencies for root, frontend, and backend
|
||||
npm run test # Run frontend + backend tests
|
||||
npm run test:frontend # Run frontend tests
|
||||
npm run test:backend # Run backend tests
|
||||
```
|
||||
|
||||
Backend-specific scripts (from `backend/` directory):
|
||||
@@ -140,6 +150,7 @@ npm run build # Compile TypeScript to JavaScript
|
||||
npm run test # Run tests with Vitest
|
||||
npm run test:coverage # Run tests with coverage report
|
||||
npm run generate # Generate database migrations with Drizzle Kit
|
||||
npm run reset-password # Reset admin password via script
|
||||
```
|
||||
|
||||
Frontend-specific scripts (from `frontend/` directory):
|
||||
@@ -150,16 +161,18 @@ npm run build # Build for production
|
||||
npm run preview # Preview production build
|
||||
npm run lint # Run ESLint
|
||||
npm run test # Run tests with Vitest
|
||||
npm run test:coverage # Run tests with coverage report
|
||||
```
|
||||
|
||||
## First-Time Setup
|
||||
|
||||
1. **Access the Application**: Open http://localhost:5556 in your browser
|
||||
|
||||
2. **Set Up Password Protection** (Optional):
|
||||
2. **Set Up Login Protection** (Optional):
|
||||
|
||||
- Go to Settings → Security
|
||||
- Enable password protection and set a password
|
||||
- Enable login and set an admin password
|
||||
- Optionally register a passkey (WebAuthn)
|
||||
|
||||
3. **Configure Download Settings**:
|
||||
|
||||
@@ -183,12 +196,11 @@ npm run test # Run tests with Vitest
|
||||
- Test the connection to verify settings
|
||||
- Note: When enabled, videos will be automatically uploaded to cloud storage after download, and local files will be deleted
|
||||
|
||||
6. **Configure Visitor Mode** (Optional):
|
||||
6. **Configure Visitor User** (Optional):
|
||||
|
||||
- Go to Settings → General Settings
|
||||
- Enable "Visitor Mode (Read-only)" to allow viewing videos without modification capabilities
|
||||
- When enabled, all write operations (downloads, deletions, edits) are blocked
|
||||
- To disable visitor mode, you'll need to enter the website password
|
||||
- Go to Settings → Security
|
||||
- Enable "Visitor User" to allow read-only access
|
||||
- Set a visitor password for the read-only role
|
||||
|
||||
7. **Start Downloading**:
|
||||
- Enter a video URL in the download input
|
||||
|
||||
@@ -1,44 +1,43 @@
|
||||
# Task Hooks Guide
|
||||
|
||||
MyTube allows you to execute custom shell scripts at various stages of a download task's lifecycle. This feature is powerful for integrating MyTube with other systems, performing post-processing on downloaded files, or sending notifications.
|
||||
MyTube lets you execute custom shell scripts at different stages of a download task. This is useful for post-processing, notifications, or external integrations.
|
||||
|
||||
## available Hooks
|
||||
|
||||
You can configure commands for the following events:
|
||||
## Available Hooks
|
||||
|
||||
| Hook Name | Trigger Point | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| **Before Task Start** (`task_before_start`) | Before download begins | Executed immediately before the download process starts. Useful for setup or validation. |
|
||||
| **Task Success** (`task_success`) | After successful download | Executed after the file is successfully downloaded / merged, but **before** it is uploaded to cloud storage (if enabled) or deleted. This is the ideal place for file processing. |
|
||||
| **Task Failed** (`task_fail`) | On task failure | Executed if the download fails for any reason. |
|
||||
| **Task Cancelled** (`task_cancel`) | On task cancellation | Executed when a user manually cancels a running task. |
|
||||
| **Before Task Start** (`task_before_start`) | Before download begins | Runs right before the download starts. |
|
||||
| **Task Success** (`task_success`) | After successful download | Runs after download/merge completes but **before** cloud upload (if enabled) or deletion. |
|
||||
| **Task Failed** (`task_fail`) | On task failure | Runs when a download fails. |
|
||||
| **Task Cancelled** (`task_cancel`) | On task cancellation | Runs when a user cancels a running task. |
|
||||
|
||||
Hook scripts are stored under `backend/data/hooks` by default.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
When a hook command is executed, the following environment variables are injected into the shell environment, providing context about the task:
|
||||
|
||||
| Variable | Description | Example |
|
||||
| :--- | :--- | :--- |
|
||||
| `MYTUBE_TASK_ID` | The unique identifier of the task | `335e98f0-15cb-46a4-846d-9d4351368923` |
|
||||
| `MYTUBE_TASK_TITLE` | The title of the video/task | `Awesome Video Title` |
|
||||
| `MYTUBE_SOURCE_URL` | The original URL of the video | `https://www.youtube.com/watch?v=...` |
|
||||
| `MYTUBE_TASK_STATUS` | The current status of the task | `success`, `fail`, `cancelled` |
|
||||
| `MYTUBE_VIDEO_PATH` | Absolute path to the downloaded video file | `/app/downloads/video.mp4` |
|
||||
| `MYTUBE_THUMBNAIL_PATH` | Absolute path to the thumbnail file | `/app/downloads/video.jpg` |
|
||||
| `MYTUBE_TASK_ID` | Unique task ID | `335e98f0-15cb-46a4-846d-9d4351368923` |
|
||||
| `MYTUBE_TASK_TITLE` | Video/task title | `Awesome Video Title` |
|
||||
| `MYTUBE_SOURCE_URL` | Original video URL | `https://www.youtube.com/watch?v=...` |
|
||||
| `MYTUBE_TASK_STATUS` | Current status | `start`, `success`, `fail`, `cancel` |
|
||||
| `MYTUBE_VIDEO_PATH` | Absolute path to video file | `/app/uploads/videos/video.mp4` |
|
||||
| `MYTUBE_THUMBNAIL_PATH` | Absolute path to thumbnail | `/app/uploads/images/video.jpg` |
|
||||
| `MYTUBE_ERROR` | Error message (only for `task_fail`) | `Network timeout` |
|
||||
|
||||
## Configuration
|
||||
|
||||
You can configure hooks in the web interface:
|
||||
1. Go to **Settings**.
|
||||
2. Scroll down to **Advanced Settings**.
|
||||
3. Find the **Task Hooks** section.
|
||||
4. Upload your `.sh` scripts for the desired events.
|
||||
5. You can Delete or Re-upload scripts as needed.
|
||||
2. Open **Advanced Settings**.
|
||||
3. Find **Task Hooks**.
|
||||
4. Upload `.sh` scripts for the desired events.
|
||||
5. Delete or re-upload as needed.
|
||||
|
||||
Hooks are executed with `bash` and are made executable on upload.
|
||||
|
||||
## Viewing Logs
|
||||
|
||||
Any output from your script (stdout/stderr) will be captured and logged to the MyTube server console.
|
||||
Any output from your script (stdout/stderr) is captured and logged by the backend.
|
||||
- Standard output (`echo "..."`) is logged as `INFO`.
|
||||
- Standard error (`>&2 echo "..."`) is logged as `WARN`.
|
||||
|
||||
@@ -69,7 +68,7 @@ curl -d "MyTube Download Failed: $MYTUBE_TASK_TITLE - $MYTUBE_ERROR" https://ntf
|
||||
```
|
||||
|
||||
### 3. File Post-Processing
|
||||
Run a python script to process the file.
|
||||
Run a Python script to process the file.
|
||||
**Hook:** `task_success`
|
||||
```bash
|
||||
#!/bin/bash
|
||||
@@ -79,7 +78,7 @@ python3 /path/to/process_video.py "$MYTUBE_VIDEO_PATH"
|
||||
## Security Warning
|
||||
|
||||
> [!WARNING]
|
||||
> Hook commands are executed with the same permissions as the MyTube backend server.
|
||||
> Hook commands run with the same permissions as the MyTube backend.
|
||||
> - Be careful when using commands that modify or delete files.
|
||||
> - Do not copy-paste scripts from untrusted sources.
|
||||
> - Do not copy/paste scripts from untrusted sources.
|
||||
> - Ensure your scripts handle errors gracefully.
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
# API 端点
|
||||
|
||||
除特殊说明外,所有 API 路由均挂载在 `/api` 下。
|
||||
|
||||
## 视频下载与搜索
|
||||
|
||||
- `GET /api/search` - 在线搜索视频 (YouTube)
|
||||
- 查询参数: `query` (必需), `limit` (可选, 默认: 8), `offset` (可选, 默认: 1)
|
||||
- `POST /api/download` - 从支持的平台下载视频
|
||||
- 请求体: `{ url: string, ...options }`
|
||||
- 支持: YouTube, Bilibili, MissAV 以及所有 yt-dlp 支持的网站
|
||||
- 请求体: `{ youtubeUrl: string, ...options }`
|
||||
- 支持: YouTube、Bilibili、MissAV 以及所有 yt-dlp 支持的网站
|
||||
- `GET /api/check-video-download` - 检查视频是否已下载
|
||||
- 查询参数: `url` (必需)
|
||||
- 返回: `{ found: boolean, status: 'exists' | 'deleted', videoId?: string, ... }`
|
||||
@@ -15,10 +18,11 @@
|
||||
- 查询参数: `url` (必需)
|
||||
- `GET /api/check-playlist` - 检查 URL 是否为受支持的播放列表
|
||||
- 查询参数: `url` (必需)
|
||||
- `GET /api/download-status` - 获取活动下载的状态
|
||||
- 返回: `{ active: [], queued: [] }`
|
||||
- `GET /api/download-status` - 获取下载状态
|
||||
- 返回: `{ activeDownloads: DownloadInfo[], queuedDownloads: DownloadInfo[] }`
|
||||
|
||||
## 视频管理
|
||||
|
||||
- `POST /api/upload` - 上传本地视频文件
|
||||
- 多部分表单数据: `video` (文件)
|
||||
- 自动生成缩略图
|
||||
@@ -38,9 +42,9 @@
|
||||
- `GET /api/videos/author-channel-url` - 获取视频的作者频道 URL
|
||||
- 查询参数: `sourceUrl` (必需)
|
||||
- 返回: `{ success: boolean, channelUrl: string | null }`
|
||||
- 首先检查数据库,如果未找到则从 YouTube/Bilibili API 获取
|
||||
|
||||
## 下载管理
|
||||
|
||||
- `POST /api/downloads/cancel/:id` - 取消活动下载
|
||||
- `DELETE /api/downloads/queue/:id` - 从队列中移除下载
|
||||
- `DELETE /api/downloads/queue` - 清空整个下载队列
|
||||
@@ -50,6 +54,7 @@
|
||||
- `DELETE /api/downloads/history` - 清空整个下载历史
|
||||
|
||||
## 收藏夹
|
||||
|
||||
- `GET /api/collections` - 获取所有收藏夹
|
||||
- `POST /api/collections` - 创建新收藏夹
|
||||
- 请求体: `{ name: string, videoIds?: string[] }`
|
||||
@@ -58,6 +63,7 @@
|
||||
- `DELETE /api/collections/:id` - 删除收藏夹
|
||||
|
||||
## 订阅
|
||||
|
||||
- `GET /api/subscriptions` - 获取所有订阅
|
||||
- `POST /api/subscriptions` - 创建新订阅
|
||||
- 请求体: `{ authorUrl: string, interval: number, platform?: string }`
|
||||
@@ -70,30 +76,60 @@
|
||||
- `GET /api/subscriptions/tasks` - 获取所有持续下载任务
|
||||
- 查询参数: `page` (可选), `limit` (可选)
|
||||
- `POST /api/subscriptions/tasks/playlist` - 创建新的播放列表下载任务
|
||||
- Body: `{ url: string, ...options }`
|
||||
- 请求体: `{ url: string, ...options }`
|
||||
- `DELETE /api/subscriptions/tasks/:id` - 取消持续下载任务
|
||||
- `DELETE /api/subscriptions/tasks/:id/delete` - 删除任务记录
|
||||
- `DELETE /api/subscriptions/tasks/clear-finished` - 清除所有已完成的任务
|
||||
|
||||
## 设置与系统
|
||||
## 设置与密码
|
||||
|
||||
- `GET /api/settings` - 获取应用设置
|
||||
- `POST /api/settings` - 更新应用设置
|
||||
- 请求体: `{ [key: string]: any }` - 设置对象
|
||||
- 支持: `visitorMode`, `cloudDriveEnabled`, `openListApiUrl`, `openListToken`, `openListPublicUrl`, `cloudDrivePath` 及其他设置
|
||||
- `GET /api/settings/cloudflared/status` - 获取 Cloudflare Tunnel 状态
|
||||
- `GET /api/settings/password-enabled` - 检查是否启用了密码保护
|
||||
- `POST /api/settings/verify-password` - 验证登录密码
|
||||
- 请求体: `{ password: string }`
|
||||
- `POST /api/settings/reset-password` - 重置登录密码
|
||||
- 请求体: `{ oldPassword: string, newPassword: string }`
|
||||
- `POST /api/settings/migrate` - 从 JSON 迁移数据到 SQLite
|
||||
- `POST /api/settings/delete-legacy` - 删除旧的 JSON 数据文件
|
||||
- `POST /api/settings/format-filenames` - 根据设置格式化视频文件名
|
||||
- `GET /api/settings/password-enabled` - 检查是否启用了密码保护
|
||||
- `GET /api/settings/reset-password-cooldown` - 获取密码重置冷却时间
|
||||
- `POST /api/settings/verify-admin-password` - 验证管理员密码
|
||||
- 请求体: `{ password: string }`
|
||||
- `POST /api/settings/verify-visitor-password` - 验证访客密码
|
||||
- 请求体: `{ password: string }`
|
||||
- `POST /api/settings/verify-password` - 验证登录密码 (已废弃)
|
||||
- 请求体: `{ password: string }`
|
||||
- `POST /api/settings/reset-password` - 重置登录密码
|
||||
- 请求体: `{ oldPassword: string, newPassword: string }`
|
||||
- `POST /api/settings/logout` - 退出当前会话
|
||||
|
||||
## 通行密钥管理
|
||||
|
||||
- `GET /api/settings/passkeys` - 获取所有注册的通行密钥
|
||||
- `GET /api/settings/passkeys/exists` - 检查是否已注册任何通行密钥
|
||||
- `POST /api/settings/passkeys/register` - 开始通行密钥注册
|
||||
- `POST /api/settings/passkeys/register/verify` - 验证通行密钥注册
|
||||
- `POST /api/settings/passkeys/authenticate` - 开始通行密钥认证
|
||||
- `POST /api/settings/passkeys/authenticate/verify` - 验证通行密钥认证
|
||||
- `DELETE /api/settings/passkeys` - 删除所有通行密钥
|
||||
|
||||
## Cookies
|
||||
|
||||
- `POST /api/settings/upload-cookies` - 上传 cookies.txt 以供 yt-dlp 使用
|
||||
- 多部分表单数据: `file` (cookies.txt)
|
||||
- `POST /api/settings/delete-cookies` - 删除 cookies.txt
|
||||
- `GET /api/settings/check-cookies` - 检查 cookies.txt 是否存在
|
||||
- `GET /api/settings/export-database` - 导出数据库作为备份文件
|
||||
|
||||
## 任务钩子
|
||||
|
||||
- `GET /api/settings/hooks/status` - 获取所有钩子的状态
|
||||
- `POST /api/settings/hooks/:name` - 上传钩子脚本
|
||||
- 多部分表单数据: `file` (脚本文件)
|
||||
- 参数: `name` (钩子名称, 例如 `task_success`)
|
||||
- `DELETE /api/settings/hooks/:name` - 删除钩子脚本
|
||||
|
||||
## 数据库备份
|
||||
|
||||
- `GET /api/settings/export-database` - 导出数据库备份文件
|
||||
- `POST /api/settings/import-database` - 从备份文件导入数据库
|
||||
- 多部分表单数据: `file` (数据库备份文件)
|
||||
- `GET /api/settings/last-backup-info` - 获取最后一个数据库备份的信息
|
||||
@@ -101,10 +137,21 @@
|
||||
- `POST /api/settings/cleanup-backup-databases` - 清理旧的备份数据库文件
|
||||
|
||||
## 文件管理
|
||||
|
||||
- `POST /api/scan-files` - 扫描上传目录中的现有视频文件
|
||||
- `POST /api/cleanup-temp-files` - 清理临时下载文件
|
||||
|
||||
## 云存储
|
||||
- `GET /cloud/videos/:filename` - 代理端点,用于从云存储(OpenList/Alist)流式传输视频
|
||||
- `GET /cloud/images/:filename` - 代理端点,用于从云存储(OpenList/Alist)提供图像
|
||||
- 注意:这些端点需要在设置中配置云存储
|
||||
|
||||
- `GET /api/cloud/signed-url` - 获取云存储签名 URL
|
||||
- 查询参数: `filename` (必需), `type` (可选: `video` 或 `thumbnail`)
|
||||
- `POST /api/cloud/sync` - 同步本地视频到云存储 (以 JSON 行流式返回进度)
|
||||
- `DELETE /api/cloud/thumbnail-cache` - 清空缩略图缓存
|
||||
- `GET /api/cloud/thumbnail-cache/:filename` - 访问缓存的云端缩略图
|
||||
- `GET /cloud/videos/:filename` - 重定向到云端视频签名 URL
|
||||
- `GET /cloud/images/:filename` - 重定向到云端缩略图签名 URL(或本地缓存)
|
||||
|
||||
## 系统
|
||||
|
||||
- `GET /api/system/version` - 获取当前版本与最新版本信息
|
||||
- 返回: `{ currentVersion, latestVersion, releaseUrl, hasUpdate }`
|
||||
|
||||
@@ -2,305 +2,117 @@
|
||||
|
||||
```
|
||||
mytube/
|
||||
├── backend/ # Express.js 后端 (TypeScript)
|
||||
│ ├── src/ # 源代码
|
||||
│ │ ├── __tests__/ # 测试文件
|
||||
│ │ │ ├── controllers/ # 控制器测试
|
||||
│ │ │ ├── middleware/ # 中间件测试
|
||||
│ │ │ ├── services/ # 服务测试
|
||||
│ │ │ └── utils/ # 工具测试
|
||||
│ │ ├── config/ # 配置文件
|
||||
│ │ │ └── paths.ts # 路径配置
|
||||
│ │ ├── controllers/ # 路由控制器
|
||||
│ │ │ ├── cleanupController.ts # 清理操作
|
||||
├── backend/ # Express.js 后端 (TypeScript)
|
||||
│ ├── src/ # 源代码
|
||||
│ │ ├── __tests__/ # 测试文件
|
||||
│ │ ├── config/ # 配置(路径等)
|
||||
│ │ ├── controllers/ # 路由控制器
|
||||
│ │ │ ├── cleanupController.ts
|
||||
│ │ │ ├── cloudStorageController.ts
|
||||
│ │ │ ├── collectionController.ts
|
||||
│ │ │ ├── cookieController.ts
|
||||
│ │ │ ├── downloadController.ts
|
||||
│ │ │ ├── hookController.ts
|
||||
│ │ │ ├── passkeyController.ts
|
||||
│ │ │ ├── passwordController.ts
|
||||
│ │ │ ├── scanController.ts
|
||||
│ │ │ ├── settingsController.ts
|
||||
│ │ │ ├── subscriptionController.ts
|
||||
│ │ │ ├── systemController.ts
|
||||
│ │ │ ├── videoController.ts
|
||||
│ │ │ ├── videoDownloadController.ts
|
||||
│ │ │ └── videoMetadataController.ts
|
||||
│ │ ├── db/ # 数据库层
|
||||
│ │ │ ├── index.ts # 数据库连接 (Drizzle ORM)
|
||||
│ │ │ ├── migrate.ts # 迁移运行器
|
||||
│ │ │ └── schema.ts # 数据库模式定义
|
||||
│ │ ├── errors/ # 自定义错误类
|
||||
│ │ │ └── DownloadErrors.ts
|
||||
│ │ ├── middleware/ # Express 中间件
|
||||
│ │ │ ├── errorHandler.ts # 错误处理中间件
|
||||
│ │ │ ├── visitorModeMiddleware.ts # 访客模式(只读)中间件
|
||||
│ │ │ └── visitorModeSettingsMiddleware.ts # 访客模式设置中间件
|
||||
│ │ ├── routes/ # API 路由定义
|
||||
│ │ │ ├── api.ts # 主 API 路由
|
||||
│ │ │ └── settingsRoutes.ts # 设置相关路由
|
||||
│ │ ├── scripts/ # 实用脚本
|
||||
│ │ │ ├── cleanVttFiles.ts
|
||||
│ │ │ └── rescanSubtitles.ts
|
||||
│ │ ├── services/ # 业务逻辑服务
|
||||
│ │ │ ├── downloaders/ # 下载器实现
|
||||
│ │ │ │ ├── BaseDownloader.ts # 抽象基类
|
||||
│ │ │ │ ├── BilibiliDownloader.ts
|
||||
│ │ │ │ ├── MissAVDownloader.ts
|
||||
│ │ │ │ ├── YtDlpDownloader.ts
|
||||
│ │ │ │ ├── bilibili/ # Bilibili 特定模块
|
||||
│ │ │ │ │ ├── bilibiliApi.ts
|
||||
│ │ │ │ │ ├── bilibiliCollection.ts
|
||||
│ │ │ │ │ ├── bilibiliCookie.ts
|
||||
│ │ │ │ │ ├── bilibiliSubtitle.ts
|
||||
│ │ │ │ │ ├── bilibiliVideo.ts
|
||||
│ │ │ │ │ └── types.ts
|
||||
│ │ │ │ └── ytdlp/ # yt-dlp 特定模块
|
||||
│ │ │ │ ├── types.ts
|
||||
│ │ │ │ ├── ytdlpChannel.ts
|
||||
│ │ │ │ ├── ytdlpConfig.ts
|
||||
│ │ │ │ ├── ytdlpHelpers.ts
|
||||
│ │ │ │ ├── ytdlpMetadata.ts
|
||||
│ │ │ │ ├── ytdlpSearch.ts
|
||||
│ │ │ │ ├── ytdlpSubtitle.ts
|
||||
│ │ │ │ └── ytdlpVideo.ts
|
||||
│ │ │ ├── storageService/ # 模块化存储服务
|
||||
│ │ │ │ ├── index.ts # 主导出文件
|
||||
│ │ │ │ ├── types.ts # 类型定义
|
||||
│ │ │ │ ├── initialization.ts # 数据库初始化
|
||||
│ │ │ │ ├── downloadStatus.ts # 活动/队列下载
|
||||
│ │ │ │ ├── downloadHistory.ts # 下载历史
|
||||
│ │ │ │ ├── videoDownloadTracking.ts # 重复下载预防
|
||||
│ │ │ │ ├── settings.ts # 应用设置
|
||||
│ │ │ │ ├── videos.ts # 视频 CRUD 操作
|
||||
│ │ │ │ ├── collections.ts # 收藏夹操作
|
||||
│ │ │ │ └── fileHelpers.ts # 文件系统工具
|
||||
│ │ │ ├── CloudStorageService.ts
|
||||
│ │ │ ├── commentService.ts
|
||||
│ │ │ ├── downloadManager.ts # 下载队列管理
|
||||
│ │ │ ├── downloadService.ts
|
||||
│ │ │ ├── loginAttemptService.ts
|
||||
│ │ │ ├── metadataService.ts
|
||||
│ │ │ ├── migrationService.ts
|
||||
│ │ │ ├── storageService.ts # 向后兼容导出
|
||||
│ │ │ ├── subscriptionService.ts
|
||||
│ │ │ ├── subtitleService.ts
|
||||
│ │ │ └── thumbnailService.ts
|
||||
│ │ ├── utils/ # 工具函数
|
||||
│ │ │ ├── bccToVtt.ts # 字幕转换
|
||||
│ │ │ ├── downloadUtils.ts
|
||||
│ │ │ ├── helpers.ts
|
||||
│ │ │ ├── logger.ts
|
||||
│ │ │ ├── progressTracker.ts
|
||||
│ │ │ ├── response.ts
|
||||
│ │ │ └── ytDlpUtils.ts
|
||||
│ │ ├── server.ts # 主服务器文件
|
||||
│ │ └── version.ts # 版本信息
|
||||
│ ├── bgutil-ytdlp-pot-provider/ # PO Token 提供者插件
|
||||
│ │ ├── plugin/ # Python 插件
|
||||
│ │ │ └── yt_dlp_plugins/
|
||||
│ │ └── server/ # TypeScript 服务器
|
||||
│ │ └── src/
|
||||
│ ├── data/ # 数据目录
|
||||
│ │ ├── mytube.db # SQLite 数据库
|
||||
│ │ ├── cookies.txt # yt-dlp cookies (可选)
|
||||
│ │ └── login-attempts.json # 登录尝试跟踪
|
||||
│ ├── drizzle/ # 数据库迁移
|
||||
│ │ └── meta/ # 迁移元数据
|
||||
│ ├── uploads/ # 上传文件目录
|
||||
│ │ ├── videos/ # 下载的视频
|
||||
│ │ ├── images/ # 下载的缩略图
|
||||
│ │ └── subtitles/ # 下载的字幕
|
||||
│ ├── dist/ # 编译后的 JavaScript
|
||||
│ ├── coverage/ # 测试覆盖率报告
|
||||
│ ├── Dockerfile # 后端 Docker 镜像
|
||||
│ ├── drizzle.config.ts # Drizzle ORM 配置
|
||||
│ ├── nodemon.json # Nodemon 配置
|
||||
│ ├── package.json # 后端依赖
|
||||
│ ├── tsconfig.json # TypeScript 配置
|
||||
│ └── vitest.config.ts # Vitest 测试配置
|
||||
├── frontend/ # React.js 前端 (Vite + TypeScript)
|
||||
│ ├── src/ # 源代码
|
||||
│ │ ├── __tests__/ # 测试文件
|
||||
│ │ ├── assets/ # 静态资源
|
||||
│ │ │ └── logo.svg
|
||||
│ │ ├── components/ # React 组件
|
||||
│ │ │ ├── Header/ # 头部组件组
|
||||
│ │ │ │ ├── ActionButtons.tsx
|
||||
│ │ │ │ ├── DownloadsMenu.tsx
|
||||
│ │ │ │ ├── index.tsx
|
||||
│ │ │ │ ├── Logo.tsx
|
||||
│ │ │ │ ├── ManageMenu.tsx
|
||||
│ │ │ │ ├── MobileMenu.tsx
|
||||
│ │ │ │ ├── SearchInput.tsx
|
||||
│ │ │ │ └── types.ts
|
||||
│ │ │ ├── ManagePage/ # 管理页面组件
|
||||
│ │ │ │ ├── CollectionsTable.tsx
|
||||
│ │ │ │ └── VideosTable.tsx
|
||||
│ │ │ ├── Settings/ # 设置页面组件
|
||||
│ │ │ │ ├── AdvancedSettings.tsx
|
||||
│ │ │ │ ├── CloudDriveSettings.tsx
|
||||
│ │ │ │ ├── CookieSettings.tsx
|
||||
│ │ │ │ ├── DatabaseSettings.tsx
|
||||
│ │ │ │ ├── DownloadSettings.tsx
|
||||
│ │ │ │ ├── GeneralSettings.tsx
|
||||
│ │ │ │ ├── SecuritySettings.tsx
|
||||
│ │ │ │ ├── TagsSettings.tsx
|
||||
│ │ │ │ ├── VideoDefaultSettings.tsx
|
||||
│ │ │ │ └── YtDlpSettings.tsx
|
||||
│ │ │ ├── VideoPlayer/ # 视频播放器组件
|
||||
│ │ │ │ ├── CommentsSection.tsx
|
||||
│ │ │ │ ├── UpNextSidebar.tsx
|
||||
│ │ │ │ ├── VideoControls.tsx
|
||||
│ │ │ │ ├── VideoInfo.tsx
|
||||
│ │ │ │ └── VideoInfo/ # 视频信息子组件
|
||||
│ │ │ │ ├── EditableTitle.tsx
|
||||
│ │ │ │ ├── VideoActionButtons.tsx
|
||||
│ │ │ │ ├── VideoAuthorInfo.tsx
|
||||
│ │ │ │ ├── VideoDescription.tsx
|
||||
│ │ │ │ ├── VideoMetadata.tsx
|
||||
│ │ │ │ ├── VideoRating.tsx
|
||||
│ │ │ │ └── VideoTags.tsx
|
||||
│ │ │ ├── AlertModal.tsx
|
||||
│ │ │ ├── AnimatedRoutes.tsx
|
||||
│ │ │ ├── AuthorsList.tsx
|
||||
│ │ │ ├── BatchDownloadModal.tsx
|
||||
│ │ │ ├── BilibiliPartsModal.tsx
|
||||
│ │ │ ├── CollectionCard.tsx
|
||||
│ │ │ ├── CollectionModal.tsx
|
||||
│ │ │ ├── Collections.tsx
|
||||
│ │ │ ├── ConfirmationModal.tsx
|
||||
│ │ │ ├── DeleteCollectionModal.tsx
|
||||
│ │ │ ├── Disclaimer.tsx
|
||||
│ │ │ ├── Footer.tsx
|
||||
│ │ │ ├── PageTransition.tsx
|
||||
│ │ │ ├── SubscribeModal.tsx
|
||||
│ │ │ ├── TagsList.tsx
|
||||
│ │ │ ├── UploadModal.tsx
|
||||
│ │ │ └── VideoCard.tsx
|
||||
│ │ ├── contexts/ # React 上下文用于状态管理
|
||||
│ │ │ ├── AuthContext.tsx
|
||||
│ │ │ ├── CollectionContext.tsx
|
||||
│ │ │ ├── DownloadContext.tsx
|
||||
│ │ │ ├── LanguageContext.tsx
|
||||
│ │ │ ├── SnackbarContext.tsx
|
||||
│ │ │ ├── ThemeContext.tsx
|
||||
│ │ │ └── VideoContext.tsx
|
||||
│ │ ├── hooks/ # 自定义 React hooks
|
||||
│ │ │ ├── useDebounce.ts
|
||||
│ │ │ ├── useShareVideo.ts
|
||||
│ │ │ └── useVideoResolution.ts
|
||||
│ │ ├── pages/ # 页面组件
|
||||
│ │ │ ├── AuthorVideos.tsx
|
||||
│ │ │ ├── CollectionPage.tsx
|
||||
│ │ │ ├── DownloadPage/ # 下载页面组件
|
||||
│ │ │ │ ├── ActiveDownloadsTab.tsx
|
||||
│ │ │ │ ├── CustomTabPanel.tsx
|
||||
│ │ │ │ ├── HistoryItem.tsx
|
||||
│ │ │ │ ├── HistoryTab.tsx
|
||||
│ │ │ │ ├── index.tsx
|
||||
│ │ │ │ └── QueueTab.tsx
|
||||
│ │ │ ├── Home.tsx
|
||||
│ │ │ ├── InstructionPage.tsx
|
||||
│ │ │ ├── LoginPage.tsx
|
||||
│ │ │ ├── ManagePage.tsx
|
||||
│ │ │ ├── SearchPage.tsx
|
||||
│ │ │ ├── SearchResults.tsx
|
||||
│ │ │ ├── SettingsPage.tsx
|
||||
│ │ │ ├── SubscriptionsPage.tsx
|
||||
│ │ │ └── VideoPlayer.tsx
|
||||
│ │ ├── utils/ # 工具和多语言
|
||||
│ │ │ ├── locales/ # 国际化文件
|
||||
│ │ │ │ ├── ar.ts # 阿拉伯语
|
||||
│ │ │ │ ├── de.ts # 德语
|
||||
│ │ │ │ ├── en.ts # 英语
|
||||
│ │ │ │ ├── es.ts # 西班牙语
|
||||
│ │ │ │ ├── fr.ts # 法语
|
||||
│ │ │ │ ├── ja.ts # 日语
|
||||
│ │ │ │ ├── ko.ts # 韩语
|
||||
│ │ │ │ ├── pt.ts # 葡萄牙语
|
||||
│ │ │ │ ├── ru.ts # 俄语
|
||||
│ │ │ │ └── zh.ts # 中文
|
||||
│ │ │ ├── consoleManager.ts
|
||||
│ │ │ ├── constants.ts
|
||||
│ │ │ ├── formatUtils.ts
|
||||
│ │ │ ├── recommendations.ts
|
||||
│ │ │ └── translations.ts
|
||||
│ │ ├── App.tsx # 主应用组件
|
||||
│ │ ├── App.css
|
||||
│ │ ├── index.css
|
||||
│ │ ├── main.tsx # 应用入口点
|
||||
│ │ ├── setupTests.ts
|
||||
│ │ ├── theme.ts # Material-UI 主题配置
|
||||
│ │ ├── types.ts # TypeScript 类型定义
|
||||
│ │ ├── version.ts # 版本信息
|
||||
│ │ └── vite-env.d.ts
|
||||
│ ├── dist/ # 生产构建输出
|
||||
│ ├── public/ # 公共静态文件
|
||||
│ ├── Dockerfile # 前端 Docker 镜像
|
||||
│ ├── entrypoint.sh # Docker 入口脚本
|
||||
│ ├── eslint.config.js # ESLint 配置
|
||||
│ ├── index.html # HTML 模板
|
||||
│ ├── nginx.conf # Nginx 配置
|
||||
│ ├── package.json # 前端依赖
|
||||
│ ├── tsconfig.json # TypeScript 配置
|
||||
│ │ ├── db/ # Drizzle ORM + SQLite
|
||||
│ │ ├── errors/ # 自定义错误类
|
||||
│ │ ├── middleware/ # Express 中间件
|
||||
│ │ │ ├── authMiddleware.ts
|
||||
│ │ │ ├── roleBasedAuthMiddleware.ts
|
||||
│ │ │ ├── roleBasedSettingsMiddleware.ts
|
||||
│ │ │ └── errorHandler.ts
|
||||
│ │ ├── routes/ # 路由定义
|
||||
│ │ │ ├── api.ts # 主 API 路由
|
||||
│ │ │ └── settingsRoutes.ts # 设置相关路由
|
||||
│ │ ├── scripts/ # 工具脚本 (VTT 清理、字幕重扫)
|
||||
│ │ ├── services/ # 业务逻辑
|
||||
│ │ │ ├── cloudStorage/ # 云存储相关与缓存
|
||||
│ │ │ ├── continuousDownload/ # 订阅任务引擎
|
||||
│ │ │ ├── downloaders/ # 平台下载器 (yt-dlp、Bilibili、MissAV)
|
||||
│ │ │ ├── storageService/ # 模块化存储服务
|
||||
│ │ │ └── *.ts # 其他服务 (auth、metadata 等)
|
||||
│ │ ├── utils/ # 工具函数
|
||||
│ │ ├── server.ts # 服务器入口
|
||||
│ │ └── version.ts # 版本信息
|
||||
│ ├── bgutil-ytdlp-pot-provider/ # PO Token 提供者插件
|
||||
│ ├── data/ # 运行数据 (数据库、hooks、备份)
|
||||
│ ├── drizzle/ # 数据库迁移
|
||||
│ ├── uploads/ # 媒体存储 (videos/images/subtitles/cache)
|
||||
│ ├── scripts/ # 维护脚本 (reset-password、migrate、verify)
|
||||
│ ├── Dockerfile
|
||||
│ ├── drizzle.config.ts
|
||||
│ ├── nodemon.json
|
||||
│ ├── package.json
|
||||
│ ├── tsconfig.json
|
||||
│ └── vitest.config.ts
|
||||
├── frontend/ # React 前端 (Vite + TypeScript)
|
||||
│ ├── src/ # 源代码
|
||||
│ │ ├── __tests__/ # 测试文件
|
||||
│ │ ├── assets/ # 静态资源
|
||||
│ │ ├── components/ # 按功能划分的 UI 组件
|
||||
│ │ ├── contexts/ # React Context 状态
|
||||
│ │ ├── hooks/ # 自定义 hooks (播放器、设置、数据)
|
||||
│ │ ├── pages/ # 路由页面
|
||||
│ │ ├── utils/ # API 客户端、工具、多语言
|
||||
│ │ ├── App.tsx
|
||||
│ │ ├── main.tsx
|
||||
│ │ ├── theme.ts
|
||||
│ │ └── version.ts
|
||||
│ ├── public/ # 公共静态资源
|
||||
│ ├── Dockerfile
|
||||
│ ├── entrypoint.sh
|
||||
│ ├── nginx.conf
|
||||
│ ├── package.json
|
||||
│ ├── tsconfig.json
|
||||
│ ├── tsconfig.node.json
|
||||
│ └── vite.config.js # Vite 配置
|
||||
├── documents/ # 文档
|
||||
│ ├── en/ # 英文文档
|
||||
│ │ ├── api-endpoints.md
|
||||
│ │ ├── directory-structure.md
|
||||
│ │ ├── docker-guide.md
|
||||
│ │ └── getting-started.md
|
||||
│ └── zh/ # 中文文档
|
||||
│ ├── api-endpoints.md
|
||||
│ ├── directory-structure.md
|
||||
│ ├── docker-guide.md
|
||||
│ └── getting-started.md
|
||||
├── data/ # 根数据目录 (可选)
|
||||
│ └── mytube.db
|
||||
├── build-and-push.sh # Docker 构建和推送脚本
|
||||
├── docker-compose.yml # Docker Compose 配置
|
||||
├── CHANGELOG.md # 更新日志
|
||||
├── CODE_OF_CONDUCT.md # 行为准则
|
||||
├── CONTRIBUTING.md # 贡献指南
|
||||
├── LICENSE # MIT 许可证
|
||||
├── README.md # 英文 README
|
||||
├── README-zh.md # 中文 README
|
||||
├── RELEASING.md # 发布流程指南
|
||||
├── SECURITY.md # 安全策略
|
||||
└── package.json # 运行两个应用的根 package.json
|
||||
│ └── vite.config.js
|
||||
├── documents/ # 文档 (EN/ZH)
|
||||
├── docker-compose.yml # 标准部署 Compose
|
||||
├── docker-compose.host-network.yml # OpenWrt/iStoreOS 的 host 网络 Compose
|
||||
├── README.md
|
||||
├── README-zh.md
|
||||
└── package.json # 根目录脚本
|
||||
```
|
||||
|
||||
## 架构概述
|
||||
|
||||
### 后端架构
|
||||
|
||||
后端遵循**分层架构**模式:
|
||||
后端遵循 **分层架构**:
|
||||
|
||||
1. **路由层** (`routes/`): 定义 API 端点并将其映射到控制器
|
||||
2. **控制器层** (`controllers/`): 处理 HTTP 请求/响应并委托给服务
|
||||
3. **服务层** (`services/`): 包含业务逻辑
|
||||
- **下载器**: 用于平台特定下载器的抽象基类模式
|
||||
- **存储服务**: 拆分为专注模块的模块化服务
|
||||
- **支持服务**: 下载管理、订阅、元数据等
|
||||
4. **数据库层** (`db/`): 使用 Drizzle ORM 和 SQLite 进行数据持久化
|
||||
5. **工具层** (`utils/`): 共享工具函数
|
||||
1. **Routes** (`routes/`): 定义 API 端点并映射到控制器
|
||||
2. **Controllers** (`controllers/`): 处理 HTTP 请求/响应
|
||||
3. **Services** (`services/`): 业务逻辑(下载器、存储、云存储、订阅等)
|
||||
4. **Database** (`db/`): Drizzle ORM + SQLite
|
||||
5. **Utils** (`utils/`): 通用工具与基础设施
|
||||
|
||||
### 前端架构
|
||||
|
||||
前端遵循**基于组件的架构**:
|
||||
前端遵循 **组件化架构**:
|
||||
|
||||
1. **页面** (`pages/`): 顶级路由组件
|
||||
2. **组件** (`components/`): 按功能组织的可重用 UI 组件
|
||||
3. **上下文** (`contexts/`): 用于全局状态管理的 React Context API
|
||||
4. **Hooks** (`hooks/`): 用于可重用逻辑的自定义 React hooks
|
||||
5. **工具** (`utils/`): 辅助函数和国际化
|
||||
1. **Pages** (`pages/`): 顶级路由组件
|
||||
2. **Components** (`components/`): 以功能划分的 UI 组件
|
||||
3. **Contexts** (`contexts/`): React Context 全局状态
|
||||
4. **Hooks** (`hooks/`): 可复用逻辑和数据访问
|
||||
5. **Utils** (`utils/`): API、格式化和多语言辅助
|
||||
|
||||
### 数据库模式
|
||||
|
||||
应用程序使用 **SQLite** 和 **Drizzle ORM** 进行数据持久化。关键表包括:
|
||||
关键表包括:
|
||||
|
||||
- `videos`: 视频元数据和文件路径
|
||||
- `collections`: 视频收藏夹/播放列表
|
||||
- `collection_videos`: 视频和收藏夹之间的多对多关系
|
||||
- `collection_videos`: 视频与收藏夹的多对多关系
|
||||
- `subscriptions`: 频道/创作者订阅
|
||||
- `downloads`: 活动下载队列
|
||||
- `download_history`: 完成的下载历史
|
||||
- `video_downloads`: 跟踪已下载的视频以防止重复
|
||||
- `settings`: 应用程序配置
|
||||
- `video_downloads`: 跟踪已下载视频以防止重复
|
||||
- `settings`: 应用配置
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# MyTube Docker 部署指南
|
||||
|
||||
本指南提供了使用 Docker 和 Docker Compose 部署 [MyTube](https://github.com/franklioxygen/MyTube "null") 的详细步骤。此设置适用于标准环境(Linux, macOS, Windows),并针对通用用途修改了原本专用于 QNAP 的配置。
|
||||
本指南提供了使用 Docker 和 Docker Compose 部署 [MyTube](https://github.com/franklioxygen/MyTube "null") 的详细步骤。仓库中包含面向 QNAP 的 Compose 文件,请按需调整卷路径,或直接使用下面的通用示例。
|
||||
|
||||
> [!NOTE] > **多架构支持:** 官方镜像支持 **amd64** (x86_64) 和 **arm64** (Apple Silicon, Raspberry Pi 等) 架构。Docker 会自动为您的系统拉取正确的镜像。
|
||||
|
||||
@@ -21,7 +21,7 @@ cd mytube-deploy
|
||||
|
||||
在文件夹中创建一个名为 `docker-compose.yml` 的文件,并粘贴以下内容。
|
||||
|
||||
**注意:** 此版本使用标准的相对路径(`./data`, `./uploads`),而不是原始仓库中特定于 QNAP 的路径。
|
||||
**注意:** 此版本使用标准相对路径(`./data`, `./uploads`)。若使用仓库内的 `docker-compose.yml`,请先调整卷路径。
|
||||
|
||||
```yaml
|
||||
version: "3.8"
|
||||
@@ -38,8 +38,6 @@ services:
|
||||
- mytube-network
|
||||
environment:
|
||||
- PORT=5551
|
||||
# 可选:如果需要,在容器内设置自定义上传目录
|
||||
# - VIDEO_DIR=/app/uploads/videos
|
||||
volumes:
|
||||
- ./uploads:/app/uploads
|
||||
- ./data:/app/data
|
||||
@@ -204,3 +202,9 @@ docker-compose up -d
|
||||
3. 删除(或注释掉)两个服务的 `ports` 和 `networks` 部分。
|
||||
4. 在 `frontend` 环境变量中设置 `NGINX_BACKEND_URL=http://localhost:5551`。
|
||||
5. 重启容器:`docker-compose up -d`
|
||||
|
||||
或者直接使用仓库提供的 `docker-compose.host-network.yml`:
|
||||
|
||||
```
|
||||
docker-compose -f docker-compose.host-network.yml up -d
|
||||
```
|
||||
|
||||
@@ -52,23 +52,21 @@ pipx inject yt-dlp bgutil-ytdlp-pot-provider
|
||||
|
||||
```env
|
||||
PORT=5551
|
||||
UPLOAD_DIR=uploads
|
||||
VIDEO_DIR=uploads/videos
|
||||
IMAGE_DIR=uploads/images
|
||||
SUBTITLES_DIR=uploads/subtitles
|
||||
DATA_DIR=data
|
||||
MAX_FILE_SIZE=500000000
|
||||
```
|
||||
|
||||
默认数据与上传路径位于 `backend/data` 和 `backend/uploads`(相对于后端工作目录)。
|
||||
|
||||
#### 前端配置
|
||||
|
||||
在 `frontend/` 目录中创建 `.env` 文件:
|
||||
|
||||
```env
|
||||
VITE_API_URL=http://localhost:5551/api
|
||||
VITE_BACKEND_URL=http://localhost:5551
|
||||
VITE_API_URL=/api
|
||||
VITE_BACKEND_URL=
|
||||
```
|
||||
|
||||
项目提供 `backend/.env.example`,请复制为 `backend/.env` 并按需调整。前端已提供 `frontend/.env`,如需覆盖默认值请使用 `frontend/.env.local`。
|
||||
|
||||
### 4. 数据库设置
|
||||
|
||||
应用程序使用 **SQLite** 和 **Drizzle ORM**。数据库将在首次启动时自动创建和迁移:
|
||||
@@ -92,7 +90,7 @@ npm run dev
|
||||
- **前端**: http://localhost:5556 (带热重载的 Vite 开发服务器)
|
||||
- **后端 API**: http://localhost:5551 (带 nodemon 的 Express 服务器)
|
||||
|
||||
### 生产模式
|
||||
### 生产模式 (本地)
|
||||
|
||||
构建并以生产模式启动:
|
||||
|
||||
@@ -100,10 +98,19 @@ npm run dev
|
||||
# 构建前端
|
||||
npm run build
|
||||
|
||||
# 启动两个服务
|
||||
# 启动后端
|
||||
cd backend
|
||||
npm run start
|
||||
|
||||
# 在另一个终端预览前端构建
|
||||
cd frontend
|
||||
npm run preview
|
||||
```
|
||||
|
||||
生产环境建议参考 [Docker 部署指南](docker-guide.md)。
|
||||
|
||||
根目录的 `npm run start` 为便捷命令,会同时运行后端启动脚本和前端开发服务器。
|
||||
|
||||
### 单独运行服务
|
||||
|
||||
您也可以单独运行服务:
|
||||
@@ -126,9 +133,12 @@ npm run preview # 预览生产构建
|
||||
|
||||
```bash
|
||||
npm run dev # 以开发模式启动前端和后端
|
||||
npm run start # 以生产模式启动前端和后端
|
||||
npm run start # 启动后端 + 前端开发服务器 (便捷)
|
||||
npm run build # 为生产环境构建前端
|
||||
npm run install:all # 安装根目录、前端和后端的依赖
|
||||
npm run test # 运行前后端测试
|
||||
npm run test:frontend # 运行前端测试
|
||||
npm run test:backend # 运行后端测试
|
||||
```
|
||||
|
||||
后端特定脚本 (从 `backend/` 目录):
|
||||
@@ -140,6 +150,7 @@ npm run build # 将 TypeScript 编译为 JavaScript
|
||||
npm run test # 使用 Vitest 运行测试
|
||||
npm run test:coverage # 运行测试并生成覆盖率报告
|
||||
npm run generate # 使用 Drizzle Kit 生成数据库迁移
|
||||
npm run reset-password # 使用脚本重置管理员密码
|
||||
```
|
||||
|
||||
前端特定脚本 (从 `frontend/` 目录):
|
||||
@@ -150,16 +161,18 @@ npm run build # 为生产环境构建
|
||||
npm run preview # 预览生产构建
|
||||
npm run lint # 运行 ESLint
|
||||
npm run test # 使用 Vitest 运行测试
|
||||
npm run test:coverage # 运行测试并生成覆盖率报告
|
||||
```
|
||||
|
||||
## 首次设置
|
||||
|
||||
1. **访问应用**: 在浏览器中打开 http://localhost:5556
|
||||
|
||||
2. **设置密码保护** (可选):
|
||||
2. **设置登录保护** (可选):
|
||||
|
||||
- 转到设置 → 安全
|
||||
- 启用密码保护并设置密码
|
||||
- 启用登录并设置管理员密码
|
||||
- 可选:注册通行密钥 (WebAuthn)
|
||||
|
||||
3. **配置下载设置**:
|
||||
|
||||
@@ -183,12 +196,11 @@ npm run test # 使用 Vitest 运行测试
|
||||
- 测试连接以验证设置
|
||||
- 注意:启用后,视频将在下载后自动上传到云存储,本地文件将被删除
|
||||
|
||||
6. **配置访客模式** (可选):
|
||||
6. **配置访客用户** (可选):
|
||||
|
||||
- 转到设置 → 常规设置
|
||||
- 启用"访客模式(只读)"以允许查看视频但无法进行修改
|
||||
- 启用后,所有写入操作(下载、删除、编辑)将被阻止
|
||||
- 要禁用访客模式,您需要输入网站密码
|
||||
- 转到设置 → 安全
|
||||
- 启用“访客用户”以获得只读访问
|
||||
- 为访客角色设置登录密码
|
||||
|
||||
7. **开始下载**:
|
||||
- 在下载输入框中输入视频 URL
|
||||
|
||||
@@ -1,44 +1,43 @@
|
||||
# 任务钩子使用指南 (Task Hooks Guide)
|
||||
|
||||
MyTube允许您在下载任务生命周期的不同阶段执行自定义Shell脚本。此功能对于与其他系统集成、对下载的文件进行后处理或发送通知非常有用。
|
||||
MyTube 允许您在下载任务的不同阶段执行自定义 Shell 脚本,用于后处理、通知或外部集成。
|
||||
|
||||
## 可用钩子 (Available Hooks)
|
||||
|
||||
您可以为以下事件配置命令:
|
||||
|
||||
| 钩子名称 | 触发时机 | 描述 |
|
||||
| :--- | :--- | :--- |
|
||||
| **任务开始前** (`task_before_start`) | 下载开始前 | 在下载过程开始之前立即执行。适用于设置或验证。 |
|
||||
| **任务成功** (`task_success`) | 下载成功后 | 在文件成功下载/合并后,但在上传到云存储(如果启用)或删除之前执行。这是文件处理的理想位置。 |
|
||||
| **任务失败** (`task_fail`) | 任务失败时 | 如果下载因任何原因失败,则执行此钩子。 |
|
||||
| **任务取消** (`task_cancel`) | 任务取消时 | 当用户手动取消正在运行的任务时执行。 |
|
||||
| **任务开始前** (`task_before_start`) | 下载开始前 | 在下载开始前立即执行。 |
|
||||
| **任务成功** (`task_success`) | 下载成功后 | 下载/合并完成后执行,且在云存储上传(若启用)或删除之前执行。 |
|
||||
| **任务失败** (`task_fail`) | 任务失败时 | 下载失败时执行。 |
|
||||
| **任务取消** (`task_cancel`) | 任务取消时 | 用户取消正在运行的任务时执行。 |
|
||||
|
||||
默认脚本目录为 `backend/data/hooks`。
|
||||
|
||||
## 环境变量 (Environment Variables)
|
||||
|
||||
当钩子命令执行时,以下环境变量将被注入到Shell环境,提供有关任务的上下文:
|
||||
|
||||
| 变量 | 描述 | 示例 |
|
||||
| :--- | :--- | :--- |
|
||||
| `MYTUBE_TASK_ID` | 任务的唯一标识符 | `335e98f0-15cb-46a4-846d-9d4351368923` |
|
||||
| `MYTUBE_TASK_TITLE` | 视频/任务的标题 | `Awesome Video Title` |
|
||||
| `MYTUBE_SOURCE_URL` | 视频的原始URL | `https://www.youtube.com/watch?v=...` |
|
||||
| `MYTUBE_TASK_STATUS` | 任务的当前状态 | `success`, `fail`, `cancelled` |
|
||||
| `MYTUBE_VIDEO_PATH` | 下载视频文件的绝对路径 | `/app/downloads/video.mp4` |
|
||||
| `MYTUBE_THUMBNAIL_PATH` | 缩略图文件的绝对路径 | `/app/downloads/video.jpg` |
|
||||
| `MYTUBE_ERROR` | 错误消息(仅限 `task_fail`) | `Network timeout` |
|
||||
| `MYTUBE_TASK_ID` | 任务唯一标识 | `335e98f0-15cb-46a4-846d-9d4351368923` |
|
||||
| `MYTUBE_TASK_TITLE` | 视频/任务标题 | `Awesome Video Title` |
|
||||
| `MYTUBE_SOURCE_URL` | 视频原始 URL | `https://www.youtube.com/watch?v=...` |
|
||||
| `MYTUBE_TASK_STATUS` | 当前状态 | `start`, `success`, `fail`, `cancel` |
|
||||
| `MYTUBE_VIDEO_PATH` | 视频文件绝对路径 | `/app/uploads/videos/video.mp4` |
|
||||
| `MYTUBE_THUMBNAIL_PATH` | 缩略图绝对路径 | `/app/uploads/images/video.jpg` |
|
||||
| `MYTUBE_ERROR` | 错误消息(仅 `task_fail`) | `Network timeout` |
|
||||
|
||||
## 配置 (Configuration)
|
||||
|
||||
您可以在网页界面中配置钩子:
|
||||
1. 转到 **设置 (Settings)**。
|
||||
2. 向下滚动到 **高级设置 (Advanced Settings)**。
|
||||
3. 找到 **任务钩子 (Task Hooks)** 部分。
|
||||
4. 为特定事件上传您的 `.sh` 脚本。
|
||||
5. 您可以根据需要删除或重新上传脚本。
|
||||
1. 进入 **设置 (Settings)**。
|
||||
2. 打开 **高级设置 (Advanced Settings)**。
|
||||
3. 找到 **任务钩子 (Task Hooks)**。
|
||||
4. 上传对应事件的 `.sh` 脚本。
|
||||
5. 需要时可删除或重新上传。
|
||||
|
||||
钩子脚本使用 `bash` 执行,上传后会自动赋予可执行权限。
|
||||
|
||||
## 查看日志 (Viewing Logs)
|
||||
|
||||
脚本的任何输出 (stdout/stderr) 都将被捕获并记录到 MyTube 服务器控制台。
|
||||
脚本输出 (stdout/stderr) 会被后端捕获并记录。
|
||||
- 标准输出 (`echo "..."`) 记录为 `INFO`。
|
||||
- 标准错误 (`>&2 echo "..."`) 记录为 `WARN`。
|
||||
|
||||
@@ -79,7 +78,7 @@ python3 /path/to/process_video.py "$MYTUBE_VIDEO_PATH"
|
||||
## 安全警告 (Security Warning)
|
||||
|
||||
> [!WARNING]
|
||||
> 钩子命令以与MyTube后端服务器相同的权限执行。
|
||||
> 钩子命令以与 MyTube 后端相同的权限执行。
|
||||
> - 使用修改或删除文件的命令时请务必小心。
|
||||
> - 请勿复制粘贴来自不可信来源的脚本。
|
||||
> - 确保您的脚本能够优雅地处理错误。
|
||||
> - 确保脚本能正确处理错误。
|
||||
|
||||
Reference in New Issue
Block a user