mirror of
https://github.com/mifi/lossless-cut.git
synced 2024-11-22 02:12:30 +01:00
fix broken black/silence detection #1705
This commit is contained in:
parent
1acf72fcfd
commit
91ceef3972
@ -277,6 +277,39 @@ async function detectIntervals({ filePath, customArgs, onProgress, from, to, mat
|
||||
return adjustSegmentsWithOffset({ segments, from });
|
||||
}
|
||||
|
||||
const mapFilterOptions = (options) => Object.entries(options).map(([key, value]) => `${key}=${value}`).join(':');
|
||||
|
||||
async function blackDetect({ filePath, filterOptions, onProgress, from, to }) {
|
||||
function matchLineTokens(line) {
|
||||
const match = line.match(/^[blackdetect\s*@\s*0x[0-9a-f]+] black_start:([\d\\.]+) black_end:([\d\\.]+) black_duration:[\d\\.]+/);
|
||||
if (!match) return {};
|
||||
return {
|
||||
start: parseFloat(match[1]),
|
||||
end: parseFloat(match[2]),
|
||||
};
|
||||
}
|
||||
const customArgs = ['-vf', `blackdetect=${mapFilterOptions(filterOptions)}`, '-an'];
|
||||
return detectIntervals({ filePath, onProgress, from, to, matchLineTokens, customArgs });
|
||||
}
|
||||
|
||||
async function silenceDetect({ filePath, filterOptions, onProgress, from, to }) {
|
||||
function matchLineTokens(line) {
|
||||
const match = line.match(/^[silencedetect\s*@\s*0x[0-9a-f]+] silence_end: ([\d\\.]+)[|\s]+silence_duration: ([\d\\.]+)/);
|
||||
if (!match) return {};
|
||||
const end = parseFloat(match[1]);
|
||||
const silenceDuration = parseFloat(match[2]);
|
||||
if (Number.isNaN(end) || Number.isNaN(silenceDuration)) return {};
|
||||
const start = end - silenceDuration;
|
||||
if (start < 0 || end <= 0 || start >= end) return {};
|
||||
return {
|
||||
start,
|
||||
end,
|
||||
};
|
||||
}
|
||||
const customArgs = ['-af', `silencedetect=${mapFilterOptions(filterOptions)}`, '-vn'];
|
||||
return detectIntervals({ filePath, onProgress, from, to, matchLineTokens, customArgs });
|
||||
}
|
||||
|
||||
function getFffmpegJpegQuality(quality) {
|
||||
// Normal range for JPEG is 2-31 with 31 being the worst quality.
|
||||
const qMin = 2;
|
||||
@ -522,7 +555,6 @@ module.exports = {
|
||||
renderWaveformPng,
|
||||
mapTimesToSegments,
|
||||
detectSceneChanges,
|
||||
detectIntervals,
|
||||
captureFrames,
|
||||
captureFrame,
|
||||
getFfCommandLine,
|
||||
@ -530,4 +562,6 @@ module.exports = {
|
||||
getDuration,
|
||||
getOneRawFrame,
|
||||
encodeLiveRawStream,
|
||||
blackDetect,
|
||||
silenceDetect,
|
||||
};
|
||||
|
@ -13,7 +13,7 @@ const { pathExists } = window.require('fs-extra');
|
||||
|
||||
const remote = window.require('@electron/remote');
|
||||
|
||||
const { renderWaveformPng, mapTimesToSegments, detectSceneChanges, detectIntervals, captureFrames, captureFrame, getFfCommandLine, runFfmpegConcat, runFfmpegWithProgress, html5ify, getDuration, abortFfmpegs, runFfmpeg, runFfprobe, getFfmpegPath, setCustomFfPath } = remote.require('./ffmpeg');
|
||||
const { renderWaveformPng, mapTimesToSegments, detectSceneChanges, captureFrames, captureFrame, getFfCommandLine, runFfmpegConcat, runFfmpegWithProgress, html5ify, getDuration, abortFfmpegs, runFfmpeg, runFfprobe, getFfmpegPath, setCustomFfPath } = remote.require('./ffmpeg');
|
||||
|
||||
|
||||
export { renderWaveformPng, mapTimesToSegments, detectSceneChanges, captureFrames, captureFrame, getFfCommandLine, runFfmpegConcat, runFfmpegWithProgress, html5ify, getDuration, abortFfmpegs, runFfprobe, getFfmpegPath, setCustomFfPath };
|
||||
@ -483,40 +483,6 @@ export async function renderThumbnails({ filePath, from, duration, onThumbnail }
|
||||
}, { concurrency: 2 });
|
||||
}
|
||||
|
||||
|
||||
const mapFilterOptions = (options) => Object.entries(options).map(([key, value]) => `${key}=${value}`).join(':');
|
||||
|
||||
export async function blackDetect({ filePath, filterOptions, onProgress, from, to }) {
|
||||
function matchLineTokens(line) {
|
||||
const match = line.match(/^[blackdetect\s*@\s*0x[0-9a-f]+] black_start:([\d\\.]+) black_end:([\d\\.]+) black_duration:[\d\\.]+/);
|
||||
if (!match) return {};
|
||||
return {
|
||||
start: parseFloat(match[1]),
|
||||
end: parseFloat(match[2]),
|
||||
};
|
||||
}
|
||||
const customArgs = ['-vf', `blackdetect=${mapFilterOptions(filterOptions)}`, '-an'];
|
||||
return detectIntervals({ filePath, onProgress, from, to, matchLineTokens, customArgs });
|
||||
}
|
||||
|
||||
export async function silenceDetect({ filePath, filterOptions, onProgress, from, to }) {
|
||||
function matchLineTokens(line) {
|
||||
const match = line.match(/^[silencedetect\s*@\s*0x[0-9a-f]+] silence_end: ([\d\\.]+)[|\s]+silence_duration: ([\d\\.]+)/);
|
||||
if (!match) return {};
|
||||
const end = parseFloat(match[1]);
|
||||
const silenceDuration = parseFloat(match[2]);
|
||||
if (Number.isNaN(end) || Number.isNaN(silenceDuration)) return {};
|
||||
const start = end - silenceDuration;
|
||||
if (start < 0 || end <= 0 || start >= end) return {};
|
||||
return {
|
||||
start,
|
||||
end,
|
||||
};
|
||||
}
|
||||
const customArgs = ['-af', `silencedetect=${mapFilterOptions(filterOptions)}`, '-vn'];
|
||||
return detectIntervals({ filePath, onProgress, from, to, matchLineTokens, customArgs });
|
||||
}
|
||||
|
||||
export async function extractWaveform({ filePath, outPath }) {
|
||||
const numSegs = 10;
|
||||
const duration = 60 * 60;
|
||||
|
@ -6,7 +6,7 @@ import pMap from 'p-map';
|
||||
|
||||
import sortBy from 'lodash/sortBy';
|
||||
|
||||
import { blackDetect, silenceDetect, detectSceneChanges as ffmpegDetectSceneChanges, readFrames, mapTimesToSegments, findKeyframeNearTime } from '../ffmpeg';
|
||||
import { detectSceneChanges as ffmpegDetectSceneChanges, readFrames, mapTimesToSegments, findKeyframeNearTime } from '../ffmpeg';
|
||||
import { handleError, shuffleArray } from '../util';
|
||||
import { errorToast } from '../swal';
|
||||
import { showParametersDialog } from '../dialogs/parameters';
|
||||
@ -15,6 +15,10 @@ import { createSegment, findSegmentsAtCursor, sortSegments, invertSegments, getS
|
||||
import * as ffmpegParameters from '../ffmpeg-parameters';
|
||||
import { maxSegmentsAllowed } from '../util/constants';
|
||||
|
||||
const remote = window.require('@electron/remote');
|
||||
|
||||
const { blackDetect, silenceDetect } = remote.require('./ffmpeg');
|
||||
|
||||
|
||||
export default ({
|
||||
filePath, workingRef, setWorking, setCutProgress, mainVideoStream,
|
||||
|
Loading…
Reference in New Issue
Block a user