diff --git a/public/menu.js b/public/menu.js index fc94fc7a..5c2c5f6b 100644 --- a/public/menu.js +++ b/public/menu.js @@ -53,7 +53,7 @@ module.exports = ({ app, mainWindow, newVersion, isStoreBuild }) => { label: esc(t('Import project')), submenu: [ { - label: esc(t('Times in seconds (CSV)')), + label: esc(t('Times in seconds / Timestamps (CSV)')), click() { mainWindow.webContents.send('importEdlFile', 'csv'); }, diff --git a/src/edlFormats.js b/src/edlFormats.js index 33266f3a..4d2946c1 100644 --- a/src/edlFormats.js +++ b/src/edlFormats.js @@ -26,7 +26,14 @@ export async function parseCsv(csvStr, processTime = (t) => t) { function parseTimeVal(str) { if (str === '') return undefined; - const parsed = parseFloat(str, 10); + let timestampMatch = str.match(/^(\d{1,2}):(\d{1,2}):(\d{1,2})(?:\.(\d{1,3}))?$/); + let parsed = undefined; + if (timestampMatch && timestampMatch.length === 5) { + let [, h, m, s, ms] = timestampMatch; + parsed = parseInt(h, 10) * 60 + parseInt(m, 10) * 60 + parseInt(s, 10) + parseInt(ms, 10) / 1000; + } else { + parsed = parseFloat(str, 10); + } return processTime(parsed); } const mapped = rows diff --git a/src/edlFormats.test.js b/src/edlFormats.test.js index 88dcb402..d8bbb67c 100644 --- a/src/edlFormats.test.js +++ b/src/edlFormats.test.js @@ -4,7 +4,7 @@ import { fileURLToPath } from 'url'; import { it, describe, expect } from 'vitest'; -import { parseYouTube, formatYouTube, parseMplayerEdl, parseXmeml, parseFcpXml, parseCsv, getTimeFromFrameNum, formatCsvFrames, getFrameCountRaw, parsePbf, parseDvAnalyzerSummaryTxt } from './edlFormats'; +import { parseYouTube, formatYouTube, parseMplayerEdl, parseXmeml, parseFcpXml, parseCsv, getTimeFromFrameNum, formatCsvFrames, formatCsvHuman, getFrameCountRaw, parsePbf, parseDvAnalyzerSummaryTxt } from './edlFormats'; // eslint-disable-next-line no-underscore-dangle const __dirname = dirname(fileURLToPath(import.meta.url)); @@ -211,6 +211,26 @@ it('parses csv with frames', async () => { expect(formatted).toEqual(csvFramesStr); }); +const csvTimestampStr = `\ +00:01:54.612,00:03:09.053,A +00:05:00.448,00:07:56.194,B +00:09:27.075,00:11:44.264,C +`; + +it('parses csv with timestamps', async () => { + const fps = 30; + const parsed = await parseCsv(csvTimestampStr); + + expect(parsed).toEqual([ + { end: 189.053, name: 'A', start: 114.612}, + { end: 476.194, name: 'B', start: 300.448}, + { end: 704.264, name: 'C', start: 567.075}, + ]); + + const formatted = await formatCsvHuman(parsed); + expect(formatted).toEqual(csvTimestampStr); +}); + it('parses pbf', async () => { expect(parsePbf(await readFixture('test1.pbf', null))).toMatchSnapshot(); expect(parsePbf(await readFixture('test2.pbf', null))).toMatchSnapshot();