From 7e056410ecf4fe1859ec4aca0d55774238a7b5c8 Mon Sep 17 00:00:00 2001 From: Mikael Finstad Date: Fri, 7 Apr 2023 16:48:32 +0900 Subject: [PATCH] change to EPOCH_MS and more fixes/improveement --- import-export.md | 1 + src/components/OutSegTemplateEditor.jsx | 24 ++++++++++++------------ src/util/outputNameTemplate.js | 15 ++++++--------- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/import-export.md b/import-export.md index 3f751abf..142ef4b3 100644 --- a/import-export.md +++ b/import-export.md @@ -9,6 +9,7 @@ When exporting multiple segments as separate files, LosslessCut offers you the a | `${FILENAME}` | The original filename without the extension (e.g. `Beach Trip` for a file named `Beach Trip.mp4`) | `${EXT}` | The extension of the file (e.g.: `.mp4`, `.mkv`) | `${SEG_NUM}` | Number of the segment (e.g. `1`, `2` or `3`) +| `${EPOCH_MS}` | Number of milliseconds since epoch (e.g. `1680852771465`) | `${SEG_LABEL}` | The label of the segment (e.g. `Getting_Lunch`) | `${SEG_SUFFIX}` | If a label exists for this segment, the label will be used, prepended by `-`. Otherwise, the segment number prepended by `-seg` will be used (e.g. `-Getting_Lunch`, `-seg1`) | `${CUT_FROM}` | The timestamp for the beginning of the segment in `hh.mm.ss.sss` format (e.g. `00.00.27.184`) diff --git a/src/components/OutSegTemplateEditor.jsx b/src/components/OutSegTemplateEditor.jsx index 182a754e..3879558e 100644 --- a/src/components/OutSegTemplateEditor.jsx +++ b/src/components/OutSegTemplateEditor.jsx @@ -4,6 +4,7 @@ import i18n from 'i18next'; import { useTranslation } from 'react-i18next'; import { WarningSignIcon, ErrorIcon, Button, IconButton, TickIcon, ResetIcon } from 'evergreen-ui'; import withReactContent from 'sweetalert2-react-content'; +import { IoIosHelpCircle } from 'react-icons/io'; import Swal from '../swal'; import HighlightedText from './HighlightedText'; @@ -12,6 +13,8 @@ import useUserSettings from '../hooks/useUserSettings'; const ReactSwal = withReactContent(Swal); +const electron = window.require('electron'); + // eslint-disable-next-line no-template-curly-in-string const extVar = '${EXT}'; @@ -26,7 +29,7 @@ const OutSegTemplateEditor = memo(({ outSegTemplate, setOutSegTemplate, generate const [error, setError] = useState(); const [outSegFileNames, setOutSegFileNames] = useState(); const [shown, setShown] = useState(); - const inputRef = useRef(null); + const inputRef = useRef(); const { t } = useTranslation(); @@ -84,18 +87,14 @@ const OutSegTemplateEditor = memo(({ outSegTemplate, setOutSegTemplate, generate const needToShow = shown || error != null; - const onTextClick = useCallback(() => { - inputRef.current.focus(); - }, []); - const onVariableClick = useCallback((variable) => { const input = inputRef.current; const startPos = input.selectionStart; const endPos = input.selectionEnd; - - const newValue = `${text.slice(0, startPos)}${'${' + variable + '}' + text.slice(endPos)}`; + + const newValue = `${text.slice(0, startPos)}${`\${${variable}}${text.slice(endPos)}`}`; setText(newValue); - + // Move the cursor to after the inserted variable const newPos = startPos + variable.length + 2; input.selectionStart = newPos; @@ -113,7 +112,7 @@ const OutSegTemplateEditor = memo(({ outSegTemplate, setOutSegTemplate, generate {needToShow && ( <>
- + {outSegFileNames != null && } @@ -123,9 +122,10 @@ const OutSegTemplateEditor = memo(({ outSegTemplate, setOutSegTemplate, generate
{error != null &&
{i18n.t('There is an error in the file name template:')} {error}
} {isMissingExtension &&
{i18n.t('The file name template is missing {{ext}} and will result in a file without the suggested extension. This may result in an unplayable output file.', { ext: extVar })}
} -
- {`${i18n.t('Variables')}`}{': '} - {['FILENAME', 'TIMESTAMP', 'CUT_FROM', 'CUT_TO', 'SEG_NUM', 'SEG_LABEL', 'SEG_SUFFIX', 'EXT', 'SEG_TAGS.XX'].map((variable) => ( +
+ {`${i18n.t('Variables')}:`} + electron.shell.openExternal('https://github.com/mifi/lossless-cut/blob/master/import-export.md#customising-exported-file-names')} /> + {['FILENAME', 'CUT_FROM', 'CUT_TO', 'SEG_NUM', 'SEG_LABEL', 'SEG_SUFFIX', 'EXT', 'SEG_TAGS.XX', 'EPOCH_MS'].map((variable) => ( onVariableClick(variable)}>{variable} ))}
diff --git a/src/util/outputNameTemplate.js b/src/util/outputNameTemplate.js index 500d92b0..95779b6b 100644 --- a/src/util/outputNameTemplate.js +++ b/src/util/outputNameTemplate.js @@ -65,15 +65,9 @@ export function getOutSegError({ fileNames, filePath, outputDir, safeOutputFileN // This is used as a fallback and so it has to always generate unique file names // eslint-disable-next-line no-template-curly-in-string export const defaultOutSegTemplate = '${FILENAME}-${CUT_FROM}-${CUT_TO}${SEG_SUFFIX}${EXT}'; -let currentTimestamp = Date.now(); -function interpolateSegmentFileName({ template, inputFileNameWithoutExt, segSuffix, ext, segNum, segLabel, cutFrom, cutTo, tags }) { - const compiled = lodashTemplate(template); - if (segSuffix) { - if (segNum > 1) { - currentTimestamp += 1; - } - } +function interpolateSegmentFileName({ template, epochMs, inputFileNameWithoutExt, segSuffix, ext, segNum, segLabel, cutFrom, cutTo, tags }) { + const compiled = lodashTemplate(template); const data = { FILENAME: inputFileNameWithoutExt, @@ -81,7 +75,7 @@ function interpolateSegmentFileName({ template, inputFileNameWithoutExt, segSuff EXT: ext, SEG_NUM: segNum, SEG_LABEL: segLabel, - TIMESTAMP: currentTimestamp, + EPOCH_MS: String(epochMs), CUT_FROM: cutFrom, CUT_TO: cutTo, SEG_TAGS: { @@ -99,6 +93,8 @@ function formatSegNum(segIndex, segments) { } export function generateOutSegFileNames({ segments, template, forceSafeOutputFileName, formatTimecode, isCustomFormatSelected, fileFormat, filePath, safeOutputFileName, maxLabelLength }) { + const currentTimestamp = Date.now(); + return segments.map((segment, i) => { const { start, end, name = '' } = segment; const segNum = formatSegNum(i, segments); @@ -118,6 +114,7 @@ export function generateOutSegFileNames({ segments, template, forceSafeOutputFil const segFileName = interpolateSegmentFileName({ template, + epochMs: currentTimestamp + i, // for convenience: give each segment a unique timestamp segNum, inputFileNameWithoutExt, segSuffix: getSegSuffix(),