playlist-data-engine 1.5.8 → 1.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -40781,76 +40781,91 @@ class I0 {
40781
40781
  /**
40782
40782
  * Analyzes audio to extract genre, mood, and vibe data.
40783
40783
  */
40784
+ /**
40785
+ * Analyze a track. Accepts either:
40786
+ * - a `string` URL: the engine fetches + decodes + downsamples via Web
40787
+ * Audio (main-thread path). Backward-compatible with all existing callers.
40788
+ * - an `{ audioSignal, sampleRate? }` object: caller has already fetched,
40789
+ * decoded, AND downsampled to mono PCM. Used when running inside a Web
40790
+ * Worker (no Web Audio available there). `sampleRate` defaults to 16000
40791
+ * (essentia.js's required rate); the engine skips fetch + decode +
40792
+ * downsample and runs only the slice + ML inference on the provided signal.
40793
+ */
40784
40794
  async analyze(e) {
40785
40795
  try {
40786
40796
  await this.initializeEssentia();
40787
- const i = await (await fetch(e)).arrayBuffer(), n = new (window.AudioContext || window.webkitAudioContext)(), a = await n.decodeAudioData(i), r = await this.extractor.downsampleAudioBuffer(
40788
- a,
40789
- n.sampleRate
40790
- ), o = this.sliceAudioSignal(r, 16e3), c = Math.max(0, Math.floor((o.length - 512) / 256) + 1), l = [], u = {
40797
+ let t;
40798
+ if (typeof e == "string") {
40799
+ const l = await (await fetch(e)).arrayBuffer(), u = typeof self < "u" ? self : typeof globalThis < "u" ? globalThis : {}, d = u.AudioContext || u.webkitAudioContext, h = u.OfflineAudioContext || u.webkitOfflineAudioContext, m = d ? new d() : h ? new h(1, 44100, 44100) : (() => {
40800
+ throw new Error("No Web Audio API available in this context");
40801
+ })(), f = await m.decodeAudioData(l);
40802
+ t = await this.extractor.downsampleAudioBuffer(f, m.sampleRate);
40803
+ } else
40804
+ t = e.audioSignal;
40805
+ const i = this.sliceAudioSignal(t, 16e3), n = Math.max(0, Math.floor((i.length - 512) / 256) + 1), a = [], r = {
40791
40806
  genres: [],
40792
40807
  moods: [],
40793
40808
  mood_tags: [],
40794
40809
  vibe_metrics: {}
40795
40810
  };
40796
40811
  if (this.options.models?.genre) {
40797
- const d = this.options.models.genre, h = Ai(d) ? d.classifier : d.modelUrl;
40798
- let m;
40799
- Ai(d) && d.classifierType ? m = d.classifierType : fr(d) && d.genreType ? m = d.genreType : m = dv(h);
40800
- const f = hv(m);
40801
- u.genres = await this.runModelPrediction(
40802
- d,
40812
+ const o = this.options.models.genre, c = Ai(o) ? o.classifier : o.modelUrl;
40813
+ let l;
40814
+ Ai(o) && o.classifierType ? l = o.classifierType : fr(o) && o.genreType ? l = o.genreType : l = dv(c);
40815
+ const u = hv(l);
40816
+ r.genres = await this.runModelPrediction(
40803
40817
  o,
40804
- f
40805
- ), u.primary_genre = u.genres.length > 0 ? u.genres[0].name : "Unknown", l.push(Ot(d));
40818
+ i,
40819
+ u
40820
+ ), r.primary_genre = r.genres.length > 0 ? r.genres[0].name : "Unknown", a.push(Ot(o));
40806
40821
  }
40807
40822
  if (this.options.models?.mood) {
40808
- const d = this.options.models.mood, h = fr(d) ? rv : ov;
40809
- u.moods = await this.runModelPrediction(
40810
- d,
40823
+ const o = this.options.models.mood, c = fr(o) ? rv : ov;
40824
+ r.moods = await this.runModelPrediction(
40811
40825
  o,
40812
- h
40813
- ), u.mood_tags = u.moods.slice(0, 3).map((m) => m.name), l.push(Ot(d));
40826
+ i,
40827
+ c
40828
+ ), r.mood_tags = r.moods.slice(0, 3).map((l) => l.name), a.push(Ot(o));
40814
40829
  }
40815
40830
  if (this.options.models?.danceability) {
40816
- const d = this.options.models.danceability, m = (await this.runModelPrediction(
40817
- d,
40831
+ const o = this.options.models.danceability, l = (await this.runModelPrediction(
40818
40832
  o,
40833
+ i,
40819
40834
  cv
40820
- )).find((f) => f.name === "danceable");
40821
- u.vibe_metrics.danceability = m?.confidence ?? 0, l.push(Ot(d));
40835
+ )).find((u) => u.name === "danceable");
40836
+ r.vibe_metrics.danceability = l?.confidence ?? 0, a.push(Ot(o));
40822
40837
  }
40823
40838
  if (this.options.models?.voice) {
40824
- const d = this.options.models.voice, m = (await this.runModelPrediction(
40825
- d,
40839
+ const o = this.options.models.voice, l = (await this.runModelPrediction(
40826
40840
  o,
40841
+ i,
40827
40842
  lv
40828
- )).find((f) => f.name === "instrumental");
40829
- u.vibe_metrics.instrumental_probability = m?.confidence ?? 0, l.push(Ot(d));
40843
+ )).find((u) => u.name === "instrumental");
40844
+ r.vibe_metrics.instrumental_probability = l?.confidence ?? 0, a.push(Ot(o));
40830
40845
  }
40831
40846
  if (this.options.models?.acoustic) {
40832
- const d = this.options.models.acoustic, m = (await this.runModelPrediction(
40833
- d,
40847
+ const o = this.options.models.acoustic, l = (await this.runModelPrediction(
40834
40848
  o,
40849
+ i,
40835
40850
  uv
40836
- )).find((f) => f.name === "electronic");
40837
- u.vibe_metrics.electronic_probability = m?.confidence ?? 0, l.push(Ot(d));
40851
+ )).find((u) => u.name === "electronic");
40852
+ r.vibe_metrics.electronic_probability = l?.confidence ?? 0, a.push(Ot(o));
40838
40853
  }
40839
- if (u.moods) {
40840
- const d = u.moods.find((m) => m.name === "energetic" || m.name === "upbeat" || m.name === "epic"), h = u.moods.find((m) => m.name === "happy" || m.name === "positive" || m.name === "uplifting");
40841
- d && (u.vibe_metrics.energy = d.confidence), h && (u.vibe_metrics.valence = h.confidence);
40854
+ if (r.moods) {
40855
+ const o = r.moods.find((l) => l.name === "energetic" || l.name === "upbeat" || l.name === "epic"), c = r.moods.find((l) => l.name === "happy" || l.name === "positive" || l.name === "uplifting");
40856
+ o && (r.vibe_metrics.energy = o.confidence), c && (r.vibe_metrics.valence = c.confidence);
40842
40857
  }
40843
40858
  return {
40844
- genres: u.genres || [],
40845
- moods: u.moods || [],
40846
- primary_genre: u.primary_genre || "Unknown",
40847
- mood_tags: u.mood_tags || [],
40848
- vibe_metrics: u.vibe_metrics,
40859
+ genres: r.genres || [],
40860
+ moods: r.moods || [],
40861
+ primary_genre: r.primary_genre || "Unknown",
40862
+ mood_tags: r.mood_tags || [],
40863
+ vibe_metrics: r.vibe_metrics,
40849
40864
  analysis_metadata: {
40850
- models_used: l,
40851
- model_used: l.length > 0 ? l[0] : void 0,
40852
- frames_analyzed: c,
40853
- duration_analyzed: o.length / 16e3,
40865
+ models_used: a,
40866
+ model_used: a.length > 0 ? a[0] : void 0,
40867
+ frames_analyzed: n,
40868
+ duration_analyzed: i.length / 16e3,
40854
40869
  analyzed_at: (/* @__PURE__ */ new Date()).toISOString()
40855
40870
  }
40856
40871
  };
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/jasondesante/playlist-data-engine.git"
8
8
  },
9
- "version": "1.5.8",
9
+ "version": "1.5.9",
10
10
  "type": "module",
11
11
  "main": "./dist/playlist-data-engine.js",
12
12
  "module": "./dist/playlist-data-engine.mjs",