mirror of
https://github.com/mifi/lossless-cut.git
synced 2024-11-21 18:02:35 +01:00
add tests
This commit is contained in:
parent
b61456c71a
commit
4c00987db9
@ -11,6 +11,7 @@ import { platform, arch, isWindows, isMac, isLinux } from './util.js';
|
||||
import { CaptureFormat, Html5ifyMode, Waveform } from '../../types.js';
|
||||
import isDev from './isDev.js';
|
||||
import logger from './logger.js';
|
||||
import { parseFfmpegProgressLine } from './progress.js';
|
||||
|
||||
|
||||
const runningFfmpegs = new Set<ExecaChildProcess<Buffer>>();
|
||||
@ -55,9 +56,9 @@ export function abortFfmpegs() {
|
||||
|
||||
function handleProgress(
|
||||
process: { stderr: Readable | null },
|
||||
durationIn: number | undefined,
|
||||
duration: number | undefined,
|
||||
onProgress: (a: number) => void,
|
||||
customMatcher: (a: string) => void = () => undefined,
|
||||
customMatcher?: (a: string) => void,
|
||||
) {
|
||||
if (!onProgress) return;
|
||||
if (process.stderr == null) return;
|
||||
@ -68,44 +69,10 @@ function handleProgress(
|
||||
// console.log('progress', line);
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line unicorn/better-regex
|
||||
let match = line.match(/frame=\s*[^\s]+\s+fps=\s*[^\s]+\s+q=\s*[^\s]+\s+(?:size|Lsize)=\s*[^\s]+\s+time=\s*([^\s]+)\s+/);
|
||||
// Audio only looks like this: "line size= 233422kB time=01:45:50.68 bitrate= 301.1kbits/s speed= 353x "
|
||||
// eslint-disable-next-line unicorn/better-regex
|
||||
if (!match) match = line.match(/(?:size|Lsize)=\s*[^\s]+\s+time=\s*([^\s]+)\s+/);
|
||||
if (!match) {
|
||||
customMatcher(line);
|
||||
return;
|
||||
const progress = parseFfmpegProgressLine({ line, customMatcher, duration });
|
||||
if (progress != null) {
|
||||
onProgress(progress);
|
||||
}
|
||||
|
||||
const timeStr = match[1];
|
||||
// console.log(timeStr);
|
||||
const match2 = timeStr!.match(/^(-?)(\d+):(\d+):(\d+)\.(\d+)$/);
|
||||
if (!match2) throw new Error(`Invalid time from ffmpeg progress ${timeStr}`);
|
||||
|
||||
const sign = match2[1];
|
||||
|
||||
if (sign === '-') {
|
||||
// For some reason, ffmpeg sometimes gives a negative progress, e.g. "-00:00:06.46"
|
||||
// let's just ignore that
|
||||
return;
|
||||
}
|
||||
|
||||
const h = parseInt(match2[2]!, 10);
|
||||
const m = parseInt(match2[3]!, 10);
|
||||
const s = parseInt(match2[4]!, 10);
|
||||
const cs = parseInt(match2[5]!, 10);
|
||||
const time = (((h * 60) + m) * 60 + s) + cs / 100;
|
||||
// console.log(time);
|
||||
|
||||
const progressTime = Math.max(0, time);
|
||||
// console.log(progressTime);
|
||||
|
||||
if (durationIn == null) return;
|
||||
const duration = Math.max(0, durationIn);
|
||||
if (duration === 0) return;
|
||||
const progress = Math.min(progressTime / duration, 1); // sometimes progressTime will be greater than cutDuration
|
||||
onProgress(progress);
|
||||
} catch (err) {
|
||||
logger.error('Failed to parse ffmpeg progress line:', err instanceof Error ? err.message : err);
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
// eslint-disable-line unicorn/filename-case
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import { test, expect, describe } from 'vitest';
|
||||
|
||||
|
18
src/main/progress.test.ts
Normal file
18
src/main/progress.test.ts
Normal file
@ -0,0 +1,18 @@
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import { describe, expect, test } from 'vitest';
|
||||
import { parseFfmpegProgressLine } from './progress';
|
||||
|
||||
describe('parseFfmpegProgressLine', () => {
|
||||
test('parse video', () => {
|
||||
const str = 'frame= 2285 fps=135 q=4.0 Lsize=N/A time=00:01:31.36 bitrate=N/A speed=5.38x ';
|
||||
expect(parseFfmpegProgressLine({ line: str, duration: 60 + 31.36 })).toBe(1);
|
||||
});
|
||||
test('parse audio 0', () => {
|
||||
const str = 'size= 0kB time=00:00:00.00 bitrate=N/A speed=N/A ';
|
||||
expect(parseFfmpegProgressLine({ line: str, duration: 1 })).toBe(0);
|
||||
});
|
||||
test('parse audio 32.02', () => {
|
||||
const str = 'size= 501kB time=00:00:32.02 bitrate= 128.2kbits/s speed=2.29e+03x ';
|
||||
expect(parseFfmpegProgressLine({ line: str, duration: 32.02 })).toBe(1);
|
||||
});
|
||||
});
|
46
src/main/progress.ts
Normal file
46
src/main/progress.ts
Normal file
@ -0,0 +1,46 @@
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export function parseFfmpegProgressLine({ line, customMatcher, duration: durationIn }: {
|
||||
line: string,
|
||||
customMatcher?: ((a: string) => void) | undefined,
|
||||
duration: number | undefined,
|
||||
}) {
|
||||
let match = line.match(/frame=\s*\S+\s+fps=\s*\S+\s+q=\s*\S+\s+(?:size|Lsize)=\s*\S+\s+time=\s*(\S+)\s+/);
|
||||
if (!match) {
|
||||
// Audio only looks like this: "size= 233422kB time=01:45:50.68 bitrate= 301.1kbits/s speed= 353x "
|
||||
match = line.match(/(?:size|Lsize)=\s*\S+\s+time=\s*(\S+)\s+/);
|
||||
}
|
||||
if (!match) {
|
||||
customMatcher?.(line);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (durationIn == null) return undefined;
|
||||
const duration = Math.max(0, durationIn);
|
||||
if (duration === 0) return undefined;
|
||||
|
||||
const timeStr = match[1];
|
||||
// console.log(timeStr);
|
||||
const match2 = timeStr!.match(/^(-?)(\d+):(\d+):(\d+)\.(\d+)$/);
|
||||
if (!match2) throw new Error(`Invalid time from ffmpeg progress ${timeStr}`);
|
||||
|
||||
const sign = match2[1];
|
||||
|
||||
if (sign === '-') {
|
||||
// For some reason, ffmpeg sometimes gives a negative progress, e.g. "-00:00:06.46"
|
||||
// let's just ignore those lines
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const h = parseInt(match2[2]!, 10);
|
||||
const m = parseInt(match2[3]!, 10);
|
||||
const s = parseInt(match2[4]!, 10);
|
||||
const cs = parseInt(match2[5]!, 10);
|
||||
const time = (((h * 60) + m) * 60 + s) + cs / 100;
|
||||
// console.log(time);
|
||||
|
||||
const progressTime = Math.max(0, time);
|
||||
// console.log(progressTime);
|
||||
|
||||
const progress = Math.min(progressTime / duration, 1); // sometimes progressTime will be greater than cutDuration
|
||||
return progress;
|
||||
}
|
Loading…
Reference in New Issue
Block a user