diff --git a/src/entry.ts b/src/entry.ts
new file mode 100644
index 0000000..4f977b3
--- /dev/null
+++ b/src/entry.ts
@@ -0,0 +1,17 @@
+import { Producer } from "./producer";
+
+export class Entry {
+ constructor(
+ public producer: Producer,
+ public in_point: string,
+ public out_point: string
+ ) {}
+
+ toXML(): string {
+ return /* HTML */ ``;
+ }
+}
diff --git a/src/example.test.ts b/src/example.test.ts
index ca417fe..995032d 100644
--- a/src/example.test.ts
+++ b/src/example.test.ts
@@ -1,4 +1,5 @@
import { $ } from "zx";
+import { Entry } from "./entry";
import Project from "./kdenlive";
describe("Kdenlive", () => {
@@ -58,4 +59,48 @@ describe("Kdenlive", () => {
await $`echo ${await project.toXML()} > 20a20v-tracks.kdenlive`;
});
});
+
+ describe("clips", () => {
+ it("should generate a 1a1v project with one clip", async () => {
+ const project = new Project(30);
+ const producer = project.addProducer("/home/kuba/Videos/5min.mp4");
+ const video_track = project.addVideoTractor();
+ const audio_track = project.addAudioTractor();
+ const entry = new Entry(producer, "00:00:00.000", "00:00:01.000");
+ video_track.addEntry(entry);
+ audio_track.addEntry(entry);
+ await $`echo ${await project.toXML()} > 1s-clip.kdenlive`;
+ });
+
+ it("should generate a 1a1v project with two contingent clips", async () => {
+ const project = new Project(30);
+ const producer = project.addProducer("/home/kuba/Videos/5min.mp4");
+ const video_track = project.addVideoTractor();
+ const audio_track = project.addAudioTractor();
+ const entry = new Entry(producer, "00:00:00.000", "00:00:01.000");
+ video_track.addEntry(entry);
+ audio_track.addEntry(entry);
+ const entry2 = new Entry(producer, "00:00:01.000", "00:00:02.000");
+ video_track.addEntry(entry2);
+ audio_track.addEntry(entry2);
+ await $`echo ${await project.toXML()} > 2x1s-clip.kdenlive`;
+ });
+
+ it("should generate a 1a1v project with 20 contingent clips", async () => {
+ const project = new Project(30);
+ const producer = project.addProducer("/home/kuba/Videos/5min.mp4");
+ const video_track = project.addVideoTractor();
+ const audio_track = project.addAudioTractor();
+ for (let i = 0; i <= 20; i++) {
+ let entry = new Entry(
+ producer,
+ `00:00:${i.toString().padStart(2, "0")}.000`,
+ `00:00:${(i + 1).toString().padStart(2, "0")}.000`
+ );
+ video_track.addEntry(entry);
+ audio_track.addEntry(entry);
+ }
+ await $`echo ${await project.toXML()} > 20x1s-clip.kdenlive`;
+ });
+ });
});
diff --git a/src/playlist.ts b/src/playlist.ts
index b861949..12f9c90 100644
--- a/src/playlist.ts
+++ b/src/playlist.ts
@@ -1,23 +1,36 @@
+import { Entry } from "./entry";
import { makeIDGen } from "./util";
const playlistIndexGen = makeIDGen(0);
export abstract class Playlist {
+ public entries: Entry[] = [];
constructor(public index = playlistIndexGen.next().value) {}
abstract toXML(): string;
+
+ addEntry(entry: Entry) {
+ this.entries.push(entry);
+ }
+
+ renderEntries() {
+ return this.entries.map((e) => e.toXML()).join("\n");
+ }
}
export class AudioPlaylist extends Playlist {
toXML() {
- return /* HTML */ `
+ return /* HTML */ `
1
+ ${this.renderEntries()}
`;
}
}
export class VideoPlaylist extends Playlist {
toXML() {
- return /* HTML */ ` `;
+ return /* HTML */ `
+ ${this.renderEntries()}
+ `;
}
}
diff --git a/src/producer.ts b/src/producer.ts
index c7a520c..1209187 100644
--- a/src/producer.ts
+++ b/src/producer.ts
@@ -9,18 +9,22 @@ export abstract class Producer {
this.index = producerIndexGen.next().value;
}
- async getNativeMltXml(fps: number) {
+ async getNativeMltXml(fps: number): Promise {
const xml = (
await $`melt ${
this.path
} -consumer xml ${`frame_rate_num=${fps}`} | htmlq producer`
).stdout;
- return xml.replace("producer0", `producer${this.index}`);
+ return xml.replace("producer0", this.id);
}
- async toXML(fps: number) {
+ async toXML(fps: number): Promise {
return await this.getNativeMltXml(fps);
}
+
+ get id() {
+ return "producer" + this.index;
+ }
}
export class ConcreteProducer extends Producer {
@@ -87,4 +91,8 @@ export class BlackTrack extends Producer {
0
`;
}
+
+ get id() {
+ return "black_track";
+ }
}
diff --git a/src/tractor.ts b/src/tractor.ts
index 59e9f6b..64c50da 100644
--- a/src/tractor.ts
+++ b/src/tractor.ts
@@ -1,3 +1,4 @@
+import { Entry } from "./entry";
import { AudioPlaylist, Playlist, VideoPlaylist } from "./playlist";
import { makeIDGen } from "./util";
@@ -9,6 +10,11 @@ export abstract class Tractor {
public index = trackIndexGen.next().value;
abstract toXML(): string;
+
+ addEntry(entry: Entry): this {
+ this.main_playlist.addEntry(entry);
+ return this;
+ }
}
export class AudioTractor extends Tractor {