diff --git a/audio_props.mjs b/audio_props.mjs
deleted file mode 100644
index 3ddfbc9..0000000
--- a/audio_props.mjs
+++ /dev/null
@@ -1,13 +0,0 @@
-const audio_props = {
-  "stream.handler_name.markup": "SoundHandler",
-  "stream.type": "audio",
-  "codec.sample_fmt": (metadata) => {
-    const type = metadata.data.Format_Settings_Sign == "Signed" ? "s" : "u";
-    const bit_depth = metadata.data.BitDepth;
-    return `${type}${bit_depth}`;
-  },
-  "codec.channels": (metadata) => metadata.data.Channels,
-  "codec.sample_rate": (metadata) => metadata.data.SamplingRate,
-};
-
-export default audio_props;
diff --git a/kdenlive.mjs b/kdenlive.mjs
index 3309abc..b0e708a 100755
--- a/kdenlive.mjs
+++ b/kdenlive.mjs
@@ -3,21 +3,26 @@
 import { formatDuration } from "./util.mjs";
 import Producer from "./producer.mjs";
 
-export default async function kdenliveProject(
-  source_files,
-  project_settings, // const project_settings = { fps: 30 };
-  clips
-) {
-  const producers = await Promise.all(source_files.map(Producer.fromFile));
-  return `
+export default class Project {
+  constructor(fps) {
+    this.producers = [];
+    this.clips = [];
+    this.fps = fps;
+  }
+
+  addProducer(file) {
+    this.producers.push(new Producer(file));
+    return this;
+  }
+
+  async toXML() {
+    return `
 
  
 ${(
-  await Promise.all(
-    producers.map((producer) => producer.toXML(project_settings))
-  )
+  await Promise.all(this.producers.map((producer) => producer.toXML(this.fps)))
 ).join("\n")}
  
   2
@@ -29,15 +34,12 @@ ${(
 ]
 
   21.08.1
-  1.02
+g  1.02
   
   
   1
-${producers
-  .map(
-    (producer, index) =>
-      ``
-  )
+${this.producers
+  .map((producer) => ``)
   .join("\n")}  
  
  
@@ -51,6 +53,8 @@ ${producers
  
  
   1
+
+
  
  
   1
@@ -93,12 +97,12 @@ ${producers
  
 
 `;
+  }
 }
 
-const project_content = await kdenliveProject(
-  ["/home/kuba/Videos/5min.mp4", "/home/kuba/Videos/5min.wav"],
-  {
-    fps: 30,
-  }
-);
-await $`echo ${project_content} > project-generated.kdenlive`;
+const project = new Project(30);
+
+project.addProducer("/home/kuba/Videos/5min.mp4");
+project.addProducer("/home/kuba/Videos/5min.wav");
+
+await $`echo ${await project.toXML()} > project-generated.kdenlive`;
diff --git a/producer.mjs b/producer.mjs
index f4368d2..20f0b8d 100644
--- a/producer.mjs
+++ b/producer.mjs
@@ -6,107 +6,23 @@ import {
   formatDuration,
 } from "./util.mjs";
 import { makeIDGen } from "./util.mjs";
-import video_props from "./video_props.mjs";
-import audio_props from "./audio_props.mjs";
 
 const makeId = makeIDGen(1);
 const producerIndexGen = makeIDGen(0);
 
 export default class Producer {
-  constructor(metadata) {
-    this.metadata = metadata;
+  constructor(path) {
+    this.path = path;
     this.index = producerIndexGen.next().value;
   }
 
-  static prop_types = {
-    length: (metadata, project_settings) => {
-      const duration = getStream(metadata.track, "General").Duration;
-      return `${duration * project_settings.fps}`;
-    },
-    eof: "pause",
-    resource: (metadata) => metadata["@ref"],
-    audio_index: (metadata) => getStreamIndex(metadata.track, "Audio"),
-    video_index: (metadata) => getStreamIndex(metadata.track, "Video"),
-    mute_on_pause: "0",
-    mlt_service: "avformat-novalidate",
-    seekable: "1",
-    aspect_ratio: "1",
-    "kdenlive:clipname": "",
-    "kdenlive:folderid": "-1",
-    "kdenlive:audio_max0": "208",
-    "kdenlive:id": () => makeId.next().value,
-    "kdenlive:file_size": async (metadata) =>
-      (
-        await $`du --bytes ${metadata["@ref"]} | awk '{print $1}'`
-      ).stdout.replace("\n", ""),
-    "kdenlive:file_hash": async (metadata) =>
-      (
-        await $`head -c 1000000 ${metadata["@ref"]} && tail -c 1000000 ${metadata["@ref"]}`.pipe(
-          $`md5sum | awk '{print $1}'`
-        )
-      ).stdout.replace("\n", ""),
-    "meta.media.nb_streams": (metadata) => metadata.track.length - 1,
-    $$$video: async (metadata, project_settings) => {
-      const video_index = indexOf(metadata.track, (e) => e["@type"] == "Video");
-      if (video_index == -1) {
-        return null;
-      }
-      return {
-        $replace: await renderAllProps(
-          video_props,
-          {
-            index: video_index,
-            path: metadata["@ref"],
-            data: metadata.track[video_index],
-          },
-          project_settings,
-          `meta.media.${getStreamIndex(metadata.track, "Video")}.`
-        ),
-      };
-    },
-    $$$audio: async (metadata, project_settings) => {
-      const audio_index = indexOf(metadata.track, (e) => e["@type"] == "Audio");
-      if (audio_index == -1) {
-        return null;
-      }
-      return {
-        $replace: await renderAllProps(
-          audio_props,
-          {
-            index: audio_index,
-            path: metadata["@ref"],
-            data: metadata.track[audio_index],
-          },
-          project_settings,
-          `meta.media.${getStreamIndex(metadata.track, "Audio")}.`
-        ),
-      };
-    },
-  };
+  async toXML(fps) {
+    const xml = (
+      await $`melt ${
+        this.path
+      } -consumer xml ${`frame_rate_num=${fps}`} | htmlq producer`
+    ).stdout;
 
-  static async fromFile(file_path) {
-    const metadata = JSON.parse(
-      (await $`mediainfo --Output=JSON ${file_path}`).stdout
-    ).media;
-    return new Producer(metadata);
-  }
-
-  getDuration() {
-    return formatDuration(
-      parseFloat(getStream(this.metadata.track, "General").Duration)
-    );
-  }
-
-  async toXML(project_settings) {
-    return `
-        ${await renderAllProps(
-          Producer.prop_types,
-          this.metadata,
-          project_settings
-        )}
-      
-    `;
+    return xml.replace("producer0", `producer${this.index}`);
   }
 }
diff --git a/util.mjs b/util.mjs
index ea3058d..edb9395 100644
--- a/util.mjs
+++ b/util.mjs
@@ -20,7 +20,6 @@ export async function renderProperty(
   } else {
     value = await fn(metadata, project_settings);
   }
-  console.log(name, value);
   if (value === null) {
     return "";
   } else if (value && value.$replace) {
diff --git a/video_props.mjs b/video_props.mjs
deleted file mode 100644
index 50f2a1c..0000000
--- a/video_props.mjs
+++ /dev/null
@@ -1,12 +0,0 @@
-const video_props = {
-  "stream.type": "video",
-  "stream.frame_rate": (metadata) => metadata.data.FrameRate,
-  "stream.sample_aspect_ratio": "1",
-  "codec.width": (metadata) => metadata.data.Width,
-  "codec.height": (metadata) => metadata.data.Height,
-  "codec.rotate": "0",
-  "codec.frame_rate": (metadata) => metadata.data.FrameRate,
-  "stream.handler_name.markup": "VideoHandle",
-};
-
-export default video_props
\ No newline at end of file