11import { ipcMain , BrowserWindow , dialog , shell } from 'electron' ;
22import * as fs from 'fs' ;
3+ import * as path from 'path' ;
34import { createMessageSender } from './messageHandler' ;
45
6+ // 定义支持的文件扩展名常量
7+ export const MEDIA_EXTENSIONS = [
8+ // 视频格式
9+ '.mp4' , '.avi' , '.mov' , '.mkv' , '.flv' , '.wmv' , '.webm' ,
10+ // 音频格式
11+ '.mp3' , '.wav' , '.ogg' , '.aac' , '.wma' , '.flac' , '.m4a' ,
12+ '.aiff' , '.ape' , '.opus' , '.ac3' , '.amr' , '.au' , '.mid' ,
13+ // 其他常见视频格式
14+ '.3gp' , '.asf' , '.rm' , '.rmvb' , '.vob' , '.ts' , '.mts' , '.m2ts' ,
15+ ] ;
16+
17+ export const SUBTITLE_EXTENSIONS = [
18+ // 字幕格式
19+ '.srt' , '.vtt' , '.ass' , '.ssa' ,
20+ ] ;
21+
22+ // 判断文件是否为媒体文件
23+ export function isMediaFile ( filePath : string ) : boolean {
24+ const ext = path . extname ( filePath ) . toLowerCase ( ) ;
25+ return MEDIA_EXTENSIONS . includes ( ext ) ;
26+ }
27+
28+ // 判断文件是否为字幕文件
29+ export function isSubtitleFile ( filePath : string ) : boolean {
30+ const ext = path . extname ( filePath ) . toLowerCase ( ) ;
31+ return SUBTITLE_EXTENSIONS . includes ( ext ) ;
32+ }
33+
34+ // 递归获取文件夹中的符合任务类型的文件
35+ async function getMediaFilesFromDirectory ( directoryPath : string , taskType : string ) : Promise < string [ ] > {
36+ // 根据任务类型选择扩展名
37+ const supportedExtensions = taskType === 'translate'
38+ ? SUBTITLE_EXTENSIONS
39+ : MEDIA_EXTENSIONS ;
40+
41+ const files : string [ ] = [ ] ;
42+
43+ try {
44+ const entries = await fs . promises . readdir ( directoryPath , { withFileTypes : true } ) ;
45+
46+ for ( const entry of entries ) {
47+ const fullPath = path . join ( directoryPath , entry . name ) ;
48+
49+ if ( entry . isDirectory ( ) ) {
50+ // 递归处理子目录
51+ const subDirFiles = await getMediaFilesFromDirectory ( fullPath , taskType ) ;
52+ files . push ( ...subDirFiles ) ;
53+ } else if ( entry . isFile ( ) ) {
54+ // 检查文件扩展名是否受支持
55+ const ext = path . extname ( entry . name ) . toLowerCase ( ) ;
56+ if ( supportedExtensions . includes ( ext ) ) {
57+ files . push ( fullPath ) ;
58+ }
59+ }
60+ }
61+ } catch ( error ) {
62+ console . error ( `读取目录 ${ directoryPath } 时出错:` , error ) ;
63+ }
64+
65+ return files ;
66+ }
67+
568export function setupIpcHandlers ( mainWindow : BrowserWindow ) {
669 ipcMain . on ( 'message' , async ( event , arg ) => {
770 event . reply ( 'message' , `${ arg } World!` ) ;
@@ -11,40 +74,12 @@ export function setupIpcHandlers(mainWindow: BrowserWindow) {
1174 const { fileType } = data ;
1275 console . log ( fileType , 'fileType' ) ;
1376 const name = fileType === 'srt' ? 'Subtitle Files' : 'Media Files' ;
14- const extensions =
15- fileType === 'srt'
16- ? [ 'srt' ]
17- : [
18- 'mp4' ,
19- 'avi' ,
20- 'mov' ,
21- 'mkv' ,
22- 'flv' ,
23- 'wmv' ,
24- 'webm' ,
25- 'mp3' ,
26- 'wav' ,
27- 'ogg' ,
28- 'aac' ,
29- 'wma' ,
30- 'flac' ,
31- 'm4a' ,
32- 'aiff' ,
33- 'ape' ,
34- 'opus' ,
35- 'ac3' ,
36- 'amr' ,
37- 'au' ,
38- 'mid' ,
39- '3gp' ,
40- 'asf' ,
41- 'rm' ,
42- 'rmvb' ,
43- 'vob' ,
44- 'ts' ,
45- 'mts' ,
46- 'm2ts' ,
47- ] ;
77+
78+ // 使用已定义的常量获取扩展名
79+ const extensions = fileType === 'srt'
80+ ? SUBTITLE_EXTENSIONS . map ( ext => ext . substring ( 1 ) ) // 移除前面的点
81+ : MEDIA_EXTENSIONS . map ( ext => ext . substring ( 1 ) ) ;
82+
4883 const result = await dialog . showOpenDialog ( {
4984 properties : [ 'openFile' , 'multiSelections' ] ,
5085 filters : [
@@ -69,20 +104,33 @@ export function setupIpcHandlers(mainWindow: BrowserWindow) {
69104 shell . openExternal ( url ) ;
70105 } ) ;
71106
72- ipcMain . handle ( 'getDroppedFiles' , async ( event , files ) => {
73- // 验证文件是否存在和可访问
74- const validPaths = await Promise . all (
75- files . map ( async ( filePath ) => {
76- try {
77- await fs . promises . access ( filePath ) ;
78- return filePath ;
79- } catch {
80- return null ;
107+ ipcMain . handle ( 'getDroppedFiles' , async ( event , { files, taskType } ) => {
108+ // 处理文件和文件夹
109+ const allValidPaths : string [ ] = [ ] ;
110+
111+ for ( const filePath of files ) {
112+ try {
113+ const stats = await fs . promises . stat ( filePath ) ;
114+
115+ if ( stats . isDirectory ( ) ) {
116+ // 如果是文件夹,递归获取所有符合任务类型的文件
117+ const filteredFiles = await getMediaFilesFromDirectory ( filePath , taskType ) ;
118+ allValidPaths . push ( ...filteredFiles ) ;
119+ } else if ( stats . isFile ( ) ) {
120+ // 如果是文件,根据任务类型过滤
121+ // 根据任务类型决定添加哪种文件
122+ if ( ( taskType === 'translate' && isSubtitleFile ( filePath ) ) ||
123+ ( taskType !== 'translate' && isMediaFile ( filePath ) ) ) {
124+ allValidPaths . push ( filePath ) ;
125+ }
81126 }
82- } ) ,
83- ) ;
84-
85- return validPaths . filter ( Boolean ) ;
127+ } catch {
128+ // 如果访问失败,跳过此路径
129+ continue ;
130+ }
131+ }
132+
133+ return allValidPaths ;
86134 } ) ;
87135
88136 ipcMain . handle ( 'selectDirectory' , async ( ) => {
0 commit comments