ai-sub-translator 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,13 @@
1
+ import { FFmpegDownloadOptions, VideoInfo } from './types.js';
2
+ export declare const initializeFFmpeg: (options: FFmpegDownloadOptions) => Promise<string>;
3
+ export declare const getFfmpegExecPath: (outputDir: string) => string;
4
+ export declare function downloadFFmpeg(options: FFmpegDownloadOptions): Promise<string>;
5
+ /**
6
+ * Default ffmpeg directory in user's cache
7
+ */
8
+ export declare const getUserDataDir: () => string;
9
+ /**
10
+ * Gets information about a video file, including available subtitle tracks
11
+ */
12
+ export declare function getVideoInfo(videoPath: string): Promise<VideoInfo>;
13
+ //# sourceMappingURL=ffmpeg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ffmpeg.d.ts","sourceRoot":"","sources":["../src/ffmpeg.ts"],"names":[],"mappings":"AASA,OAAO,EACH,qBAAqB,EACrB,SAAS,EACZ,MAAM,YAAY,CAAC;AAapB,eAAO,MAAM,gBAAgB,GAAU,SAAS,qBAAqB,KAAG,OAAO,CAAC,MAAM,CAYrF,CAAA;AAQD,eAAO,MAAM,iBAAiB,GAAI,WAAW,MAAM,WAElD,CAAA;AAyBD,wBAAsB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiJpF;AAsBD;;GAEG;AACH,eAAO,MAAM,cAAc,QAAO,MAGjC,CAAC;AAEF;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAIxE"}
package/dist/ffmpeg.js ADDED
@@ -0,0 +1,222 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import os from 'os';
4
+ import unzipper from 'unzipper';
5
+ import { XzReadableStream } from 'xz-decompress';
6
+ import { extract as tarExtract } from 'tar';
7
+ import { detectSubtitles, } from './subtitle-extractor.js';
8
+ import { Readable } from 'stream';
9
+ import { promises as fsPromises } from 'fs';
10
+ const { rename: moveFile, rm: removeDir, chmod: chmodFile, unlink: removeFile, stat: statFile, mkdir: makeDir } = fsPromises;
11
+ const URL_MAC_X64 = 'https://evermeet.cx/pub/ffmpeg/ffmpeg-7.1.1.zip';
12
+ const URL_MAC_ARM64 = 'https://www.osxexperts.net/ffmpeg711arm.zip';
13
+ const URL_LINUX_X64 = 'https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz';
14
+ const URL_LINUX_ARM64 = 'https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-arm64-static.tar.xz';
15
+ const URL_WIN_X64 = 'https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip';
16
+ export const initializeFFmpeg = async (options) => {
17
+ const downloadPath = getUserDataDir();
18
+ const execPath = getFfmpegExecPath(downloadPath);
19
+ if (execPath && fs.existsSync(execPath)) {
20
+ console.log(`Using existing ffmpeg at ${execPath}`);
21
+ return execPath;
22
+ }
23
+ else {
24
+ options.outputDir = downloadPath;
25
+ }
26
+ return downloadFFmpeg(options);
27
+ };
28
+ const getExecName = () => {
29
+ const platform = os.platform();
30
+ const extension = platform === 'win32' ? '.exe' : '';
31
+ return `ffmpeg${extension}`;
32
+ };
33
+ export const getFfmpegExecPath = (outputDir) => {
34
+ return path.join(outputDir, getExecName());
35
+ };
36
+ const findExecutable = async (dir, execName) => {
37
+ const files = fs.readdirSync(dir);
38
+ for (const file of files) {
39
+ const filePath = path.join(dir, file);
40
+ let stat;
41
+ try {
42
+ stat = await statFile(filePath);
43
+ }
44
+ catch (error) {
45
+ console.error(`Error getting stats for file ${filePath}:`, error);
46
+ continue;
47
+ }
48
+ if (stat.isFile() && execName === file) {
49
+ return filePath;
50
+ }
51
+ else if (stat.isDirectory()) {
52
+ const result = await findExecutable(filePath, execName);
53
+ if (result) {
54
+ return result;
55
+ }
56
+ }
57
+ }
58
+ return null;
59
+ };
60
+ export async function downloadFFmpeg(options) {
61
+ const platform = options.platform || os.platform();
62
+ const arch = os.arch();
63
+ const url = getFFmpegDownloadUrl(platform, arch);
64
+ let extension = url.split('.').pop();
65
+ if (extension === 'xz') {
66
+ extension = 'tar.xz';
67
+ }
68
+ // Create directory if it doesn't exist
69
+ if (!fs.existsSync(options.outputDir)) {
70
+ fs.mkdirSync(options.outputDir, { recursive: true });
71
+ }
72
+ const filename = `ffmpeg.${extension}`;
73
+ const outputPath = path.join(options.outputDir, filename);
74
+ try {
75
+ console.log(`Downloading ffmpeg from ${url}...`);
76
+ const response = await fetch(url);
77
+ if (!response.ok) {
78
+ throw new Error(`Failed to download ffmpeg: ${response.statusText}`);
79
+ }
80
+ const totalSize = parseInt(response.headers.get('content-length') || '0', 10);
81
+ const reader = response.body?.getReader();
82
+ if (!reader) {
83
+ throw new Error('Unable to read response body');
84
+ }
85
+ const writer = fs.createWriteStream(outputPath);
86
+ let receivedBytes = 0;
87
+ while (true) {
88
+ const { done, value } = await reader.read();
89
+ if (done)
90
+ break;
91
+ writer.write(Buffer.from(value));
92
+ receivedBytes += value.length;
93
+ if (options.onProgress && totalSize > 0) {
94
+ const progress = receivedBytes / totalSize;
95
+ options.onProgress(progress);
96
+ }
97
+ }
98
+ writer.end();
99
+ console.log(`FFmpeg downloaded successfully to ${outputPath}`);
100
+ }
101
+ catch (error) {
102
+ console.error('Error downloading ffmpeg:', error);
103
+ throw error;
104
+ }
105
+ // Extract the file
106
+ const extractDir = path.join(options.outputDir, 'extracted');
107
+ if (extension === 'zip') {
108
+ const zip = fs.createReadStream(outputPath);
109
+ const extract = unzipper.Extract({ path: extractDir });
110
+ zip.pipe(extract);
111
+ try {
112
+ await new Promise((resolve, reject) => {
113
+ zip.on('end', () => resolve());
114
+ zip.on('error', reject);
115
+ });
116
+ }
117
+ catch (error) {
118
+ console.error('Error unzipping ffmpeg:', error);
119
+ throw error;
120
+ }
121
+ }
122
+ else if (extension === 'tar.xz') {
123
+ try {
124
+ const decompressedFilePath = path.join(getUserDataDir(), 'ffmpeg.tar');
125
+ const decompressedFile = fs.createWriteStream(decompressedFilePath);
126
+ const compressedFile = fs.createReadStream(outputPath);
127
+ const webStream = Readable.toWeb(compressedFile);
128
+ const decompressor = new XzReadableStream(webStream);
129
+ const xzReader = decompressor.getReader();
130
+ while (true) {
131
+ const { done, value } = await xzReader.read();
132
+ if (done)
133
+ break;
134
+ decompressedFile.write(Buffer.from(value));
135
+ }
136
+ decompressedFile.end();
137
+ await new Promise((resolve, reject) => {
138
+ decompressedFile.on('finish', resolve);
139
+ decompressedFile.on('error', reject);
140
+ });
141
+ await makeDir(extractDir, { recursive: true });
142
+ await tarExtract({
143
+ file: decompressedFilePath,
144
+ cwd: extractDir,
145
+ });
146
+ await removeFile(decompressedFilePath);
147
+ }
148
+ catch (error) {
149
+ console.error('Error decompressing ffmpeg:', error);
150
+ throw error;
151
+ }
152
+ }
153
+ else {
154
+ console.log(`Archive format not supported: ${extension}`);
155
+ }
156
+ const execName = getExecName();
157
+ const execOutputPath = getFfmpegExecPath(getUserDataDir());
158
+ const execExtractedOutputPath = await findExecutable(extractDir, execName);
159
+ try {
160
+ await moveFile(execExtractedOutputPath, execOutputPath);
161
+ }
162
+ catch (error) {
163
+ console.error('Error moving ffmpeg:', error);
164
+ throw error;
165
+ }
166
+ try {
167
+ await removeDir(extractDir, { recursive: true });
168
+ }
169
+ catch (error) {
170
+ console.error('Error removing extracted directory:', error);
171
+ }
172
+ try {
173
+ await removeFile(outputPath);
174
+ }
175
+ catch (error) {
176
+ console.error('Error removing extracted file:', error);
177
+ }
178
+ if (platform !== 'win32') {
179
+ try {
180
+ await chmodFile(execOutputPath, 0o755);
181
+ }
182
+ catch (error) {
183
+ console.error('Error chmodding ffmpeg:', error);
184
+ throw error;
185
+ }
186
+ }
187
+ return execOutputPath;
188
+ }
189
+ /**
190
+ * Gets the appropriate ffmpeg download URL based on the platform
191
+ */
192
+ function getFFmpegDownloadUrl(platform, arch) {
193
+ switch (platform) {
194
+ case 'win32':
195
+ return URL_WIN_X64;
196
+ case 'darwin':
197
+ return arch === 'arm64'
198
+ ? URL_MAC_ARM64
199
+ : URL_MAC_X64;
200
+ case 'linux':
201
+ return arch === 'arm64'
202
+ ? URL_LINUX_ARM64
203
+ : URL_LINUX_X64;
204
+ default:
205
+ throw new Error(`Unsupported platform: ${platform}`);
206
+ }
207
+ }
208
+ /**
209
+ * Default ffmpeg directory in user's cache
210
+ */
211
+ export const getUserDataDir = () => {
212
+ const home = os.homedir();
213
+ return path.join(home, '.cache', 'ai-sub-translator');
214
+ };
215
+ /**
216
+ * Gets information about a video file, including available subtitle tracks
217
+ */
218
+ export async function getVideoInfo(videoPath) {
219
+ const ffmpegPath = await initializeFFmpeg({});
220
+ return detectSubtitles(videoPath, ffmpegPath);
221
+ }
222
+ //# sourceMappingURL=ffmpeg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ffmpeg.js","sourceRoot":"","sources":["../src/ffmpeg.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  export { translate } from './translator.js';
2
2
  export { parseSrt, formatSrt } from './srt-parser.js';
3
- export type { TranslateOptions, TranslateResult, SrtEntry } from './types.js';
3
+ export { initializeFFmpeg, getFfmpegExecPath, getVideoInfo, getUserDataDir } from './ffmpeg.js';
4
+ export { detectSubtitles, extractSubtitle, parseFfmpegSubtitleStreams } from './subtitle-extractor.js';
5
+ export type { TranslateOptions, TranslateResult, SrtEntry, FFmpegDownloadOptions, SubtitleTrack, VideoInfo, ExtractSubtitleOptions } from './types.js';
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACtD,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACvG,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,QAAQ,EAAE,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
1
  export { translate } from './translator.js';
2
2
  export { parseSrt, formatSrt } from './srt-parser.js';
3
+ export { initializeFFmpeg, getFfmpegExecPath, getVideoInfo, getUserDataDir } from './ffmpeg.js';
4
+ export { detectSubtitles, extractSubtitle, parseFfmpegSubtitleStreams } from './subtitle-extractor.js';
3
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { SubtitleTrack, VideoInfo } from './types.js';
2
+ export declare function parseFfmpegSubtitleStreams(output: string): SubtitleTrack[];
3
+ export declare function detectSubtitles(videoPath: string, ffmpegPath: string): Promise<VideoInfo>;
4
+ export declare function extractSubtitle(videoPath: string, subtitleIndex: number): Promise<string>;
5
+ //# sourceMappingURL=subtitle-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subtitle-extractor.d.ts","sourceRoot":"","sources":["../src/subtitle-extractor.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAOtD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,EAAE,CAgC1E;AAED,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAmB/F;AAED,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA+B/F"}
@@ -0,0 +1,83 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as childProcess from 'child_process';
4
+ import { promisify } from 'util';
5
+ import { getFfmpegExecPath, getUserDataDir } from './ffmpeg.js';
6
+ import { promises as fsPromises } from 'fs';
7
+ const exec = promisify(childProcess.exec);
8
+ const { readFile, unlink: rmFile } = fsPromises;
9
+ export function parseFfmpegSubtitleStreams(output) {
10
+ const lines = output.split('\n');
11
+ const subtitles = [];
12
+ const streamRegex = /Stream #0:(\d+)(?:\((\w+)\))?: Subtitle: [^\s]+(?: \(([^\)]+)\))?(?: \(([^\)]+)\))?/i;
13
+ const titleRegex = /title\s+:\s+(.+)/i;
14
+ let currentStream = null;
15
+ for (const line of lines) {
16
+ const streamMatch = line.match(streamRegex);
17
+ if (streamMatch) {
18
+ const [, index, lang, flag1] = streamMatch;
19
+ currentStream = {
20
+ index: parseInt(index),
21
+ language: lang,
22
+ format: flag1,
23
+ };
24
+ subtitles.push(currentStream);
25
+ continue;
26
+ }
27
+ if (currentStream && line.includes('Metadata'))
28
+ continue;
29
+ const titleMatch = line.match(titleRegex);
30
+ if (titleMatch && currentStream) {
31
+ currentStream.title = titleMatch[1].trim();
32
+ }
33
+ }
34
+ return subtitles;
35
+ }
36
+ export async function detectSubtitles(videoPath, ffmpegPath) {
37
+ if (!fs.existsSync(videoPath)) {
38
+ throw new Error(`Video file does not exist: ${videoPath}`);
39
+ }
40
+ let commandOutput = '';
41
+ try {
42
+ await exec(`"${ffmpegPath}" -i "${videoPath}"`);
43
+ }
44
+ catch (error) {
45
+ commandOutput = error.message;
46
+ }
47
+ const subtitleTracks = parseFfmpegSubtitleStreams(commandOutput).filter((track) => track.format.includes('srt'));
48
+ return {
49
+ path: videoPath,
50
+ subtitleTracks
51
+ };
52
+ }
53
+ export async function extractSubtitle(videoPath, subtitleIndex) {
54
+ const outputPath = path.join(getUserDataDir(), `subtitle-${Date.now()}.srt`);
55
+ const ffmpegPath = getFfmpegExecPath(getUserDataDir());
56
+ if (!fs.existsSync(videoPath)) {
57
+ throw new Error(`Video file does not exist: ${videoPath}`);
58
+ }
59
+ // Ensure cache directory exists
60
+ fs.mkdirSync(path.dirname(outputPath), { recursive: true });
61
+ try {
62
+ await exec(`"${ffmpegPath}" -i "${videoPath}" -map 0:${subtitleIndex} -y "${outputPath}"`);
63
+ if (!fs.existsSync(outputPath)) {
64
+ throw new Error('Subtitle extraction failed: Output file not created');
65
+ }
66
+ try {
67
+ const text = await readFile(outputPath, 'utf8');
68
+ return text;
69
+ }
70
+ catch (error) {
71
+ console.error('Error reading subtitle file:', error);
72
+ throw new Error(`Failed to read subtitle file: ${error.message || error}`);
73
+ }
74
+ finally {
75
+ await rmFile(outputPath);
76
+ }
77
+ }
78
+ catch (error) {
79
+ console.error('Error extracting subtitle:', error);
80
+ throw new Error(`Failed to extract subtitle: ${error.message || error}`);
81
+ }
82
+ }
83
+ //# sourceMappingURL=subtitle-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subtitle-extractor.js","sourceRoot":"","sources":["../src/subtitle-extractor.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -18,4 +18,64 @@ export interface TranslateResult {
18
18
  totalBatches: number;
19
19
  completedBatches: number;
20
20
  }
21
+ export interface FFmpegDownloadOptions {
22
+ /**
23
+ * Directory where the ffmpeg executable will be saved
24
+ */
25
+ outputDir?: string;
26
+ /**
27
+ * Platform to download ffmpeg for: 'darwin' (macOS), 'win32' (Windows), or 'linux'
28
+ */
29
+ platform?: string;
30
+ /**
31
+ * Progress callback function that receives download progress percentage
32
+ */
33
+ onProgress?: (progress: number) => void;
34
+ }
35
+ export interface SubtitleTrack {
36
+ /**
37
+ * Subtitle track index in the video file
38
+ */
39
+ index: number;
40
+ /**
41
+ * Language of the subtitle track (if available)
42
+ */
43
+ language: string;
44
+ /**
45
+ * Title of the subtitle track (if available)
46
+ */
47
+ title?: string;
48
+ /**
49
+ * Format of the subtitle track (srt, ass, etc.)
50
+ */
51
+ format: string;
52
+ }
53
+ export interface VideoInfo {
54
+ /**
55
+ * Full path to the video file
56
+ */
57
+ path: string;
58
+ /**
59
+ * List of subtitle tracks found in the video
60
+ */
61
+ subtitleTracks: SubtitleTrack[];
62
+ }
63
+ export interface ExtractSubtitleOptions {
64
+ /**
65
+ * Path to the video file
66
+ */
67
+ videoPath: string;
68
+ /**
69
+ * Index of the subtitle track to extract
70
+ */
71
+ subtitleIndex: number;
72
+ /**
73
+ * Output path where the subtitle file will be saved
74
+ */
75
+ outputPath: string;
76
+ /**
77
+ * Path to the ffmpeg executable
78
+ */
79
+ ffmpegPath: string;
80
+ }
21
81
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;CAC1B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,cAAc,EAAE,aAAa,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-sub-translator",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "AI-powered subtitle translator using Google Gemini. Translates SRT subtitles to any language.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -34,9 +34,13 @@
34
34
  },
35
35
  "license": "MIT",
36
36
  "dependencies": {
37
- "@google/genai": "^0.8.0"
37
+ "@google/genai": "^0.8.0",
38
+ "tar": "^7.4.3",
39
+ "unzipper": "^0.12.3",
40
+ "xz-decompress": "^0.2.2"
38
41
  },
39
42
  "devDependencies": {
43
+ "@types/unzipper": "^0.10.11",
40
44
  "typescript": "^5.7.2",
41
45
  "vitest": "^2.1.8"
42
46
  }