|
|
|
|
@ -2,10 +2,10 @@ import JSON5 from 'json5';
|
|
|
|
|
import i18n from 'i18next';
|
|
|
|
|
import invariant from 'tiny-invariant';
|
|
|
|
|
|
|
|
|
|
import { parseSrtToSegments, formatSrt, parseCuesheet, parseXmeml, parseFcpXml, parseCsv, parseCutlist, parsePbf, parseMplayerEdl, formatCsvHuman, formatTsv, formatCsvFrames, formatCsvSeconds, parseCsvTime, getFrameValParser, parseDvAnalyzerSummaryTxt } from './edlFormats';
|
|
|
|
|
import { parseSrtToSegments, formatSrt, parseCuesheet, parseXmeml, parseFcpXml, parseCsv, parseCutlist, parsePbf, parseEdl, formatCsvHuman, formatTsv, formatCsvFrames, formatCsvSeconds, parseCsvTime, getFrameValParser, parseDvAnalyzerSummaryTxt } from './edlFormats';
|
|
|
|
|
import { askForYouTubeInput, showOpenDialog } from './dialogs';
|
|
|
|
|
import { getOutPath } from './util';
|
|
|
|
|
import { EdlExportType, EdlFileType, EdlImportType, Segment, StateSegment } from './types';
|
|
|
|
|
import { EdlExportType, EdlFileType, EdlImportType, GetFrameCount, Segment, StateSegment } from './types';
|
|
|
|
|
|
|
|
|
|
const { readFile, writeFile } = window.require('fs/promises');
|
|
|
|
|
const cueParser = window.require('cue-parser');
|
|
|
|
|
@ -13,68 +13,76 @@ const { basename } = window.require('path');
|
|
|
|
|
|
|
|
|
|
const { dialog } = window.require('@electron/remote');
|
|
|
|
|
|
|
|
|
|
export async function loadCsvSeconds(path: string) {
|
|
|
|
|
|
|
|
|
|
async function loadCsvSeconds(path: string) {
|
|
|
|
|
return parseCsv(await readFile(path, 'utf8'), parseCsvTime);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function loadCsvFrames(path: string, fps?: number) {
|
|
|
|
|
if (!fps) throw new Error('The loaded file has an unknown framerate');
|
|
|
|
|
async function loadCsvFrames(path: string, fps: number) {
|
|
|
|
|
return parseCsv(await readFile(path, 'utf8'), getFrameValParser(fps));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function loadCutlistSeconds(path: string) {
|
|
|
|
|
async function loadCutlistSeconds(path: string) {
|
|
|
|
|
return parseCutlist(await readFile(path, 'utf8'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function loadXmeml(path: string) {
|
|
|
|
|
async function loadXmeml(path: string) {
|
|
|
|
|
return parseXmeml(await readFile(path, 'utf8'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function loadFcpXml(path: string) {
|
|
|
|
|
async function loadFcpXml(path: string) {
|
|
|
|
|
return parseFcpXml(await readFile(path, 'utf8'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function loadDvAnalyzerSummaryTxt(path: string) {
|
|
|
|
|
async function loadDvAnalyzerSummaryTxt(path: string) {
|
|
|
|
|
return parseDvAnalyzerSummaryTxt(await readFile(path, 'utf8'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function loadPbf(path: string) {
|
|
|
|
|
async function loadPbf(path: string) {
|
|
|
|
|
return parsePbf(await readFile(path));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function loadMplayerEdl(path: string) {
|
|
|
|
|
return parseMplayerEdl(await readFile(path, 'utf8'));
|
|
|
|
|
async function loadEdl(path: string, fps: number) {
|
|
|
|
|
return parseEdl(await readFile(path, 'utf8'), fps);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function loadCue(path: string) {
|
|
|
|
|
async function loadCue(path: string) {
|
|
|
|
|
return parseCuesheet(cueParser.parse(path));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function loadSrt(path: string) {
|
|
|
|
|
async function loadSrt(path: string) {
|
|
|
|
|
return parseSrtToSegments(await readFile(path, 'utf8'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function saveCsv(path: string, cutSegments) {
|
|
|
|
|
export async function saveCsv(path: string, cutSegments: Segment[]) {
|
|
|
|
|
await writeFile(path, await formatCsvSeconds(cutSegments));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function saveCsvHuman(path: string, cutSegments) {
|
|
|
|
|
export async function saveCsvHuman(path: string, cutSegments: Segment[]) {
|
|
|
|
|
await writeFile(path, await formatCsvHuman(cutSegments));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function saveCsvFrames({ path, cutSegments, getFrameCount }) {
|
|
|
|
|
export async function saveCsvFrames({ path, cutSegments, getFrameCount }: {
|
|
|
|
|
path: string,
|
|
|
|
|
cutSegments: Segment[],
|
|
|
|
|
getFrameCount: GetFrameCount,
|
|
|
|
|
}) {
|
|
|
|
|
await writeFile(path, await formatCsvFrames({ cutSegments, getFrameCount }));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function saveTsv(path: string, cutSegments) {
|
|
|
|
|
export async function saveTsv(path: string, cutSegments: Segment[]) {
|
|
|
|
|
await writeFile(path, await formatTsv(cutSegments));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function saveSrt(path: string, cutSegments) {
|
|
|
|
|
await writeFile(path, await formatSrt(cutSegments));
|
|
|
|
|
export async function saveSrt(path: string, cutSegments: Segment[]) {
|
|
|
|
|
await writeFile(path, formatSrt(cutSegments));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function saveLlcProject({ savePath, filePath, cutSegments }) {
|
|
|
|
|
export async function saveLlcProject({ savePath, filePath, cutSegments }: {
|
|
|
|
|
savePath: string,
|
|
|
|
|
filePath: string,
|
|
|
|
|
cutSegments: StateSegment[],
|
|
|
|
|
}) {
|
|
|
|
|
const projectData = {
|
|
|
|
|
version: 1,
|
|
|
|
|
mediaFileName: basename(filePath),
|
|
|
|
|
@ -99,14 +107,20 @@ export async function loadLlcProject(path: string) {
|
|
|
|
|
|
|
|
|
|
export async function readEdlFile({ type, path, fps }: { type: EdlFileType, path: string, fps?: number | undefined }) {
|
|
|
|
|
if (type === 'csv') return loadCsvSeconds(path);
|
|
|
|
|
if (type === 'csv-frames') return loadCsvFrames(path, fps);
|
|
|
|
|
if (type === 'csv-frames') {
|
|
|
|
|
invariant(fps != null, 'The loaded media has an unknown framerate');
|
|
|
|
|
return loadCsvFrames(path, fps);
|
|
|
|
|
}
|
|
|
|
|
if (type === 'cutlist') return loadCutlistSeconds(path);
|
|
|
|
|
if (type === 'xmeml') return loadXmeml(path);
|
|
|
|
|
if (type === 'fcpxml') return loadFcpXml(path);
|
|
|
|
|
if (type === 'dv-analyzer-summary-txt') return loadDvAnalyzerSummaryTxt(path);
|
|
|
|
|
if (type === 'cue') return loadCue(path);
|
|
|
|
|
if (type === 'pbf') return loadPbf(path);
|
|
|
|
|
if (type === 'mplayer') return loadMplayerEdl(path);
|
|
|
|
|
if (type === 'edl') {
|
|
|
|
|
invariant(fps != null, 'The loaded media has an unknown framerate');
|
|
|
|
|
return loadEdl(path, fps);
|
|
|
|
|
}
|
|
|
|
|
if (type === 'srt') return loadSrt(path);
|
|
|
|
|
if (type === 'llc') {
|
|
|
|
|
const project = await loadLlcProject(path);
|
|
|
|
|
@ -125,7 +139,7 @@ export async function askForEdlImport({ type, fps }: { type: EdlImportType, fps?
|
|
|
|
|
else if (type === 'fcpxml') filters = [{ name: i18n.t('FCPXML files'), extensions: ['fcpxml'] }];
|
|
|
|
|
else if (type === 'cue') filters = [{ name: i18n.t('CUE files'), extensions: ['cue'] }];
|
|
|
|
|
else if (type === 'pbf') filters = [{ name: i18n.t('PBF files'), extensions: ['pbf'] }];
|
|
|
|
|
else if (type === 'mplayer') filters = [{ name: i18n.t('MPlayer EDL'), extensions: ['*'] }];
|
|
|
|
|
else if (type === 'edl') filters = [{ name: i18n.t('EDL'), extensions: ['*'] }];
|
|
|
|
|
else if (type === 'dv-analyzer-summary-txt') filters = [{ name: i18n.t('DV Analyzer Summary.txt'), extensions: ['txt'] }];
|
|
|
|
|
else if (type === 'srt') filters = [{ name: i18n.t('Subtitles (SRT)'), extensions: ['srt'] }];
|
|
|
|
|
else if (type === 'llc') filters = [{ name: i18n.t('LosslessCut project'), extensions: ['llc'] }];
|
|
|
|
|
@ -137,7 +151,11 @@ export async function askForEdlImport({ type, fps }: { type: EdlImportType, fps?
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function exportEdlFile({ type, cutSegments, customOutDir, filePath, getFrameCount }: {
|
|
|
|
|
type: EdlExportType, cutSegments: Segment[], customOutDir?: string | undefined, filePath?: string | undefined, getFrameCount: (a: number) => number | undefined,
|
|
|
|
|
type: EdlExportType,
|
|
|
|
|
cutSegments: StateSegment[],
|
|
|
|
|
customOutDir?: string | undefined,
|
|
|
|
|
filePath?: string | undefined,
|
|
|
|
|
getFrameCount: GetFrameCount,
|
|
|
|
|
}) {
|
|
|
|
|
invariant(filePath != null);
|
|
|
|
|
|
|
|
|
|
|