1
0
mirror of https://github.com/mifi/lossless-cut.git synced 2024-11-25 19:52:44 +01:00

allow showing timecode as frame counts #878

This commit is contained in:
Mikael Finstad 2022-01-14 15:57:14 +07:00
parent 7928257003
commit 6b5857b902
No known key found for this signature in database
GPG Key ID: 25AB36E3E81CBC26
4 changed files with 64 additions and 42 deletions

View File

@ -13,7 +13,7 @@ const defaults = {
keyframeCut: true,
autoMerge: false,
autoDeleteMergedSegments: true,
timecodeShowFrames: false,
timecodeFormat: 'timecodeWithDecimalFraction',
invertCutSegments: false,
autoExportExtraStreams: true,
exportConfirmEnabled: true,

View File

@ -170,7 +170,7 @@ const App = memo(() => {
const isCustomFormatSelected = fileFormat !== detectedFileFormat;
const {
captureFormat, setCaptureFormat, customOutDir, setCustomOutDir, keyframeCut, setKeyframeCut, preserveMovData, setPreserveMovData, movFastStart, setMovFastStart, avoidNegativeTs, setAvoidNegativeTs, autoMerge, setAutoMerge, timecodeShowFrames, setTimecodeShowFrames, invertCutSegments, setInvertCutSegments, autoExportExtraStreams, setAutoExportExtraStreams, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, playbackVolume, setPlaybackVolume, autoSaveProjectFile, setAutoSaveProjectFile, wheelSensitivity, setWheelSensitivity, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, ffmpegExperimental, setFfmpegExperimental, hideNotifications, setHideNotifications, autoLoadTimecode, setAutoLoadTimecode, autoDeleteMergedSegments, setAutoDeleteMergedSegments, exportConfirmEnabled, setExportConfirmEnabled, segmentsToChapters, setSegmentsToChapters, preserveMetadataOnMerge, setPreserveMetadataOnMerge, simpleMode, setSimpleMode, outSegTemplate, setOutSegTemplate, keyboardSeekAccFactor, setKeyboardSeekAccFactor, keyboardNormalSeekSpeed, setKeyboardNormalSeekSpeed, enableTransferTimestamps, setEnableTransferTimestamps, outFormatLocked, setOutFormatLocked, safeOutputFileName, setSafeOutputFileName,
captureFormat, setCaptureFormat, customOutDir, setCustomOutDir, keyframeCut, setKeyframeCut, preserveMovData, setPreserveMovData, movFastStart, setMovFastStart, avoidNegativeTs, setAvoidNegativeTs, autoMerge, setAutoMerge, timecodeFormat, setTimecodeFormat, invertCutSegments, setInvertCutSegments, autoExportExtraStreams, setAutoExportExtraStreams, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, playbackVolume, setPlaybackVolume, autoSaveProjectFile, setAutoSaveProjectFile, wheelSensitivity, setWheelSensitivity, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, ffmpegExperimental, setFfmpegExperimental, hideNotifications, setHideNotifications, autoLoadTimecode, setAutoLoadTimecode, autoDeleteMergedSegments, setAutoDeleteMergedSegments, exportConfirmEnabled, setExportConfirmEnabled, segmentsToChapters, setSegmentsToChapters, preserveMetadataOnMerge, setPreserveMetadataOnMerge, simpleMode, setSimpleMode, outSegTemplate, setOutSegTemplate, keyboardSeekAccFactor, setKeyboardSeekAccFactor, keyboardNormalSeekSpeed, setKeyboardNormalSeekSpeed, enableTransferTimestamps, setEnableTransferTimestamps, outFormatLocked, setOutFormatLocked, safeOutputFileName, setSafeOutputFileName,
} = useUserPreferences();
const {
@ -421,15 +421,22 @@ const App = memo(() => {
setCutSegments(sortBy(cutSegments, getSegApparentStart));
}, [cutSegments, setCutSegments]);
const formatTimecode = useCallback((sec) => formatDuration({
seconds: sec, fps: timecodeShowFrames ? detectedFps : undefined,
}), [detectedFps, timecodeShowFrames]);
const getFrameCount = useCallback((sec) => {
if (detectedFps == null) return undefined;
return Math.floor(sec * detectedFps);
}, [detectedFps]);
const formatTimecode = useCallback((sec) => {
if (timecodeFormat === 'framesTotal') {
const frameCount = getFrameCount(sec);
return frameCount != null ? frameCount : '';
}
if (timecodeFormat === 'timecodeWithFramesFraction') {
return formatDuration({ seconds: sec, fps: detectedFps });
}
return formatDuration({ seconds: sec });
}, [detectedFps, timecodeFormat, getFrameCount]);
useEffect(() => {
currentTimeRef.current = playing ? playerTime : commandedTime;
}, [commandedTime, playerTime, playing]);
@ -2047,8 +2054,8 @@ const App = memo(() => {
setInvertCutSegments={setInvertCutSegments}
autoSaveProjectFile={autoSaveProjectFile}
setAutoSaveProjectFile={setAutoSaveProjectFile}
timecodeShowFrames={timecodeShowFrames}
setTimecodeShowFrames={setTimecodeShowFrames}
timecodeFormat={timecodeFormat}
setTimecodeFormat={setTimecodeFormat}
askBeforeClose={askBeforeClose}
setAskBeforeClose={setAskBeforeClose}
enableAskForImportChapters={enableAskForImportChapters}
@ -2071,7 +2078,7 @@ const App = memo(() => {
renderCaptureFormatButton={renderCaptureFormatButton}
onTunerRequested={onTunerRequested}
/>
), [changeOutDir, customOutDir, keyframeCut, setKeyframeCut, invertCutSegments, setInvertCutSegments, autoSaveProjectFile, setAutoSaveProjectFile, timecodeShowFrames, setTimecodeShowFrames, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, ffmpegExperimental, setFfmpegExperimental, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, hideNotifications, setHideNotifications, autoLoadTimecode, setAutoLoadTimecode, AutoExportToggler, renderCaptureFormatButton, onTunerRequested, enableTransferTimestamps, setEnableTransferTimestamps]);
), [changeOutDir, customOutDir, keyframeCut, setKeyframeCut, invertCutSegments, setInvertCutSegments, autoSaveProjectFile, setAutoSaveProjectFile, timecodeFormat, setTimecodeFormat, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, ffmpegExperimental, setFfmpegExperimental, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, hideNotifications, setHideNotifications, autoLoadTimecode, setAutoLoadTimecode, AutoExportToggler, renderCaptureFormatButton, onTunerRequested, enableTransferTimestamps, setEnableTransferTimestamps]);
useEffect(() => {
if (!isStoreBuild) loadMifiLink().then(setMifiLink);

View File

@ -1,12 +1,39 @@
import React, { memo, useCallback } from 'react';
import React, { memo, useCallback, useMemo } from 'react';
import { FaYinYang } from 'react-icons/fa';
import { Button, Table, NumericalIcon, KeyIcon, FolderCloseIcon, DocumentIcon, TimeIcon, Checkbox, Select } from 'evergreen-ui';
import { useTranslation } from 'react-i18next';
// https://www.electronjs.org/docs/api/locales
// See i18n.js
const langNames = {
en: 'English',
cs: 'Čeština',
de: 'Deutsch',
es: 'Español',
fr: 'Français',
it: 'Italiano',
nl: 'Nederlands',
nb: 'Norsk',
pl: 'Polski',
pt: 'Português',
pt_BR: 'português do Brasil',
fi: 'Suomi',
ru: 'русский',
// sr: 'Cрпски',
tr: 'Türkçe',
vi: 'Tiếng Việt',
ja: '日本語',
zh: '中文',
zh_Hant: '繁體中文',
zh_Hans: '简体中文',
ko: '한국어',
};
const Settings = memo(({
changeOutDir, customOutDir, keyframeCut, setKeyframeCut, invertCutSegments, setInvertCutSegments,
autoSaveProjectFile, setAutoSaveProjectFile, timecodeShowFrames, setTimecodeShowFrames, askBeforeClose, setAskBeforeClose,
autoSaveProjectFile, setAutoSaveProjectFile, timecodeFormat, setTimecodeFormat, askBeforeClose, setAskBeforeClose,
AutoExportToggler, renderCaptureFormatButton, onTunerRequested, language, setLanguage,
invertTimelineScroll, setInvertTimelineScroll, ffmpegExperimental, setFfmpegExperimental,
enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction,
@ -26,31 +53,19 @@ const Settings = memo(({
setLanguage(l);
}, [setLanguage]);
// https://www.electronjs.org/docs/api/locales
// See i18n.js
const langNames = {
en: 'English',
cs: 'Čeština',
de: 'Deutsch',
es: 'Español',
fr: 'Français',
it: 'Italiano',
nl: 'Nederlands',
nb: 'Norsk',
pl: 'Polski',
pt: 'Português',
pt_BR: 'português do Brasil',
fi: 'Suomi',
ru: 'русский',
// sr: 'Cрпски',
tr: 'Türkçe',
vi: 'Tiếng Việt',
ja: '日本語',
zh: '中文',
zh_Hant: '繁體中文',
zh_Hans: '简体中文',
ko: '한국어',
};
const timecodeFormatOptions = useMemo(() => ({
framesTotal: t('Frame numbers'),
timecodeWithDecimalFraction: t('Millisecond fractions'),
timecodeWithFramesFraction: t('Frame fractions'),
}), [t]);
const onTimecodeFormatClick = useCallback(() => {
const keys = Object.keys(timecodeFormatOptions);
let index = keys.indexOf(timecodeFormat);
if (index === -1 || index >= keys.length - 1) index = 0;
else index += 1;
setTimecodeFormat(keys[index]);
}, [setTimecodeFormat, timecodeFormat, timecodeFormatOptions]);
return (
<>
@ -159,8 +174,8 @@ const Settings = memo(({
<Row>
<KeyCell>{t('In timecode show')}</KeyCell>
<Table.TextCell>
<Button iconBefore={timecodeShowFrames ? NumericalIcon : TimeIcon} onClick={() => setTimecodeShowFrames((v) => !v)}>
{timecodeShowFrames ? t('Frame numbers') : t('Millisecond fractions')}
<Button iconBefore={timecodeFormat === 'framesTotal' ? NumericalIcon : TimeIcon} onClick={onTimecodeFormatClick}>
{timecodeFormatOptions[timecodeFormat]}
</Button>
</Table.TextCell>
</Row>

View File

@ -38,8 +38,8 @@ export default () => {
useEffect(() => safeSetConfig('avoidNegativeTs', avoidNegativeTs), [avoidNegativeTs]);
const [autoMerge, setAutoMerge] = useState(configStore.get('autoMerge'));
useEffect(() => safeSetConfig('autoMerge', autoMerge), [autoMerge]);
const [timecodeShowFrames, setTimecodeShowFrames] = useState(configStore.get('timecodeShowFrames'));
useEffect(() => safeSetConfig('timecodeShowFrames', timecodeShowFrames), [timecodeShowFrames]);
const [timecodeFormat, setTimecodeFormat] = useState(configStore.get('timecodeFormat'));
useEffect(() => safeSetConfig('timecodeFormat', timecodeFormat), [timecodeFormat]);
const [invertCutSegments, setInvertCutSegments] = useState(configStore.get('invertCutSegments'));
useEffect(() => safeSetConfig('invertCutSegments', invertCutSegments), [invertCutSegments]);
const [autoExportExtraStreams, setAutoExportExtraStreams] = useState(configStore.get('autoExportExtraStreams'));
@ -113,8 +113,8 @@ export default () => {
setAvoidNegativeTs,
autoMerge,
setAutoMerge,
timecodeShowFrames,
setTimecodeShowFrames,
timecodeFormat,
setTimecodeFormat,
invertCutSegments,
setInvertCutSegments,
autoExportExtraStreams,