1
0
mirror of https://github.com/mifi/lossless-cut.git synced 2024-11-25 11:43:17 +01:00
Mikael Finstad 2024-05-14 12:13:35 +02:00
parent 236bdd80c8
commit 8436bfdd78
No known key found for this signature in database
GPG Key ID: 25AB36E3E81CBC26
10 changed files with 87 additions and 28 deletions

View File

@ -32,12 +32,14 @@ const defaultKeyBindings: KeyBinding[] = [
{ keys: 'g', action: 'goToTimecode' }, { keys: 'g', action: 'goToTimecode' },
{ keys: 'left', action: 'seekBackwards' }, { keys: 'left', action: 'seekBackwards' },
{ keys: 'ctrl+shift+left', action: 'seekBackwards2' },
{ keys: 'ctrl+left', action: 'seekBackwardsPercent' }, { keys: 'ctrl+left', action: 'seekBackwardsPercent' },
{ keys: 'command+left', action: 'seekBackwardsPercent' }, { keys: 'command+left', action: 'seekBackwardsPercent' },
{ keys: 'alt+left', action: 'seekBackwardsKeyframe' }, { keys: 'alt+left', action: 'seekBackwardsKeyframe' },
{ keys: 'shift+left', action: 'jumpCutStart' }, { keys: 'shift+left', action: 'jumpCutStart' },
{ keys: 'right', action: 'seekForwards' }, { keys: 'right', action: 'seekForwards' },
{ keys: 'ctrl+shift+right', action: 'seekForwards2' },
{ keys: 'ctrl+right', action: 'seekForwardsPercent' }, { keys: 'ctrl+right', action: 'seekForwardsPercent' },
{ keys: 'command+right', action: 'seekForwardsPercent' }, { keys: 'command+right', action: 'seekForwardsPercent' },
{ keys: 'alt+right', action: 'seekForwardsKeyframe' }, { keys: 'alt+right', action: 'seekForwardsKeyframe' },
@ -114,6 +116,8 @@ const defaults: Config = {
outSegTemplate: undefined, outSegTemplate: undefined,
keyboardSeekAccFactor: 1.03, keyboardSeekAccFactor: 1.03,
keyboardNormalSeekSpeed: 1, keyboardNormalSeekSpeed: 1,
keyboardSeekSpeed2: 10,
keyboardSeekSpeed3: 60,
treatInputFileModifiedTimeAsStart: true, treatInputFileModifiedTimeAsStart: true,
treatOutputFileModifiedTimeAsStart: true, treatOutputFileModifiedTimeAsStart: true,
outFormatLocked: undefined, outFormatLocked: undefined,

View File

@ -195,7 +195,7 @@ function App() {
const allUserSettings = useUserSettingsRoot(); const allUserSettings = useUserSettingsRoot();
const { const {
captureFormat, setCaptureFormat, customOutDir, setCustomOutDir, keyframeCut, setKeyframeCut, preserveMovData, setPreserveMovData, movFastStart, setMovFastStart, avoidNegativeTs, autoMerge, timecodeFormat, invertCutSegments, setInvertCutSegments, autoExportExtraStreams, askBeforeClose, enableAskForImportChapters, enableAskForFileOpenAction, playbackVolume, setPlaybackVolume, autoSaveProjectFile, wheelSensitivity, invertTimelineScroll, language, ffmpegExperimental, hideNotifications, autoLoadTimecode, autoDeleteMergedSegments, exportConfirmEnabled, setExportConfirmEnabled, segmentsToChapters, setSegmentsToChapters, preserveMetadataOnMerge, setPreserveMetadataOnMerge, simpleMode, setSimpleMode, outSegTemplate, setOutSegTemplate, keyboardSeekAccFactor, keyboardNormalSeekSpeed, treatInputFileModifiedTimeAsStart, treatOutputFileModifiedTimeAsStart, outFormatLocked, setOutFormatLocked, safeOutputFileName, setSafeOutputFileName, enableAutoHtml5ify, segmentsToChaptersOnly, keyBindings, setKeyBindings, resetKeyBindings, enableSmartCut, customFfPath, storeProjectInWorkingDir, setStoreProjectInWorkingDir, enableOverwriteOutput, mouseWheelZoomModifierKey, captureFrameMethod, captureFrameQuality, captureFrameFileNameFormat, enableNativeHevc, cleanupChoices, setCleanupChoices, darkMode, setDarkMode, preferStrongColors, outputFileNameMinZeroPadding, cutFromAdjustmentFrames, captureFormat, setCaptureFormat, customOutDir, setCustomOutDir, keyframeCut, setKeyframeCut, preserveMovData, setPreserveMovData, movFastStart, setMovFastStart, avoidNegativeTs, autoMerge, timecodeFormat, invertCutSegments, setInvertCutSegments, autoExportExtraStreams, askBeforeClose, enableAskForImportChapters, enableAskForFileOpenAction, playbackVolume, setPlaybackVolume, autoSaveProjectFile, wheelSensitivity, invertTimelineScroll, language, ffmpegExperimental, hideNotifications, autoLoadTimecode, autoDeleteMergedSegments, exportConfirmEnabled, setExportConfirmEnabled, segmentsToChapters, setSegmentsToChapters, preserveMetadataOnMerge, setPreserveMetadataOnMerge, simpleMode, setSimpleMode, outSegTemplate, setOutSegTemplate, keyboardSeekAccFactor, keyboardNormalSeekSpeed, keyboardSeekSpeed2, keyboardSeekSpeed3, treatInputFileModifiedTimeAsStart, treatOutputFileModifiedTimeAsStart, outFormatLocked, setOutFormatLocked, safeOutputFileName, setSafeOutputFileName, enableAutoHtml5ify, segmentsToChaptersOnly, keyBindings, setKeyBindings, resetKeyBindings, enableSmartCut, customFfPath, storeProjectInWorkingDir, setStoreProjectInWorkingDir, enableOverwriteOutput, mouseWheelZoomModifierKey, captureFrameMethod, captureFrameQuality, captureFrameFileNameFormat, enableNativeHevc, cleanupChoices, setCleanupChoices, darkMode, setDarkMode, preferStrongColors, outputFileNameMinZeroPadding, cutFromAdjustmentFrames,
} = allUserSettings; } = allUserSettings;
useEffect(() => { useEffect(() => {
@ -2087,6 +2087,15 @@ function App() {
seekAccelerationRef.current = 1; seekAccelerationRef.current = 1;
} }
function seekRel2({ keyup, amount }: { keyup: boolean | undefined, amount: number }) {
if (keyup) {
seekReset();
return;
}
seekRel(seekAccelerationRef.current * amount);
seekAccelerationRef.current *= keyboardSeekAccFactor;
}
const ret: Record<MainKeyboardAction, ((a: { keyup?: boolean | undefined }) => boolean) | ((a: { keyup?: boolean | undefined }) => void)> = { const ret: Record<MainKeyboardAction, ((a: { keyup?: boolean | undefined }) => boolean) | ((a: { keyup?: boolean | undefined }) => void)> = {
// NOTE: Do not change these keys because users have bound keys by these names in their config files // NOTE: Do not change these keys because users have bound keys by these names in their config files
// For actions, see also KeyboardShortcuts.jsx // For actions, see also KeyboardShortcuts.jsx
@ -2111,22 +2120,12 @@ function App() {
splitCurrentSegment, splitCurrentSegment,
increaseRotation, increaseRotation,
goToTimecode, goToTimecode,
seekBackwards({ keyup }) { seekBackwards: ({ keyup }) => seekRel2({ keyup, amount: -1 * keyboardNormalSeekSpeed }),
if (keyup) { seekBackwards2: ({ keyup }) => seekRel2({ keyup, amount: -1 * keyboardSeekSpeed2 }),
seekReset(); seekBackwards3: ({ keyup }) => seekRel2({ keyup, amount: -1 * keyboardSeekSpeed3 }),
return; seekForwards: ({ keyup }) => seekRel2({ keyup, amount: keyboardNormalSeekSpeed }),
} seekForwards2: ({ keyup }) => seekRel2({ keyup, amount: keyboardSeekSpeed2 }),
seekRel(keyboardNormalSeekSpeed * seekAccelerationRef.current * -1); seekForwards3: ({ keyup }) => seekRel2({ keyup, amount: keyboardSeekSpeed3 }),
seekAccelerationRef.current *= keyboardSeekAccFactor;
},
seekForwards({ keyup }) {
if (keyup) {
seekReset();
return;
}
seekRel(keyboardNormalSeekSpeed * seekAccelerationRef.current);
seekAccelerationRef.current *= keyboardSeekAccFactor;
},
seekBackwardsPercent: () => { seekRelPercent(-0.01); return false; }, seekBackwardsPercent: () => { seekRelPercent(-0.01); return false; },
seekForwardsPercent: () => { seekRelPercent(0.01); return false; }, seekForwardsPercent: () => { seekRelPercent(0.01); return false; },
seekBackwardsKeyframe: () => seekClosestKeyframe(-1), seekBackwardsKeyframe: () => seekClosestKeyframe(-1),
@ -2220,7 +2219,7 @@ function App() {
}; };
return ret; return ret;
}, [addSegment, alignSegmentTimesToKeyframes, apparentCutSegments, askStartTimeOffset, batchFileJump, batchOpenSelectedFile, captureSnapshot, captureSnapshotAsCoverArt, changePlaybackRate, checkFileOpened, cleanupFilesDialog, clearSegments, closeBatch, closeFileWithConfirm, combineOverlappingSegments, combineSelectedSegments, concatBatch, convertFormatBatch, copySegmentsToClipboard, createFixedDurationSegments, createNumSegments, createRandomSegments, createSegmentsFromKeyframes, currentSegIndexSafe, cutSegments.length, cutSegmentsHistory, deselectAllSegments, detectBlackScenes, detectSceneChanges, detectSilentScenes, duplicateCurrentSegment, editCurrentSegmentTags, extractAllStreams, extractCurrentSegmentFramesAsImages, extractSelectedSegmentsFramesAsImages, fillSegmentsGaps, goToTimecode, handleShowStreamsSelectorClick, increaseRotation, invertAllSegments, invertSelectedSegments, jumpCutEnd, jumpCutStart, jumpSeg, jumpTimelineEnd, jumpTimelineStart, keyboardNormalSeekSpeed, keyboardSeekAccFactor, onExportPress, onLabelSegment, openFilesDialog, openSendReportDialogWithState, pause, play, removeCutSegment, removeSelectedSegments, reorderSegsByStartTime, seekClosestKeyframe, seekRel, seekRelPercent, selectAllSegments, selectOnlyCurrentSegment, setCurrentSegIndex, setCutEnd, setCutStart, setPlaybackVolume, shiftAllSegmentTimes, shortStep, showIncludeExternalStreamsDialog, shuffleSegments, splitCurrentSegment, timelineToggleComfortZoom, toggleCaptureFormat, toggleCurrentSegmentSelected, toggleFullscreenVideo, toggleKeyframeCut, toggleLastCommands, toggleLoopSelectedSegments, togglePlay, toggleSegmentsList, toggleSettings, toggleShowKeyframes, toggleShowThumbnails, toggleStreamsSelector, toggleStripAudio, toggleStripThumbnail, toggleWaveformMode, tryFixInvalidDuration, userHtml5ifyCurrentFile, zoomRel]); }, [addSegment, alignSegmentTimesToKeyframes, apparentCutSegments, askStartTimeOffset, batchFileJump, batchOpenSelectedFile, captureSnapshot, captureSnapshotAsCoverArt, changePlaybackRate, checkFileOpened, cleanupFilesDialog, clearSegments, closeBatch, closeFileWithConfirm, combineOverlappingSegments, combineSelectedSegments, concatBatch, convertFormatBatch, copySegmentsToClipboard, createFixedDurationSegments, createNumSegments, createRandomSegments, createSegmentsFromKeyframes, currentSegIndexSafe, cutSegments.length, cutSegmentsHistory, deselectAllSegments, detectBlackScenes, detectSceneChanges, detectSilentScenes, duplicateCurrentSegment, editCurrentSegmentTags, extractAllStreams, extractCurrentSegmentFramesAsImages, extractSelectedSegmentsFramesAsImages, fillSegmentsGaps, goToTimecode, handleShowStreamsSelectorClick, increaseRotation, invertAllSegments, invertSelectedSegments, jumpCutEnd, jumpCutStart, jumpSeg, jumpTimelineEnd, jumpTimelineStart, keyboardNormalSeekSpeed, keyboardSeekAccFactor, keyboardSeekSpeed2, keyboardSeekSpeed3, onExportPress, onLabelSegment, openFilesDialog, openSendReportDialogWithState, pause, play, removeCutSegment, removeSelectedSegments, reorderSegsByStartTime, seekClosestKeyframe, seekRel, seekRelPercent, selectAllSegments, selectOnlyCurrentSegment, setCurrentSegIndex, setCutEnd, setCutStart, setPlaybackVolume, shiftAllSegmentTimes, shortStep, showIncludeExternalStreamsDialog, shuffleSegments, splitCurrentSegment, timelineToggleComfortZoom, toggleCaptureFormat, toggleCurrentSegmentSelected, toggleFullscreenVideo, toggleKeyframeCut, toggleLastCommands, toggleLoopSelectedSegments, togglePlay, toggleSegmentsList, toggleSettings, toggleShowKeyframes, toggleShowThumbnails, toggleStreamsSelector, toggleStripAudio, toggleStripThumbnail, toggleWaveformMode, tryFixInvalidDuration, userHtml5ifyCurrentFile, zoomRel]);
const getKeyboardAction = useCallback((action: MainKeyboardAction) => mainActions[action], [mainActions]); const getKeyboardAction = useCallback((action: MainKeyboardAction) => mainActions[action], [mainActions]);

View File

@ -224,11 +224,27 @@ const KeyboardShortcuts = memo(({
category: seekingCategory, category: seekingCategory,
}, },
seekBackwards: { seekBackwards: {
name: t('Seek backward 1 sec'), name: t('Backward seek'),
category: seekingCategory, category: seekingCategory,
}, },
seekForwards: { seekForwards: {
name: t('Seek forward 1 sec'), name: t('Forward seek'),
category: seekingCategory,
},
seekBackwards2: {
name: t('Backward seek (longer)'),
category: seekingCategory,
},
seekForwards2: {
name: t('Forward seek (longer)'),
category: seekingCategory,
},
seekBackwards3: {
name: t('Backward seek (longest)'),
category: seekingCategory,
},
seekForwards3: {
name: t('Forward seek (longest)'),
category: seekingCategory, category: seekingCategory,
}, },
seekBackwardsKeyframe: { seekBackwardsKeyframe: {

View File

@ -357,12 +357,26 @@ const Settings = memo(({
</Row> </Row>
<Row> <Row>
<KeyCell>{t('Timeline keyboard seek speed')}</KeyCell> <KeyCell>{t('Timeline keyboard seek interval')}</KeyCell>
<td> <td>
<Button iconBefore={CogIcon} onClick={() => onTunerRequested('keyboardNormalSeekSpeed')}>{t('Change value')}</Button> <Button iconBefore={CogIcon} onClick={() => onTunerRequested('keyboardNormalSeekSpeed')}>{t('Change value')}</Button>
</td> </td>
</Row> </Row>
<Row>
<KeyCell>{t('Timeline keyboard seek interval (longer)')}</KeyCell>
<td>
<Button iconBefore={CogIcon} onClick={() => onTunerRequested('keyboardSeekSpeed2')}>{t('Change value')}</Button>
</td>
</Row>
<Row>
<KeyCell>{t('Timeline keyboard seek interval (longest)')}</KeyCell>
<td>
<Button iconBefore={CogIcon} onClick={() => onTunerRequested('keyboardSeekSpeed3')}>{t('Change value')}</Button>
</td>
</Row>
<Row> <Row>
<KeyCell>{t('Timeline keyboard seek acceleration')}</KeyCell> <KeyCell>{t('Timeline keyboard seek acceleration')}</KeyCell>
<td> <td>

View File

@ -35,7 +35,7 @@ const ValueTuner = memo(({ style, title, value, setValue, onFinished, resolution
<div style={{ background: 'var(--gray1)', color: 'var(--gray12)', position: 'absolute', bottom: 0, padding: 10, margin: 10, borderRadius: 10, ...style }}> <div style={{ background: 'var(--gray1)', color: 'var(--gray12)', position: 'absolute', bottom: 0, padding: 10, margin: 10, borderRadius: 10, ...style }}>
<div style={{ display: 'flex', alignItems: 'center', flexBasis: 400, marginBottom: '.2em' }}> <div style={{ display: 'flex', alignItems: 'center', flexBasis: 400, marginBottom: '.2em' }}>
<div>{title}</div> <div>{title}</div>
<div style={{ marginLeft: '.5em', fontWeight: 'bold', marginRight: '.5em', textDecoration: 'underline' }}>{value.toFixed(4)}</div> <div style={{ marginLeft: '.5em', fontWeight: 'bold', marginRight: '.5em', textDecoration: 'underline', fontFamily: 'monospace', width: '5em' }}>{value.toFixed(4)}</div>
<Switch checked={isZoomed} onCheckedChange={toggleZoom} style={{ flexShrink: 0 }} /><span style={{ marginLeft: '.3em' }}>{t('Precise')}</span> <Switch checked={isZoomed} onCheckedChange={toggleZoom} style={{ flexShrink: 0 }} /><span style={{ marginLeft: '.3em' }}>{t('Precise')}</span>
</div> </div>

View File

@ -7,7 +7,7 @@ import { TunerType } from '../types';
const ValueTuners = memo(({ type, onFinished }: { type: TunerType, onFinished: () => void }) => { const ValueTuners = memo(({ type, onFinished }: { type: TunerType, onFinished: () => void }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { wheelSensitivity, setWheelSensitivity, keyboardNormalSeekSpeed, setKeyboardNormalSeekSpeed, keyboardSeekAccFactor, setKeyboardSeekAccFactor } = useUserSettings(); const { wheelSensitivity, setWheelSensitivity, keyboardNormalSeekSpeed, keyboardSeekSpeed2, setKeyboardSeekSpeed2, keyboardSeekSpeed3, setKeyboardSeekSpeed3, setKeyboardNormalSeekSpeed, keyboardSeekAccFactor, setKeyboardSeekAccFactor } = useUserSettings();
// NOTE default values are duplicated in src/main/configStore.js // NOTE default values are duplicated in src/main/configStore.js
const types = { const types = {
@ -20,13 +20,29 @@ const ValueTuners = memo(({ type, onFinished }: { type: TunerType, onFinished: (
default: 0.2, default: 0.2,
}, },
keyboardNormalSeekSpeed: { keyboardNormalSeekSpeed: {
title: t('Timeline keyboard seek speed'), title: t('Timeline keyboard seek interval'),
value: keyboardNormalSeekSpeed, value: keyboardNormalSeekSpeed,
setValue: setKeyboardNormalSeekSpeed, setValue: setKeyboardNormalSeekSpeed,
min: 0, min: 0,
max: 100, max: 120,
default: 1, default: 1,
}, },
keyboardSeekSpeed2: {
title: t('Timeline keyboard seek interval (longer)'),
value: keyboardSeekSpeed2,
setValue: setKeyboardSeekSpeed2,
min: 0,
max: 600,
default: 10,
},
keyboardSeekSpeed3: {
title: t('Timeline keyboard seek interval (longest)'),
value: keyboardSeekSpeed3,
setValue: setKeyboardSeekSpeed3,
min: 0,
max: 3600,
default: 60,
},
keyboardSeekAccFactor: { keyboardSeekAccFactor: {
title: t('Timeline keyboard seek acceleration'), title: t('Timeline keyboard seek acceleration'),
value: keyboardSeekAccFactor, value: keyboardSeekAccFactor,

View File

@ -9,7 +9,7 @@ import { KeyBinding, KeyboardAction } from '../../../../types';
// for all dialog actions (e.g. detectSceneChanges) we must use keyup, or we risk having the button press inserted into the dialog's input element right after the dialog opens // for all dialog actions (e.g. detectSceneChanges) we must use keyup, or we risk having the button press inserted into the dialog's input element right after the dialog opens
// todo use keyup for most events? // todo use keyup for most events?
const keyupActions = new Set<KeyboardAction>(['seekBackwards', 'seekForwards', 'detectBlackScenes', 'detectSilentScenes', 'detectSceneChanges']); const keyupActions = new Set<KeyboardAction>(['seekBackwards', 'seekForwards', 'seekBackwards2', 'seekForwards2', 'seekBackwards3', 'seekForwards3', 'detectBlackScenes', 'detectSilentScenes', 'detectSceneChanges']);
interface StoredAction { action: KeyboardAction, keyup?: boolean } interface StoredAction { action: KeyboardAction, keyup?: boolean }

View File

@ -99,6 +99,10 @@ export default () => {
useEffect(() => safeSetConfig({ keyboardSeekAccFactor }), [keyboardSeekAccFactor]); useEffect(() => safeSetConfig({ keyboardSeekAccFactor }), [keyboardSeekAccFactor]);
const [keyboardNormalSeekSpeed, setKeyboardNormalSeekSpeed] = useState(safeGetConfigInitial('keyboardNormalSeekSpeed')); const [keyboardNormalSeekSpeed, setKeyboardNormalSeekSpeed] = useState(safeGetConfigInitial('keyboardNormalSeekSpeed'));
useEffect(() => safeSetConfig({ keyboardNormalSeekSpeed }), [keyboardNormalSeekSpeed]); useEffect(() => safeSetConfig({ keyboardNormalSeekSpeed }), [keyboardNormalSeekSpeed]);
const [keyboardSeekSpeed2, setKeyboardSeekSpeed2] = useState(safeGetConfigInitial('keyboardSeekSpeed2'));
useEffect(() => safeSetConfig({ keyboardSeekSpeed2 }), [keyboardSeekSpeed2]);
const [keyboardSeekSpeed3, setKeyboardSeekSpeed3] = useState(safeGetConfigInitial('keyboardSeekSpeed3'));
useEffect(() => safeSetConfig({ keyboardSeekSpeed3 }), [keyboardSeekSpeed3]);
const [treatInputFileModifiedTimeAsStart, setTreatInputFileModifiedTimeAsStart] = useState(safeGetConfigInitial('treatInputFileModifiedTimeAsStart')); const [treatInputFileModifiedTimeAsStart, setTreatInputFileModifiedTimeAsStart] = useState(safeGetConfigInitial('treatInputFileModifiedTimeAsStart'));
useEffect(() => safeSetConfig({ treatInputFileModifiedTimeAsStart }), [treatInputFileModifiedTimeAsStart]); useEffect(() => safeSetConfig({ treatInputFileModifiedTimeAsStart }), [treatInputFileModifiedTimeAsStart]);
@ -220,6 +224,10 @@ export default () => {
setKeyboardSeekAccFactor, setKeyboardSeekAccFactor,
keyboardNormalSeekSpeed, keyboardNormalSeekSpeed,
setKeyboardNormalSeekSpeed, setKeyboardNormalSeekSpeed,
keyboardSeekSpeed2,
setKeyboardSeekSpeed2,
keyboardSeekSpeed3,
setKeyboardSeekSpeed3,
treatInputFileModifiedTimeAsStart, treatInputFileModifiedTimeAsStart,
setTreatInputFileModifiedTimeAsStart, setTreatInputFileModifiedTimeAsStart,
treatOutputFileModifiedTimeAsStart, treatOutputFileModifiedTimeAsStart,

View File

@ -70,7 +70,7 @@ export type EdlImportType = 'youtube' | EdlFileType;
export type EdlExportType = 'csv' | 'tsv-human' | 'csv-human' | 'csv-frames' | 'srt' | 'llc'; export type EdlExportType = 'csv' | 'tsv-human' | 'csv-human' | 'csv-frames' | 'srt' | 'llc';
export type TunerType = 'wheelSensitivity' | 'keyboardNormalSeekSpeed' | 'keyboardSeekAccFactor'; export type TunerType = 'wheelSensitivity' | 'keyboardNormalSeekSpeed' | 'keyboardSeekSpeed2' | 'keyboardSeekSpeed3' | 'keyboardSeekAccFactor';
export interface RenderableWaveform { export interface RenderableWaveform {
createdAt: Date, createdAt: Date,

View File

@ -1,4 +1,4 @@
export type KeyboardAction = 'addSegment' | 'togglePlayResetSpeed' | 'togglePlayNoResetSpeed' | 'reducePlaybackRate' | 'reducePlaybackRateMore' | 'increasePlaybackRate' | 'increasePlaybackRateMore' | 'timelineToggleComfortZoom' | 'seekPreviousFrame' | 'seekNextFrame' | 'captureSnapshot' | 'setCutStart' | 'setCutEnd' | 'removeCurrentSegment' | 'cleanupFilesDialog' | 'splitCurrentSegment' | 'increaseRotation' | 'goToTimecode' | 'seekBackwards' | 'seekBackwardsPercent' | 'seekBackwardsPercent' | 'seekBackwardsKeyframe' | 'jumpCutStart' | 'seekForwards' | 'seekForwardsPercent' | 'seekForwardsPercent' | 'seekForwardsKeyframe' | 'jumpCutEnd' | 'jumpTimelineStart' | 'jumpTimelineEnd' | 'jumpFirstSegment' | 'jumpPrevSegment' | 'timelineZoomIn' | 'timelineZoomIn' | 'batchPreviousFile' | 'jumpLastSegment' | 'jumpNextSegment' | 'timelineZoomOut' | 'timelineZoomOut' | 'batchNextFile' | 'batchOpenSelectedFile' | 'batchOpenPreviousFile' | 'batchOpenNextFile' | 'undo' | 'undo' | 'redo' | 'redo' | 'copySegmentsToClipboard' | 'copySegmentsToClipboard' | 'toggleFullscreenVideo' | 'labelCurrentSegment' | 'export' | 'toggleKeyboardShortcuts' | 'closeActiveScreen' | 'increaseVolume' | 'decreaseVolume' | 'detectBlackScenes' | 'detectSilentScenes' | 'detectSceneChanges' | 'toggleLastCommands' | 'play' | 'pause' | 'reloadFile' | 'html5ify' | 'togglePlayOnlyCurrentSegment' | 'toggleLoopOnlyCurrentSegment' | 'toggleLoopStartEndOnlyCurrentSegment' | 'toggleLoopSelectedSegments' | 'editCurrentSegmentTags' | 'duplicateCurrentSegment' | 'reorderSegsByStartTime' | 'invertAllSegments' | 'fillSegmentsGaps' | 'shiftAllSegmentTimes' | 'alignSegmentTimesToKeyframes' | 'createSegmentsFromKeyframes' | 'createFixedDurationSegments' | 'createNumSegments' | 'createRandomSegments' | 'shuffleSegments' | 'combineOverlappingSegments' | 'combineSelectedSegments' | 'clearSegments' | 'toggleSegmentsList' | 'selectOnlyCurrentSegment' | 'deselectAllSegments' | 'selectAllSegments' | 'toggleCurrentSegmentSelected' | 'invertSelectedSegments' | 'removeSelectedSegments' | 'toggleStreamsSelector' | 'extractAllStreams' | 'showStreamsSelector' | 'showIncludeExternalStreamsDialog' | 'captureSnapshotAsCoverArt' | 'extractCurrentSegmentFramesAsImages' | 'extractSelectedSegmentsFramesAsImages' | 'convertFormatBatch' | 'convertFormatCurrentFile' | 'fixInvalidDuration' | 'closeBatch' | 'concatBatch' | 'toggleKeyframeCutMode' | 'toggleCaptureFormat' | 'toggleStripAudio' | 'toggleStripThumbnail' | 'setStartTimeOffset' | 'toggleWaveformMode' | 'toggleShowThumbnails' | 'toggleShowKeyframes' | 'toggleSettings' | 'openSendReportDialog' | 'openFilesDialog' | 'exportYouTube' | 'closeCurrentFile' | 'quit'; export type KeyboardAction = 'addSegment' | 'togglePlayResetSpeed' | 'togglePlayNoResetSpeed' | 'reducePlaybackRate' | 'reducePlaybackRateMore' | 'increasePlaybackRate' | 'increasePlaybackRateMore' | 'timelineToggleComfortZoom' | 'seekPreviousFrame' | 'seekNextFrame' | 'captureSnapshot' | 'setCutStart' | 'setCutEnd' | 'removeCurrentSegment' | 'cleanupFilesDialog' | 'splitCurrentSegment' | 'increaseRotation' | 'goToTimecode' | 'seekBackwards' | 'seekBackwards2' | 'seekBackwards3' | 'seekBackwardsPercent' | 'seekBackwardsPercent' | 'seekBackwardsKeyframe' | 'jumpCutStart' | 'seekForwards' | 'seekForwards2' | 'seekForwards3' | 'seekForwardsPercent' | 'seekForwardsPercent' | 'seekForwardsKeyframe' | 'jumpCutEnd' | 'jumpTimelineStart' | 'jumpTimelineEnd' | 'jumpFirstSegment' | 'jumpPrevSegment' | 'timelineZoomIn' | 'timelineZoomIn' | 'batchPreviousFile' | 'jumpLastSegment' | 'jumpNextSegment' | 'timelineZoomOut' | 'timelineZoomOut' | 'batchNextFile' | 'batchOpenSelectedFile' | 'batchOpenPreviousFile' | 'batchOpenNextFile' | 'undo' | 'undo' | 'redo' | 'redo' | 'copySegmentsToClipboard' | 'copySegmentsToClipboard' | 'toggleFullscreenVideo' | 'labelCurrentSegment' | 'export' | 'toggleKeyboardShortcuts' | 'closeActiveScreen' | 'increaseVolume' | 'decreaseVolume' | 'detectBlackScenes' | 'detectSilentScenes' | 'detectSceneChanges' | 'toggleLastCommands' | 'play' | 'pause' | 'reloadFile' | 'html5ify' | 'togglePlayOnlyCurrentSegment' | 'toggleLoopOnlyCurrentSegment' | 'toggleLoopStartEndOnlyCurrentSegment' | 'toggleLoopSelectedSegments' | 'editCurrentSegmentTags' | 'duplicateCurrentSegment' | 'reorderSegsByStartTime' | 'invertAllSegments' | 'fillSegmentsGaps' | 'shiftAllSegmentTimes' | 'alignSegmentTimesToKeyframes' | 'createSegmentsFromKeyframes' | 'createFixedDurationSegments' | 'createNumSegments' | 'createRandomSegments' | 'shuffleSegments' | 'combineOverlappingSegments' | 'combineSelectedSegments' | 'clearSegments' | 'toggleSegmentsList' | 'selectOnlyCurrentSegment' | 'deselectAllSegments' | 'selectAllSegments' | 'toggleCurrentSegmentSelected' | 'invertSelectedSegments' | 'removeSelectedSegments' | 'toggleStreamsSelector' | 'extractAllStreams' | 'showStreamsSelector' | 'showIncludeExternalStreamsDialog' | 'captureSnapshotAsCoverArt' | 'extractCurrentSegmentFramesAsImages' | 'extractSelectedSegmentsFramesAsImages' | 'convertFormatBatch' | 'convertFormatCurrentFile' | 'fixInvalidDuration' | 'closeBatch' | 'concatBatch' | 'toggleKeyframeCutMode' | 'toggleCaptureFormat' | 'toggleStripAudio' | 'toggleStripThumbnail' | 'setStartTimeOffset' | 'toggleWaveformMode' | 'toggleShowThumbnails' | 'toggleShowKeyframes' | 'toggleSettings' | 'openSendReportDialog' | 'openFilesDialog' | 'exportYouTube' | 'closeCurrentFile' | 'quit';
export interface KeyBinding { export interface KeyBinding {
keys: string, keys: string,
@ -72,6 +72,8 @@ export interface Config {
outSegTemplate: string | undefined, outSegTemplate: string | undefined,
keyboardSeekAccFactor: number, keyboardSeekAccFactor: number,
keyboardNormalSeekSpeed: number, keyboardNormalSeekSpeed: number,
keyboardSeekSpeed2: number,
keyboardSeekSpeed3: number,
treatInputFileModifiedTimeAsStart: boolean, treatInputFileModifiedTimeAsStart: boolean,
treatOutputFileModifiedTimeAsStart: boolean | undefined | null, treatOutputFileModifiedTimeAsStart: boolean | undefined | null,
outFormatLocked: string | undefined, outFormatLocked: string | undefined,