Skip to content
laker-93Public

About

typescript port of laker93/pyserato

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

pyserato-ts

TypeScript port of pyserato (https://github.com/laker-93/pyserato/).

File formats

Serato's cue and beat grid payloads are the same bytes in every container; only where they are stored differs. tserato reads and writes them in:

Container Where the tag lives Status
MP3 ID3v2 GEOB frame supported
FLAC Vorbis comment, base64 envelope supported
WAV, AIFF ID3 chunk inside RIFF/IFF #17
M4A ----:com.serato.dj freeform atom #17

The container is decided by the file's own bytes, not its extension. Anything in that second group throws UnsupportedContainerError rather than reporting that the track has no cues -- a caller has to be able to tell those apart.

Write Crates

// example/testEncoder.ts
import { Builder, Crate, Track, V2Encoder, HotCue, HotCueType } from "tserato"

async function main() {
  // create encoder + builder
  const encoder = new V2Encoder();
  const builder = new Builder(encoder);

  // create crate
  const crate = new Crate("foojs");

  // add track
  const track = Track.fromPath("/Users/lukepurnell/test music/Russian Circles - Gnosis/Russian Circles - Gnosis - 06 Betrayal.mp3");
  crate.addTrack(track);

  // add cues
  track.addHotCue(
    new HotCue({
      name: "mycue1",
      type: HotCueType.CUE,
      start: 500,
      index: 1,
    })
  );
  track.addHotCue(
    new HotCue({
      name: "mycue2",
      type: HotCueType.CUE,
      start: 1000,
      index: 2,
    })
  );

  track.addHotCue(
    new HotCue({
      name: "myloop1",
      type: HotCueType.LOOP,
      start: 2000,
      end: 3000,
      index: 3,
    })
  );

  // save crate (writes .crate file + tags)
  await builder.save(crate, undefined, true);

  console.log("Crate saved successfully!");
}

main().catch(console.error);

Write Cues

import { Builder, Crate, Track, V2Encoder, HotCue, HotCueType } from "tserato"

async function main() {
  // create encoder + builder
  const encoder = new V2Encoder();
  const builder = new Builder(encoder);

  // create crate
  const crate = new Crate("foojs");

  // add track
  const track = Track.fromPath("/Users/lukepurnell/test music/Russian Circles - Gnosis/Russian Circles - Gnosis - 06 Betrayal.mp3");
  crate.addTrack(track);

  // add cues
  track.addHotCue(
    new HotCue({
      name: "mycue1",
      type: HotCueType.CUE,
      start: 500,
      index: 1,
    })
  );
  track.addHotCue(
    new HotCue({
      name: "mycue2",
      type: HotCueType.CUE,
      start: 1000,
      index: 2,
    })
  );

  track.addHotCue(
    new HotCue({
      name: "myloop1",
      type: HotCueType.LOOP,
      start: 2000,
      end: 3000,
      index: 3,
    })
  );

  // save crate (writes .crate file + tags)
  await builder.save(crate, undefined, true);

  console.log("Crate saved successfully!");
}

main().catch(console.error);

About

typescript port of laker93/pyserato

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages