npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

audio-workbench

v0.1.0

Published

DAW-like audio player with waveform + spectrogram for analysis

Readme

audio-workbench

DAW-ähnlicher Audio-Player (Waveform + Spektrogramm + Transport Controls) als eigenständige Library.

Install

npm i audio-workbench

WaveSurfer.js wird automatisch per CDN geladen — kein extra Install nötig.

Paketinhalt

  • dist/birdnet-player.esm.js (ESM, Web Worker als separate Datei)
  • dist/birdnet-player.iife.js (CDN/IIFE, Worker inlined)
  • dist/birdnet-player.css (Styles)
  • types/index.d.ts (TypeScript)
  • src/dsp.js (DSP-Kernfunktionen: FFT, Mel-Filterbank, Spektrogramm)

Quickstart

import { BirdNETPlayer } from 'audio-workbench'
import 'audio-workbench/style'

const player = new BirdNETPlayer(document.getElementById('player'))
await player.ready

10 Usage Examples

1) ESM (Vite/Vanilla)

import { BirdNETPlayer } from 'audio-workbench'
import 'audio-workbench/style'

const player = new BirdNETPlayer(document.getElementById('player'))
await player.ready

2) ESM + URL laden

await player.loadUrl('/audio/birdsong.mp3')
player.play()

3) ESM + File Input

const input = document.querySelector('#audio')
input.addEventListener('change', async () => {
  const file = input.files?.[0]
  if (!file) return
  await player.loadFile(file)
})

4) React

import { useEffect, useRef } from 'react'
import { BirdNETPlayer } from 'audio-workbench'
import 'audio-workbench/style'

export default function Player() {
  const ref = useRef(null)
  useEffect(() => {
    if (!ref.current) return
    const p = new BirdNETPlayer(ref.current)
    return () => p.destroy()
  }, [])
  return <div ref={ref} />
}

5) Vue

import { onMounted, onBeforeUnmount, ref } from 'vue'
import { BirdNETPlayer } from 'audio-workbench'
import 'audio-workbench/style'

const root = ref(null)
let player

onMounted(() => { player = new BirdNETPlayer(root.value) })
onBeforeUnmount(() => player?.destroy())

6) Svelte

<script>
  import { onMount } from 'svelte'
  import { BirdNETPlayer } from 'audio-workbench'
  import 'audio-workbench/style'

  let el
  let player
  onMount(() => {
    player = new BirdNETPlayer(el)
    return () => player.destroy()
  })
</script>

<div bind:this={el}></div>

7) CDN / IIFE (Vanilla)

<script src="https://unpkg.com/wavesurfer.js@7"></script>
<script src="https://unpkg.com/audio-workbench/dist/birdnet-player.iife.js"></script>
<link rel="stylesheet" href="https://unpkg.com/audio-workbench/dist/birdnet-player.css" />
<div id="player"></div>
<script>
  const player = new BirdNETPlayerModule.BirdNETPlayer(document.getElementById('player'))
</script>

8) Streamlit (Python)

from audio_workbench import render_daw_player
import streamlit as st
import streamlit.components.v1 as components

components.html(render_daw_player(audio_bytes), height=620, scrolling=False)

9) Jupyter Notebook

from IPython.display import HTML
from audio_workbench import render_daw_player

HTML(render_daw_player(audio_bytes))

10) Electron / Tauri WebView

import { BirdNETPlayer } from 'audio-workbench'
import 'audio-workbench/style'

const p = new BirdNETPlayer(document.getElementById('player'))
await p.loadUrl('file:///absolute/path/to/audio.wav')

API

new BirdNETPlayer(container: HTMLElement, options?)
player.ready: Promise<BirdNETPlayer>
player.loadUrl(url: string): Promise<void>
player.loadFile(file: File): Promise<void>
player.currentTime: number
player.duration: number
player.play(): void
player.pause(): void
player.stop(): void
player.togglePlayPause(): void
player.playBandpassedSegment(startSec: number, endSec: number, freqMinHz: number, freqMaxHz: number): void
player.renameLabel(id: string, name: string): boolean
player.getLabelTaxonomy(): Array<{ name: string; color?: string; shortcut?: string }>
player.setLabelTaxonomy(items: Array<{ name: string; color?: string; shortcut?: string }>): void
player.applyTaxonomyToLabel(id: string, shortcutOrIndex: string | number): boolean
player.getPlaybackViewportConfig(): object
player.setPlaybackViewportConfig(config: object): object
player.destroy(): void

Spektrogramm-Modi

Der Player bietet zwei Spektrogramm-Modi, wählbar über das Mode-Dropdown:

| Modus | Frequenzachse | Normalisierung | Farbpalette | |-------|---------------|----------------|-------------| | Perch (Standard) | Mel-Skala (logarithmisch) | PCEN (Per-Channel Energy Normalization) | Grayscale / frei wählbar | | Classic (XC-Stil) | Linear (direkte FFT-Bins) | Power → dB-Skala | Xeno-Canto Warm-Body / frei wählbar |

Der Classic-Modus erzeugt Spektrogramme die optisch den Darstellungen auf xeno-canto.org entsprechen.

Debug Performance Overlay

Aktiviere das Laufzeit-Overlay mit:

  • URL: ?perf=1 (z. B. demo/index.html?perf=1)
  • oder Option: new BirdNETPlayer(el, { enablePerfOverlay: true })

Das Overlay zeigt u. a. FPS, Long-Frames, Eventraten und Transport-State-Transitions.

Label Editing

  • Doppelklick auf ein Label öffnet einen Inline-Editor.
  • Vorschläge basieren auf bereits verwendeten Label-Namen (wiederverwendbare Label-Library).
  • Farbe ist im Inline-Editor direkt per Color-Picker editierbar.
  • Enter speichert, Esc verwirft.
  • Taxonomy-Presets mit 1..9 sind unterstützt: erst Label fokussieren (anklicken), dann Shortcut drücken.

Follow Modes

  • Follow-Button schaltet zyklisch: FreeFollowSmooth.
  • Smooth fährt kontinuierlich mit, statt in Sprüngen zu zentrieren.
  • Follow/Smooth Verhalten ist konfigurierbar (Constructor + Runtime):
const player = new BirdNETPlayer(el, {
  followCatchupDurationMs: 280,
  followCatchupSeekDurationMs: 420,
  smoothLerp: 0.16,
  smoothSeekLerp: 0.07
})

player.setPlaybackViewportConfig({ smoothSeekFocusMs: 1700 })

Compact Preview Modes

Für kleine Embeds kannst du den DAW-Look auf ein Vorschaufenster reduzieren:

const player = new BirdNETPlayer(el, {
  viewMode: 'spectrogram', // 'both' | 'waveform' | 'spectrogram'
  transportStyle: 'hero',  // großer Play-Button
  transportOverlay: true,  // zentriert, ohne Toolbar-Höhe
  showWaveformTimeline: false,
  showOverview: false,
  showFileOpen: false,
  showStatusbar: false,
  showTime: false,
  showVolume: false
})

Tests

npm test          # 25 Tests (DSP, Spectrogram Utils, Transport State)

Build

npm run build     # Vite build (ESM + IIFE + CSS + Sourcemaps + TypeScript)
npm run dev       # Vite dev server mit HMR (öffnet http://localhost:5173)

Der Build nutzt Vite im Library-Mode:

  • ESM-Build: Worker als separate Datei
  • IIFE-Build: Worker inlined (kein zusätzlicher Netzwerk-Request)
  • CSS wird automatisch extrahiert
  • Sourcemaps für beide Formate
  • TypeScript Declarations aus JSDoc generiert

Demos

| Demo | Modus | Starten | |------|-------|---------| | http://localhost:5173/ | Dev (ESM, HMR) | npm run dev | | demo/index.html | Produktion (IIFE aus dist/) | Datei direkt öffnen | | demo/storybook.html | Interactive Stories | npm run dev |

Architektur

src/
├── BirdNETPlayer.js    Public API Facade
├── PlayerState.js      Zentraler State & Orchestrierung
├── dsp.js              DSP-Kernfunktionen (FFT, Mel, Filterbank)
├── spectrogram.js      Pipeline: Compute → Grayscale → GPU-Colorize → Render
├── spectrogram.worker.js  Web Worker (importiert dsp.js)
├── template.js         HTML-Template (data-aw Attribute, multi-instance-fähig)
├── player.css          Styles (CSS Custom Properties, scoped auf .daw-shell)
├── annotations.js      Amplitude + Spektrogramm Labels
├── waveform.js         Waveform-Rendering
├── gestures.js         Touch/Mouse Interaction
├── utils.js            Hilfsfunktionen
└── constants.js        Konfiguration & Defaults

Release Runbook

Git hooks einmalig installieren:

npm run hooks:install
  1. Einmalig npm Trusted Publishing einrichten:
  • npm Package audio-workbench -> Settings -> Trusted publisher
  • GitHub owner/org: limitlessgreen
  • Repository: Audio-Workbench
  • Workflow file: .github/workflows/ci.yml
  1. Version nur in VERSION erhöhen (Single Source of Truth):
echo "X.Y.Z" > VERSION
npm run version:sync
npm run version:check
  1. Build + Packaging lokal prüfen:
npm test
npm pack
cd python-wrapper
python -m pip install --upgrade build twine
python -m build
python -m twine check dist/*
  1. Changelog aktualisieren (CHANGELOG.md).

  2. Commit + Tag erstellen (automatisiert):

bash ./scripts/release.sh X.Y.Z
  1. Veröffentlichung läuft über GitHub Actions bei Tag v*:
  • npm: publish-npm
  • PyPI: publish-pypi
  1. Optional manueller Fallback:
npm publish --access public
cd python-wrapper
python -m twine upload dist/*

License

GNU AGPL-3.0