|
Interactive demo and a full labeling app (BirdNET detection & annotation). Try them in your browser: |
DAW-like audio player (waveform + spectrogram + transport controls) as a standalone library — built for bioacoustic analysis, annotation, and embedding.
- Highlights
- Labeling app
- Install
- Quickstart
- Player Options
- Usage Examples
- Demos
- Python wrapper
- Development & releases
- Contributing
- License
- Fast, accurate spectrograms — computed in Rust/WebAssembly and rendered on the GPU; presets, colour schemes, auto contrast, PCEN, log frequency
- Synced waveform + spectrogram with smooth zoom, scroll and playhead follow — also for long recordings
- Label annotation — draw, move, resize, undo/redo; snap to call boxes a call from a single click; zoom box and edit loupe for precise edges
- BirdNET suggestions — accept or discard detections in one click
- Xeno-canto integration — import recordings and their annotation sets, compare with reference calls, upload your labels as Annota-JSON sets
- Projects — stored in the browser or in a local folder (File System Access API), Raven export
- Bat recordings — time expansion, heterodyne, frequency division and pitch shift
- Embeddable — npm package (ESM / IIFE) and a Python wrapper for Jupyter, Streamlit and Gradio
The labeling app runs entirely in the browser — no install, no server.
Overview — load a recording, zoom and play![]() |
Labeling — draw and name labels![]() |
Snap to call — one click boxes the call![]() |
Zoom box & loupe — precise box edges![]() |
Display — presets, colour schemes, contrast![]() |
The same UI is available as a desktop app (Tauri, preview) — installers are attached to each release.
npm i signavisNote: signavis expects wavesurfer.js as a peer dependency (v7). Install it with:
npm i wavesurfer.js@^7Or include wavesurfer.js from a CDN in the browser:
<script src="https://unpkg.com/wavesurfer.js@7"></script>Or for Python:
pip install signavisSee PyPI and the python-wrapper/README.md for full Python usage.
import { BirdNETPlayer } from 'signavis'
import 'signavis/style'
const player = new BirdNETPlayer(document.getElementById('player'))
await player.ready| Option | Type | Default | Description |
|---|---|---|---|
viewMode |
string | 'both' |
'both', 'waveform', 'spectrogram' — visible analysis views |
transportStyle |
string | 'default' |
'default', 'hero' — transport button style |
transportOverlay |
boolean | false |
Centered play overlay, no toolbar height |
showFileOpen |
boolean | true |
Show Open button and file input |
showTransport |
boolean | true |
Show transport controls (play/pause/stop) |
showTime |
boolean | true |
Show time display |
showVolume |
boolean | true |
Show volume controls |
showViewToggles |
boolean | true |
Show Follow/Loop/Fit/Reset buttons |
showZoom |
boolean | true |
Show zoom slider |
showFFTControls |
boolean | true |
Show FFT size, max frequency, color scheme |
showDisplayGain |
boolean | true |
Show floor/ceiling sliders, auto contrast |
showStatusbar |
boolean | true |
Show bottom status bar |
showOverview |
boolean | true |
Show overview navigator |
showWaveformTimeline |
boolean | true |
Show bottom timeline in waveform view |
compactToolbar |
string | 'auto' |
'auto', 'on', 'off' — responsive toolbar compaction |
labelTaxonomy |
array | see docs | Custom label presets (name, color, shortcut) |
| ... | ... | ... | ... |
See the API section for usage examples and more details.
import { BirdNETPlayer } from 'signavis'
import 'signavis/style'
const player = new BirdNETPlayer(document.getElementById('player'))
await player.readyawait player.loadUrl('/audio/birdsong.mp3')
player.play()const input = document.querySelector('#audio')
input.addEventListener('change', async () => {
const file = input.files?.[0]
if (!file) return
await player.loadFile(file)
})import { useEffect, useRef } from 'react'
import { BirdNETPlayer } from 'signavis'
import 'signavis/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} />
}import { onMounted, onBeforeUnmount, ref } from 'vue'
import { BirdNETPlayer } from 'signavis'
import 'signavis/style'
const root = ref(null)
let player
onMounted(() => { player = new BirdNETPlayer(root.value) })
onBeforeUnmount(() => player?.destroy())<script>
import { onMount } from 'svelte'
import { BirdNETPlayer } from 'signavis'
import 'signavis/style'
let el
let player
onMount(() => {
player = new BirdNETPlayer(el)
return () => player.destroy()
})
</script>
<div bind:this={el}></div><script src="https://unpkg.com/wavesurfer.js@7"></script>
<script src="https://unpkg.com/signavis/dist/birdnet-player.iife.js"></script>
<link rel="stylesheet" href="https://unpkg.com/signavis/dist/birdnet-player.css" />
<div id="player"></div>
<script>
const player = new BirdNETPlayerModule.BirdNETPlayer(document.getElementById('player'))
</script>from signavis import render_daw_player
import streamlit.components.v1 as components
components.html(render_daw_player(audio_bytes), height=620, scrolling=False)from IPython.display import HTML
from signavis import render_daw_player
HTML(render_daw_player(audio_bytes))- Live Demo (GitHub Pages) — component storybook with configurable stories
- Labeling App — full-featured annotation tool with BirdNET detection, Xeno-canto integration, label management and spectrogram settings (
demo/labeling-app.html) - Google Colab Demo Notebook
- Streamlit:
streamlit run python-wrapper/demo_streamlit.py
- Gradio:
pip install gradio python python-wrapper/demo_gradio.py
The Python wrapper allows embedding the player in Streamlit, Jupyter, and Gradio. See python-wrapper/README.md for full usage, options, and advanced features.
Install:
pip install signavisDocs & PyPI: https://pypi.org/project/signavis
npm ci
npm run dev # Vite dev server, labeling app at /demo/labeling-app.html
npm run typecheck
npm test
npm run build # library + types into dist/ and types/
npm pack --dry-run # inspect what would be publishedReleases are cut with bash scripts/release.sh <version> (e.g. 1.0.1 or 1.1.0-rc.1): it syncs the version across
package.json, pyproject.toml and the Tauri files, commits, tags and pushes. The tag triggers CI, which publishes
to npm (trusted publishing; pre-releases under the next dist-tag) and PyPI and creates a GitHub release with the
notes from CHANGELOG.md and the desktop installers.
The npm package includes the BirdNET model under models/ (~79 MB). Demo GIFs are recorded with
npm run demo:gifs (see tools/demo-gifs) and attached to the demo-media release.
See the repository on GitHub and open issues/PRs: https://github.com/LimitlessGreen/SignaVis
GNU AGPL-3.0





