From c63d61d472ac2b5c1fea2cba6eed53655e859d00 Mon Sep 17 00:00:00 2001 From: Mikael Finstad Date: Tue, 24 Aug 2021 20:23:27 +0700 Subject: [PATCH] support Mplay EDL types 1,2,3 also #609 --- src/edlFormats.js | 32 ++++++++++++++------ src/edlFormats.test.js | 63 ++++++++++++++++++++++++++++++---------- src/fixtures/mplayer.edl | 5 ++++ 3 files changed, 76 insertions(+), 24 deletions(-) create mode 100644 src/fixtures/mplayer.edl diff --git a/src/edlFormats.js b/src/edlFormats.js index 8085946..8f3a138 100644 --- a/src/edlFormats.js +++ b/src/edlFormats.js @@ -34,20 +34,34 @@ export async function parseCsv(str) { } export async function parseMplayerEdl(text) { - const cutAwaySegments = text.split('\n').map((line) => { - // We only support "Cut" (0) - const match = line.match(/^\s*([^\s]+)\s+([^\s]+)\s+0\s*$/); + const allRows = text.split('\n').map((line) => { + const match = line.match(/^\s*([^\s]+)\s+([^\s]+)\s+([0123])\s*$/); if (!match) return undefined; const start = parseFloat(match[1]); const end = parseFloat(match[2]); - if (start < 0 || end < 0 || start >= end) throw new Error(i18n.t('Invalid start or end value. Must contain a number of seconds')); - return { start, end }; + const type = parseInt(match[3], 10); + if (Number.isNaN(start) || Number.isNaN(end)) return undefined; + if (start < 0 || end < 0 || start >= end) return undefined; + return { start, end, type }; }).filter((it) => it); - if (cutAwaySegments.length === 0) throw new Error(i18n.t('Invalid EDL data found')); - const inverted = invertSegments(sortSegments(cutAwaySegments)); - if (!inverted) throw new Error(i18n.t('Invalid EDL data found')); - return inverted; + const cutAwaySegments = allRows.filter((row) => row.type === 0); + const muteSegments = allRows.filter((row) => row.type === 1); + const sceneMarkers = allRows.filter((row) => row.type === 2); + const commercialBreaks = allRows.filter((row) => row.type === 3); + + const inverted = cutAwaySegments.length > 0 ? invertSegments(sortSegments(cutAwaySegments)) : []; + + const map = (segments, name, type) => segments.map(({ start, end }) => ({ start, end, name, tags: { mplayerEdlType: type } })); + + const out = [ + ...map(inverted || [], 'Cut', 0), + ...map(muteSegments, 'Mute', 1), + ...map(sceneMarkers, 'Scene Marker', 2), + ...map(commercialBreaks, 'Commercial Break', 3), + ]; + if (out.length === 0) throw new Error(i18n.t('Invalid EDL data found')); + return out; } export function parseCuesheet(cuesheet) { diff --git a/src/edlFormats.test.js b/src/edlFormats.test.js index 325e33c..6b6f092 100644 --- a/src/edlFormats.test.js +++ b/src/edlFormats.test.js @@ -1,3 +1,6 @@ +import fs from 'fs'; +import { join } from 'path'; + import { parseYouTube, formatYouTube, parseMplayerEdl } from './edlFormats'; it('parseYoutube', () => { @@ -62,7 +65,7 @@ it('formatYouTube', () => { // https://kodi.wiki/view/Edit_decision_list // http://www.mplayerhq.hu/DOCS/HTML/en/edl.html it('parseMplayerEdl', async () => { - // TODO support more durations: + // TODO support more durations (frames and timestamps): /* const str = `\ 5.3 7.1 0 @@ -80,19 +83,49 @@ it('parseMplayerEdl', async () => { `; */ - const str = `\ -5.3 7.1 0 -15 16.7 1 -420 822 3 -1 255.3 2 -720.1 2 -`; + const str = await fs.promises.readFile(join(__dirname, 'fixtures', 'mplayer.edl'), 'utf-8'); - expect(await parseMplayerEdl(str)).toEqual([{ start: 0, end: 5.3 }, { start: 7.1, end: undefined }]); - - const str2 = `\ - 0 1.1 0 -`; - - expect(await parseMplayerEdl(str2)).toEqual([{ start: 1.1, end: undefined }]); + expect(await parseMplayerEdl(str)).toEqual([ + { start: 0, + end: 5.3, + name: 'Cut', + tags: { mplayerEdlType: 0 }, + }, + { start: 7.1, + end: undefined, + name: 'Cut', + tags: { mplayerEdlType: 0 }, + }, + { + end: 16.7, + start: 15, + name: 'Mute', + tags: { mplayerEdlType: 1 }, + }, + { + end: 255.3, + start: 1, + name: 'Scene Marker', + tags: { mplayerEdlType: 2 }, + }, + { + end: 822, + start: 420, + name: 'Commercial Break', + tags: { mplayerEdlType: 3 }, + }, + ]); +}); + +it('parseMplayerEdl, starting at 0', async () => { + const str2 = ' 0 1.1 0\n'; + + expect(await parseMplayerEdl(str2)).toEqual([{ + start: 1.1, + end: undefined, + name: 'Cut', + tags: { + mplayerEdlType: 0, + }, + }]); }); diff --git a/src/fixtures/mplayer.edl b/src/fixtures/mplayer.edl new file mode 100644 index 0000000..0280400 --- /dev/null +++ b/src/fixtures/mplayer.edl @@ -0,0 +1,5 @@ + 5.3 7.1 0 + 15 16.7 1 + 420 822 3 + 1 255.3 2 + 720.1 2