-
Notifications
You must be signed in to change notification settings - Fork 2
feat(ffmpeg): implement dynamic FFmpeg download system with runtime management #155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7ff4e10
736f097
6e3b384
5fb2964
1ce0428
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -474,6 +474,51 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) { | |
| ipcMain.handle(IpcChannel.Ffmpeg_GetWarmupStatus, async () => { | ||
| return FFmpegService.getWarmupStatus() | ||
| }) | ||
| ipcMain.handle(IpcChannel.Ffmpeg_GetInfo, async () => { | ||
| return ffmpegService.getFFmpegInfo() | ||
| }) | ||
| ipcMain.handle(IpcChannel.Ffmpeg_AutoDetectAndDownload, async () => { | ||
| return await ffmpegService.autoDetectAndDownload() | ||
| }) | ||
|
|
||
| // FFmpeg 下载服务 | ||
| const ffmpegDownloadService = ffmpegService.getDownloadService() | ||
| ipcMain.handle( | ||
| IpcChannel.FfmpegDownload_CheckExists, | ||
| async (_, platform?: string, arch?: string) => { | ||
| return ffmpegDownloadService.checkFFmpegExists(platform as any, arch as any) | ||
| } | ||
| ) | ||
| ipcMain.handle( | ||
| IpcChannel.FfmpegDownload_GetVersion, | ||
| async (_, platform?: string, arch?: string) => { | ||
| return ffmpegDownloadService.getFFmpegVersion(platform as any, arch as any) | ||
| } | ||
| ) | ||
| ipcMain.handle( | ||
| IpcChannel.FfmpegDownload_Download, | ||
| async (_, platform?: string, arch?: string) => { | ||
| return await ffmpegDownloadService.downloadFFmpeg(platform as any, arch as any) | ||
| } | ||
| ) | ||
| ipcMain.handle( | ||
| IpcChannel.FfmpegDownload_GetProgress, | ||
| async (_, platform?: string, arch?: string) => { | ||
| return ffmpegDownloadService.getDownloadProgress(platform as any, arch as any) | ||
| } | ||
| ) | ||
| ipcMain.handle(IpcChannel.FfmpegDownload_Cancel, async (_, platform?: string, arch?: string) => { | ||
| return ffmpegDownloadService.cancelDownload(platform as any, arch as any) | ||
| }) | ||
| ipcMain.handle(IpcChannel.FfmpegDownload_Remove, async (_, platform?: string, arch?: string) => { | ||
| return ffmpegDownloadService.removeFFmpeg(platform as any, arch as any) | ||
| }) | ||
| ipcMain.handle(IpcChannel.FfmpegDownload_GetAllVersions, async () => { | ||
| return ffmpegDownloadService.getAllSupportedVersions() | ||
| }) | ||
| ipcMain.handle(IpcChannel.FfmpegDownload_CleanupTemp, async () => { | ||
| return ffmpegDownloadService.cleanupTempFiles() | ||
| }) | ||
|
Comment on lines
+484
to
+521
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Fix test failures: avoid calling ffmpegService.getDownloadService(); use the exported singleton. CI fails with “getDownloadService is not a function”. Import the singleton Apply within this block: - // FFmpeg 下载服务
- const ffmpegDownloadService = ffmpegService.getDownloadService()
+ // FFmpeg 下载服务
+ // Use the singleton to avoid method-shape drift and simplify testing.
+ const ffmpegDl = ffmpegDownloadService
ipcMain.handle(
IpcChannel.FfmpegDownload_CheckExists,
async (_, platform?: string, arch?: string) => {
- return ffmpegDownloadService.checkFFmpegExists(platform as any, arch as any)
+ return ffmpegDl.checkFFmpegExists(platform as Platform, arch as Arch)
}
)
ipcMain.handle(
IpcChannel.FfmpegDownload_GetVersion,
async (_, platform?: string, arch?: string) => {
- return ffmpegDownloadService.getFFmpegVersion(platform as any, arch as any)
+ return ffmpegDl.getFFmpegVersion(platform as Platform, arch as Arch)
}
)
ipcMain.handle(
IpcChannel.FfmpegDownload_Download,
async (_, platform?: string, arch?: string) => {
- return await ffmpegDownloadService.downloadFFmpeg(platform as any, arch as any)
+ return await ffmpegDl.downloadFFmpeg(platform as Platform, arch as Arch)
}
)
ipcMain.handle(
IpcChannel.FfmpegDownload_GetProgress,
async (_, platform?: string, arch?: string) => {
- return ffmpegDownloadService.getDownloadProgress(platform as any, arch as any)
+ return ffmpegDl.getDownloadProgress(platform as Platform, arch as Arch)
}
)
- ipcMain.handle(IpcChannel.FfmpegDownload_Cancel, async (_, platform?: string, arch?: string) => {
- return ffmpegDownloadService.cancelDownload(platform as any, arch as any)
+ ipcMain.handle(IpcChannel.FfmpegDownload_Cancel, async (_, platform?: string, arch?: string) => {
+ return ffmpegDl.cancelDownload(platform as Platform, arch as Arch)
})
- ipcMain.handle(IpcChannel.FfmpegDownload_Remove, async (_, platform?: string, arch?: string) => {
- return ffmpegDownloadService.removeFFmpeg(platform as any, arch as any)
+ ipcMain.handle(IpcChannel.FfmpegDownload_Remove, async (_, platform?: string, arch?: string) => {
+ return ffmpegDl.removeFFmpeg(platform as Platform, arch as Arch)
})
ipcMain.handle(IpcChannel.FfmpegDownload_GetAllVersions, async () => {
- return ffmpegDownloadService.getAllSupportedVersions()
+ return ffmpegDl.getAllSupportedVersions()
})
ipcMain.handle(IpcChannel.FfmpegDownload_CleanupTemp, async () => {
- return ffmpegDownloadService.cleanupTempFiles()
+ return ffmpegDl.cleanupTempFiles()
})Add supporting imports (outside this hunk): import { ffmpegDownloadService, type Platform, type Arch } from './services/FFmpegDownloadService'Optional validation: reject unexpected inputs at IPC boundary to prevent misuse. const isValidPlatform = (p?: string): p is Platform => !!p && ['win32','darwin','linux'].includes(p)
const isValidArch = (a?: string): a is Arch => !!a && ['x64','arm64'].includes(a)🧰 Tools🪛 GitHub Check: test (macos-latest, 20)[failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_Delete > 应该处理删除文件时的错误 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_Delete > 应该成功删除文件并记录日志 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_FindByType > 应该处理类型查找文件时的错误 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_FindByType > 应该返回空数组当没有匹配类型的文件时 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_FindByType > 应该根据类型查找文件 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_FindByPath > 应该返回undefined当文件不存在时 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_FindByPath > 应该处理路径查找文件时的错误 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_FindByPath > 应该根据路径查找文件 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_Add > 应该处理添加文件时的错误 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_Add > 应该成功添加文件并记录日志 🪛 GitHub Check: test (ubuntu-latest, 20)[failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_Delete > 应该处理删除文件时的错误 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_Delete > 应该成功删除文件并记录日志 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_FindByType > 应该处理类型查找文件时的错误 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_FindByType > 应该返回空数组当没有匹配类型的文件时 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_FindByType > 应该根据类型查找文件 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_FindByPath > 应该返回undefined当文件不存在时 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_FindByPath > 应该处理路径查找文件时的错误 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_FindByPath > 应该根据路径查找文件 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_Add > 应该处理添加文件时的错误 [failure] 485-485: src/main/tests/ipc.database.test.ts > IPC Database Handlers > Files DAO IPC Handlers > DB_Files_Add > 应该成功添加文件并记录日志 🤖 Prompt for AI Agents |
||
|
|
||
| // MediaParser (Remotion) | ||
| ipcMain.handle(IpcChannel.MediaInfo_CheckExists, async () => { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
FFmpeg download service mock aligns; add contract verification to avoid drift.
Good addition; it unblocks IPC registration. To prevent silent breakage if IPC expects different shapes (async vs sync), verify callsites and consider pre-populating safe defaults if awaited.
Run to confirm the mocked API matches production usage:
Optionally, assert the full API shape during test setup to catch drift early.
🏁 Script executed:
Length of output: 5892
FFmpeg download service mock aligns with code usage — add a lightweight contract check.
rg output shows ipc handlers (src/main/ipc.ts) and FFmpegService (src/main/services/FFmpegService.ts) call: checkFFmpegExists, getFFmpegPath, getFFmpegVersion, downloadFFmpeg, getDownloadProgress, cancelDownload, removeFFmpeg, getAllSupportedVersions, cleanupTempFiles — all present in the test mock. Add a single test assertion that getDownloadService() returns these methods and stub async-returning methods to return Promises/expected shapes (e.g., getFFmpegVersion() -> { version: string }).
🤖 Prompt for AI Agents