[go: nahoru, domu]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cutlist (OTR) import option #1952

Merged
merged 2 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add cutlist import option
  • Loading branch information
Lars-Olof Kreim committed Apr 7, 2024
commit 3cc997bcb2649967cbff76e838f0e798d8289240
6 changes: 6 additions & 0 deletions src/main/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ export default ({ app, mainWindow, newVersion, isStoreBuild }: {
mainWindow.webContents.send('importEdlFile', 'csv-frames');
},
},
{
label: esc(t('Cutlist')),
click() {
mainWindow.webContents.send('importEdlFile', 'cutlist');
},
},
{
label: esc(t('EDL (MPlayer)')),
click() {
Expand Down
58 changes: 57 additions & 1 deletion src/renderer/src/edlFormats.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { fileURLToPath } from 'url';
import { it, describe, expect } from 'vitest';


import { parseSrt, formatSrt, parseYouTube, formatYouTube, parseMplayerEdl, parseXmeml, parseFcpXml, parseCsv, parseCsvTime, getFrameValParser, formatCsvFrames, getFrameCountRaw, parsePbf, parseDvAnalyzerSummaryTxt } from './edlFormats';
import { parseSrt, formatSrt, parseYouTube, formatYouTube, parseMplayerEdl, parseXmeml, parseFcpXml, parseCsv, parseCsvTime, getFrameValParser, formatCsvFrames, getFrameCountRaw, parsePbf, parseDvAnalyzerSummaryTxt, parseCutlist } from './edlFormats';

// eslint-disable-next-line no-underscore-dangle
const __dirname = dirname(fileURLToPath(import.meta.url));
Expand Down Expand Up @@ -242,6 +242,62 @@ it('parses csv with timestamps', async () => {
]);
});

const cutlistStr = `
[General]
Application=SomeApplication.exe
Version=0.0.0.1
FramesPerSecond=25
IntendedCutApplicationName=SomeApplication
IntendedCutApplication=SomeApplication.exe
VDUseSmartRendering=1
IntendedCutApplicationVersion=1.7.8
comment1=The following parts of the movie will be kept, the rest will be cut out.
comment2=All values are given in seconds.
NoOfCuts=2
ApplyToFile=Some_File_Name.avi
OriginalFileSizeBytes=123456

[Cut0]
Start=849.12
StartFrame=21228
Duration=1881.84
DurationFrames=47046

[Cut1]
Start=3147.72
StartFrame=78693
Duration=944.6
DurationFrames=23615

[Info]
Author=AuthorName
RatingByAuthor=0
EPGError=0
ActualContent=
MissingBeginning=0
MissingEnding=0
MissingVideo=0
MissingAudio=0
OtherError=0
OtherErrorDescription=
SuggestedMovieName=
UserComment=cutted with XXXX

[Meta]
CutlistId=12345
GeneratedOn=1900-01-01 00:00:01
GeneratedBy=cutlist v0.0.0
`;

it('parses cutlist', async () => {
const parsed = await parseCutlist(cutlistStr);

expect(parsed).toEqual([
{ end: 2730.96, name: 'Cut 0', start: 849.12 },
{ end: 4092.32, name: 'Cut 1', start: 3147.72 },
]);
});

it('parses pbf', async () => {
expect(parsePbf(await readFixtureBinary('test1.pbf'))).toMatchSnapshot();
expect(parsePbf(await readFixtureBinary('test2.pbf'))).toMatchSnapshot();
Expand Down
66 changes: 66 additions & 0 deletions src/renderer/src/edlFormats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,72 @@
return mapped;
}

export async function parseCutlist(clStr: string) {

Check failure on line 73 in src/renderer/src/edlFormats.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Block must not be padded by blank lines

// first parse INI-File into "iniValue" object
const regex = {
section: /^\s*\[\s*([^\]]*)\s*\]\s*$/,

Check failure on line 77 in src/renderer/src/edlFormats.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

/^\s*\[\s*([^\]]*)\s*\]\s*$/ can be optimized to /^\s*\[\s*([^\]]*)\s*]\s*$/
param: /^\s*([^=]+?)\s*=\s*(.*?)\s*$/,
comment: /^\s*;.*$/

Check failure on line 79 in src/renderer/src/edlFormats.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Missing trailing comma
};
const iniValue = {};
const lines = clStr.split(/[\r\n]+/);

Check failure on line 82 in src/renderer/src/edlFormats.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

/[\r\n]+/ can be optimized to /[\n\r]+/
let section:string|null|undefined = null;
lines.forEach(function(line){

Check failure on line 84 in src/renderer/src/edlFormats.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Unexpected function expression

Check warning on line 84 in src/renderer/src/edlFormats.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Unexpected unnamed function

Check failure on line 84 in src/renderer/src/edlFormats.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Missing space before function parentheses

Check failure on line 84 in src/renderer/src/edlFormats.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Missing space before opening brace
if(regex.comment.test(line)){

Check failure on line 85 in src/renderer/src/edlFormats.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Expected indentation of 4 spaces but found 6

Check failure on line 85 in src/renderer/src/edlFormats.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Expected space(s) after "if"

Check failure on line 85 in src/renderer/src/edlFormats.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

Missing space before opening brace
return;
}else if(regex.param.test(line)){
const match = line.match(regex.param) || [];
if(match[1]){
if(section){
iniValue[section][match[1]] = match[2];
}else{
iniValue[match[1]] = match[2];
}
}
}else if(regex.section.test(line)){
const match = line.match(regex.section) || [];
if(match[1]){
iniValue[match[1]] = {};
section = match[1];
}
}else if(line.length == 0 && section){
section = null;
};
});

// end INI-File parse

let found = true;
let i = 0;
const cutArr:{start:number, end:number, name:string}[] = [];
while(found) {
const cutEntry = iniValue['Cut'+i];
if (cutEntry) {
const start = parseFloat(cutEntry.Start);
const end = Math.round((start + parseFloat(cutEntry.Duration) + Number.EPSILON) * 100) / 100
cutArr.push({
start: start,
end: end,
name: `Cut ${i}`,
});
} else {
found = false;
}
i++;
}

if (!cutArr.every(({ start, end }) => (
(start === undefined || !Number.isNaN(start))
&& (end === undefined || !Number.isNaN(end))
))) {
console.log(cutArr);
throw new Error(i18n.t('Invalid start or end value. Must contain a number of seconds'));
}

return cutArr;
}

export async function parseMplayerEdl(text: string) {
const allRows = text.split('\n').flatMap((line) => {
const match = line.match(/^\s*(\S+)\s+(\S+)\s+([0-3])\s*$/);
Expand Down
7 changes: 6 additions & 1 deletion src/renderer/src/edlStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import JSON5 from 'json5';
import i18n from 'i18next';
import type { parse as CueParse } from 'cue-parser';

import { parseSrt, formatSrt, parseCuesheet, parseXmeml, parseFcpXml, parseCsv, parsePbf, parseMplayerEdl, formatCsvHuman, formatTsv, formatCsvFrames, formatCsvSeconds, parseCsvTime, getFrameValParser, parseDvAnalyzerSummaryTxt } from './edlFormats';
import { parseSrt, formatSrt, parseCuesheet, parseXmeml, parseFcpXml, parseCsv, parseCutlist, parsePbf, parseMplayerEdl, 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';
Expand All @@ -22,6 +22,10 @@ export async function loadCsvFrames(path: string, fps?: number) {
return parseCsv(await readFile(path, 'utf8'), getFrameValParser(fps));
}

export async function loadCutlistSeconds(path: string) {
return parseCutlist(await readFile(path, 'utf8'));
}

export async function loadXmeml(path: string) {
return parseXmeml(await readFile(path, 'utf8'));
}
Expand Down Expand Up @@ -96,6 +100,7 @@ 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 === '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);
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export interface InverseCutSegment {

export type PlaybackMode = 'loop-segment-start-end' | 'loop-segment' | 'play-segment-once' | 'loop-selected-segments';

export type EdlFileType = 'csv' | 'csv-frames' | 'xmeml' | 'fcpxml' | 'dv-analyzer-summary-txt' | 'cue' | 'pbf' | 'mplayer' | 'srt' | 'llc';
export type EdlFileType = 'csv' | 'csv-frames' | 'cutlist' | 'xmeml' | 'fcpxml' | 'dv-analyzer-summary-txt' | 'cue' | 'pbf' | 'mplayer' | 'srt' | 'llc';

export type EdlImportType = 'youtube' | EdlFileType;

Expand Down
Loading