Add experimental flag setting #336

pull/377/head
Mikael Finstad 6 years ago
parent 6c4f7c1ccb
commit 4a20c1ac00

@ -14,6 +14,7 @@ const defaults = {
autoSaveProjectFile: true, autoSaveProjectFile: true,
wheelSensitivity: 0.2, wheelSensitivity: 0.2,
language: undefined, language: undefined,
ffmpegExperimental: false,
}, },
}; };

@ -223,6 +223,8 @@ const App = memo(() => {
useEffect(() => safeSetConfig('invertTimelineScroll', invertTimelineScroll), [invertTimelineScroll]); useEffect(() => safeSetConfig('invertTimelineScroll', invertTimelineScroll), [invertTimelineScroll]);
const [language, setLanguage] = useState(configStore.get('language')); const [language, setLanguage] = useState(configStore.get('language'));
useEffect(() => safeSetConfig('language', language), [language]); useEffect(() => safeSetConfig('language', language), [language]);
const [ffmpegExperimental, setFfmpegExperimental] = useState(configStore.get('ffmpegExperimental'));
useEffect(() => safeSetConfig('ffmpegExperimental', ffmpegExperimental), [ffmpegExperimental]);
useEffect(() => { useEffect(() => {
i18n.changeLanguage(language || fallbackLng).catch(console.error); i18n.changeLanguage(language || fallbackLng).catch(console.error);
@ -633,7 +635,7 @@ const App = memo(() => {
const outPath = getOutPath(newCustomOutDir, firstPath, `merged${ext}`); const outPath = getOutPath(newCustomOutDir, firstPath, `merged${ext}`);
// console.log('merge', paths); // console.log('merge', paths);
await ffmpegMergeFiles({ paths, outPath, allStreams, onProgress: setCutProgress }); await ffmpegMergeFiles({ paths, outPath, allStreams, ffmpegExperimental, onProgress: setCutProgress });
openDirToast({ icon: 'success', dirPath: outputDir, text: i18n.t('Files merged!') }); openDirToast({ icon: 'success', dirPath: outputDir, text: i18n.t('Files merged!') });
} catch (err) { } catch (err) {
errorToast(i18n.t('Failed to merge files. Make sure they are all of the exact same codecs')); errorToast(i18n.t('Failed to merge files. Make sure they are all of the exact same codecs'));
@ -642,7 +644,7 @@ const App = memo(() => {
setWorking(); setWorking();
setCutProgress(); setCutProgress();
} }
}, [assureOutDirAccess, outputDir]); }, [assureOutDirAccess, outputDir, ffmpegExperimental]);
const toggleCaptureFormat = useCallback(() => setCaptureFormat(f => (f === 'png' ? 'jpeg' : 'png')), []); const toggleCaptureFormat = useCallback(() => setCaptureFormat(f => (f === 'png' ? 'jpeg' : 'png')), []);
const toggleKeyframeCut = useCallback(() => setKeyframeCut((val) => { const toggleKeyframeCut = useCallback(() => setKeyframeCut((val) => {
@ -1009,6 +1011,7 @@ const App = memo(() => {
onProgress: setCutProgress, onProgress: setCutProgress,
appendFfmpegCommandLog, appendFfmpegCommandLog,
shortestFlag, shortestFlag,
ffmpegExperimental,
}); });
if (outFiles.length > 1 && autoMerge) { if (outFiles.length > 1 && autoMerge) {
@ -1021,6 +1024,7 @@ const App = memo(() => {
outFormat: fileFormat, outFormat: fileFormat,
isCustomFormatSelected, isCustomFormatSelected,
segmentPaths: outFiles, segmentPaths: outFiles,
ffmpegExperimental,
onProgress: setCutProgress, onProgress: setCutProgress,
}); });
} }
@ -1059,7 +1063,7 @@ const App = memo(() => {
working, duration, filePath, keyframeCut, working, duration, filePath, keyframeCut,
autoMerge, customOutDir, fileFormat, haveInvalidSegs, copyFileStreams, numStreamsToCopy, autoMerge, customOutDir, fileFormat, haveInvalidSegs, copyFileStreams, numStreamsToCopy,
exportExtraStreams, nonCopiedExtraStreams, outputDir, shortestFlag, isCustomFormatSelected, exportExtraStreams, nonCopiedExtraStreams, outputDir, shortestFlag, isCustomFormatSelected,
fileFormatData, mainStreams, fileFormatData, mainStreams, ffmpegExperimental,
]); ]);
const capture = useCallback(async () => { const capture = useCallback(async () => {
@ -1718,6 +1722,8 @@ const App = memo(() => {
setTimecodeShowFrames={setTimecodeShowFrames} setTimecodeShowFrames={setTimecodeShowFrames}
askBeforeClose={askBeforeClose} askBeforeClose={askBeforeClose}
setAskBeforeClose={setAskBeforeClose} setAskBeforeClose={setAskBeforeClose}
ffmpegExperimental={ffmpegExperimental}
setFfmpegExperimental={setFfmpegExperimental}
invertTimelineScroll={invertTimelineScroll} invertTimelineScroll={invertTimelineScroll}
setInvertTimelineScroll={setInvertTimelineScroll} setInvertTimelineScroll={setInvertTimelineScroll}
language={language} language={language}
@ -1728,7 +1734,7 @@ const App = memo(() => {
renderCaptureFormatButton={renderCaptureFormatButton} renderCaptureFormatButton={renderCaptureFormatButton}
onWheelTunerRequested={onWheelTunerRequested} onWheelTunerRequested={onWheelTunerRequested}
/> />
), [AutoExportToggler, askBeforeClose, autoMerge, autoSaveProjectFile, customOutDir, invertCutSegments, keyframeCut, renderCaptureFormatButton, renderOutFmt, timecodeShowFrames, changeOutDir, onWheelTunerRequested, language, invertTimelineScroll]); ), [AutoExportToggler, askBeforeClose, autoMerge, autoSaveProjectFile, customOutDir, invertCutSegments, keyframeCut, renderCaptureFormatButton, renderOutFmt, timecodeShowFrames, changeOutDir, onWheelTunerRequested, language, invertTimelineScroll, ffmpegExperimental, setFfmpegExperimental]);
useEffect(() => { useEffect(() => {
if (!isStoreBuild) loadMifiLink().then(setMifiLink); if (!isStoreBuild) loadMifiLink().then(setMifiLink);

@ -37,7 +37,8 @@ const HelpSheet = memo(({
<li>Try both <b>Keyframe cut</b> and <b>Normal cut</b> modes</li> <li>Try both <b>Keyframe cut</b> and <b>Normal cut</b> modes</li>
<li>Try to set the <b>start-</b>cutpoint a <b>few frames before or after</b> the nearest keyframe (may also solve audio sync issues)</li> <li>Try to set the <b>start-</b>cutpoint a <b>few frames before or after</b> the nearest keyframe (may also solve audio sync issues)</li>
<li>Try to disable some <b>Tracks</b></li> <li>Try to disable some <b>Tracks</b></li>
<li>Try a different <b>output format</b></li> <li>Try a different <b>Output format</b></li>
<li>Try to enable the <b>Experimental Flag</b> in Settings</li>
</ol> </ol>
<p style={{ fontWeight: 'bold' }}> <p style={{ fontWeight: 'bold' }}>

@ -7,7 +7,7 @@ const Settings = memo(({
changeOutDir, customOutDir, autoMerge, setAutoMerge, keyframeCut, setKeyframeCut, invertCutSegments, setInvertCutSegments, changeOutDir, customOutDir, autoMerge, setAutoMerge, keyframeCut, setKeyframeCut, invertCutSegments, setInvertCutSegments,
autoSaveProjectFile, setAutoSaveProjectFile, timecodeShowFrames, setTimecodeShowFrames, askBeforeClose, setAskBeforeClose, autoSaveProjectFile, setAutoSaveProjectFile, timecodeShowFrames, setTimecodeShowFrames, askBeforeClose, setAskBeforeClose,
renderOutFmt, AutoExportToggler, renderCaptureFormatButton, onWheelTunerRequested, language, setLanguage, renderOutFmt, AutoExportToggler, renderCaptureFormatButton, onWheelTunerRequested, language, setLanguage,
invertTimelineScroll, setInvertTimelineScroll, invertTimelineScroll, setInvertTimelineScroll, ffmpegExperimental, setFfmpegExperimental,
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -113,6 +113,17 @@ const Settings = memo(({
</Table.TextCell> </Table.TextCell>
</Row> </Row>
<Row>
<KeyCell>{t('Enable experimental ffmpeg features flag?')}</KeyCell>
<Table.TextCell>
<Checkbox
label={t('Experimental flag')}
checked={ffmpegExperimental}
onChange={e => setFfmpegExperimental(e.target.checked)}
/>
</Table.TextCell>
</Row>
<Row> <Row>
<KeyCell> <KeyCell>
{t('Auto save project file?')}<br /> {t('Auto save project file?')}<br />

@ -205,7 +205,7 @@ function getMovFlags(outFormat) {
} }
async function cut({ async function cut({
filePath, outFormat, cutFrom, cutTo, videoDuration, rotation, filePath, outFormat, cutFrom, cutTo, videoDuration, rotation, ffmpegExperimental,
onProgress, copyFileStreams, keyframeCut, outPath, appendFfmpegCommandLog, shortestFlag, onProgress, copyFileStreams, keyframeCut, outPath, appendFfmpegCommandLog, shortestFlag,
}) { }) {
const cuttingStart = isCuttingStart(cutFrom); const cuttingStart = isCuttingStart(cutFrom);
@ -253,6 +253,9 @@ async function cut({
// See https://github.com/mifi/lossless-cut/issues/170 // See https://github.com/mifi/lossless-cut/issues/170
'-ignore_unknown', '-ignore_unknown',
// https://superuser.com/questions/543589/information-about-ffmpeg-command-line-options
...(ffmpegExperimental ? ['-strict', 'experimental'] : []),
...rotationArgs, ...rotationArgs,
'-f', outFormat, '-y', outPath, '-f', outFormat, '-y', outPath,
@ -279,7 +282,7 @@ function getOutFileExtension({ isCustomFormatSelected, outFormat, filePath }) {
export async function cutMultiple({ export async function cutMultiple({
customOutDir, filePath, segments: segmentsUnsorted, videoDuration, rotation, customOutDir, filePath, segments: segmentsUnsorted, videoDuration, rotation,
onProgress, keyframeCut, copyFileStreams, outFormat, isCustomFormatSelected, onProgress, keyframeCut, copyFileStreams, outFormat, isCustomFormatSelected,
appendFfmpegCommandLog, shortestFlag, appendFfmpegCommandLog, shortestFlag, ffmpegExperimental,
}) { }) {
const segments = sortBy(segmentsUnsorted, 'cutFrom'); const segments = sortBy(segmentsUnsorted, 'cutFrom');
const singleProgresses = {}; const singleProgresses = {};
@ -317,6 +320,7 @@ export async function cutMultiple({
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
onProgress: progress => onSingleProgress(i, progress), onProgress: progress => onSingleProgress(i, progress),
appendFfmpegCommandLog, appendFfmpegCommandLog,
ffmpegExperimental,
}); });
outFiles.push(outPath); outFiles.push(outPath);
@ -435,7 +439,7 @@ export async function html5ifyDummy(filePath, outPath, onProgress) {
await transferTimestamps(filePath, outPath); await transferTimestamps(filePath, outPath);
} }
export async function mergeFiles({ paths, outPath, allStreams, outFormat, onProgress = () => {} }) { export async function mergeFiles({ paths, outPath, allStreams, outFormat, ffmpegExperimental, onProgress = () => {} }) {
console.log('Merging files', { paths }, 'to', outPath); console.log('Merging files', { paths }, 'to', outPath);
const durations = await pMap(paths, getDuration, { concurrency: 1 }); const durations = await pMap(paths, getDuration, { concurrency: 1 });
@ -458,6 +462,9 @@ export async function mergeFiles({ paths, outPath, allStreams, outFormat, onProg
// See https://github.com/mifi/lossless-cut/issues/170 // See https://github.com/mifi/lossless-cut/issues/170
'-ignore_unknown', '-ignore_unknown',
// https://superuser.com/questions/543589/information-about-ffmpeg-command-line-options
...(ffmpegExperimental ? ['-strict', 'experimental'] : []),
...(outFormat ? ['-f', outFormat] : []), ...(outFormat ? ['-f', outFormat] : []),
'-y', outPath, '-y', outPath,
]; ];
@ -480,12 +487,12 @@ export async function mergeFiles({ paths, outPath, allStreams, outFormat, onProg
console.log(result.stdout); console.log(result.stdout);
} }
export async function autoMergeSegments({ customOutDir, sourceFile, isCustomFormatSelected, outFormat, segmentPaths, onProgress }) { export async function autoMergeSegments({ customOutDir, sourceFile, isCustomFormatSelected, outFormat, segmentPaths, ffmpegExperimental, onProgress }) {
const ext = getOutFileExtension({ isCustomFormatSelected, outFormat, filePath: sourceFile }); const ext = getOutFileExtension({ isCustomFormatSelected, outFormat, filePath: sourceFile });
const fileName = `cut-merged-${new Date().getTime()}${ext}`; const fileName = `cut-merged-${new Date().getTime()}${ext}`;
const outPath = getOutPath(customOutDir, sourceFile, fileName); const outPath = getOutPath(customOutDir, sourceFile, fileName);
await mergeFiles({ paths: segmentPaths, outPath, outFormat, allStreams: true, onProgress }); await mergeFiles({ paths: segmentPaths, outPath, outFormat, allStreams: true, ffmpegExperimental, onProgress });
await pMap(segmentPaths, path => fs.unlink(path), { concurrency: 5 }); await pMap(segmentPaths, path => fs.unlink(path), { concurrency: 5 });
} }

Loading…
Cancel
Save