kopia lustrzana https://github.com/mifi/lossless-cut
rodzic
1bada15d39
commit
da48d5bd1b
|
@ -38,7 +38,7 @@ module.exports = (app, mainWindow, newVersion) => {
|
|||
{
|
||||
label: 'Save project (CSV)',
|
||||
click() {
|
||||
mainWindow.webContents.send('exportEdlFile');
|
||||
mainWindow.webContents.send('exportEdlFile', 'csv');
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -70,6 +70,17 @@ module.exports = (app, mainWindow, newVersion) => {
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Export project',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Human readable (TSV)',
|
||||
click() {
|
||||
mainWindow.webContents.send('exportEdlFile', 'tsv');
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Convert to supported format',
|
||||
|
|
29
src/App.jsx
29
src/App.jsx
|
@ -45,7 +45,7 @@ import {
|
|||
findNearestKeyFrameTime, html5ify as ffmpegHtml5ify, isStreamThumbnail, isAudioSupported, isIphoneHevc, tryReadChaptersToEdl,
|
||||
fixInvalidDuration, getDuration, getTimecodeFromStreams, createChaptersFromSegments,
|
||||
} from './ffmpeg';
|
||||
import { saveCsv, loadCsv, loadXmeml, loadCue, loadPbf } from './edlStore';
|
||||
import { saveCsv, saveTsv, loadCsv, loadXmeml, loadCue, loadPbf } from './edlStore';
|
||||
import {
|
||||
getOutPath, formatDuration, toast, errorToast, showFfmpegFail, setFileNameTitle, getOutDir, withBlur,
|
||||
checkDirWriteAccess, dirExists, openDirToast, isMasBuild, isStoreBuild, dragPreventer, doesPlayerSupportFile,
|
||||
|
@ -1648,19 +1648,28 @@ const App = memo(() => {
|
|||
setStartTimeOffset(newStartTimeOffset);
|
||||
}
|
||||
|
||||
async function exportEdlFile() {
|
||||
async function exportEdlFile(e, type) {
|
||||
try {
|
||||
if (!checkFileOpened()) return;
|
||||
const { canceled, filePath: fp } = await dialog.showSaveDialog({ defaultPath: `${new Date().getTime()}.csv`, filters: [{ name: i18n.t('CSV files'), extensions: ['csv'] }] });
|
||||
if (canceled || !fp) return;
|
||||
if (await exists(fp)) {
|
||||
errorToast(i18n.t('File exists, bailing'));
|
||||
return;
|
||||
|
||||
let filters;
|
||||
let ext;
|
||||
if (type === 'csv') {
|
||||
ext = 'csv';
|
||||
filters = [{ name: i18n.t('CSV files'), extensions: [ext] }];
|
||||
} else if (type === 'tsv') {
|
||||
ext = 'txt';
|
||||
filters = [{ name: i18n.t('TXT files'), extensions: [ext] }];
|
||||
}
|
||||
await saveCsv(fp, cutSegments);
|
||||
|
||||
const { canceled, filePath: fp } = await dialog.showSaveDialog({ defaultPath: `${new Date().getTime()}.${ext}`, filters });
|
||||
if (canceled || !fp) return;
|
||||
console.log('Saving', type, fp);
|
||||
if (type === 'csv') await saveCsv(fp, cutSegments);
|
||||
else if (type === 'tsv') await saveTsv(fp, cutSegments);
|
||||
} catch (err) {
|
||||
errorToast(i18n.t('Failed to export CSV'));
|
||||
console.error('Failed to export CSV', err);
|
||||
errorToast(i18n.t('Failed to export project'));
|
||||
console.error('Failed to export project', type, err);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import csvStringify from 'csv-stringify';
|
|||
import pify from 'pify';
|
||||
|
||||
import { parseCuesheet, parseXmeml, parseCsv, parsePbf } from './edlFormats';
|
||||
import { formatDuration } from './util';
|
||||
|
||||
const fs = window.require('fs-extra');
|
||||
const cueParser = window.require('cue-parser');
|
||||
|
@ -25,8 +26,13 @@ export async function loadCue(path) {
|
|||
}
|
||||
|
||||
export async function saveCsv(path, cutSegments) {
|
||||
console.log('Saving', path);
|
||||
const rows = cutSegments.map(({ start, end, name }) => [start, end, name]);
|
||||
const str = await csvStringifyAsync(rows);
|
||||
await fs.writeFile(path, str);
|
||||
}
|
||||
|
||||
export async function saveTsv(path, cutSegments) {
|
||||
// TODO escape tab, how?
|
||||
const rows = cutSegments.map(({ start, end, name }) => `${start != null ? formatDuration({ seconds: start }) : ''}\t${end != null ? formatDuration({ seconds: end }) : ''}\t${name}`);
|
||||
await fs.writeFile(path, rows.join('\n'));
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue