{"id":49773088,"url":"https://github.com/limitlessgreen/signavis","last_synced_at":"2026-05-11T14:01:25.699Z","repository":{"id":346924062,"uuid":"1161163939","full_name":"LimitlessGreen/SignaVis","owner":"LimitlessGreen","description":"Interactive waveform + spectrogram audio player for analysis, annotation, and embeddable previews (Web, Streamlit, Gradio)","archived":false,"fork":false,"pushed_at":"2026-05-11T07:53:47.000Z","size":80468,"stargazers_count":1,"open_issues_count":4,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-11T13:59:38.939Z","etag":null,"topics":["audio-annotation","audio-player","audio-visualization","bioacoustics","birdnet","ecology","fft","javascript","jupyter","labeling-tool","librosa","mel-spectrogram","pcen","pypi","python","scientific-visualization","spectrogram","waveform","webgl","xeno-canto"],"latest_commit_sha":null,"homepage":"https://limitlessgreen.github.io/SignaVis/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LimitlessGreen.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["LimitlessGreen"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"thanks_dev":null,"custom":null}},"created_at":"2026-02-18T20:02:42.000Z","updated_at":"2026-05-11T06:04:54.000Z","dependencies_parsed_at":null,"dependency_job_id":"45b1a34c-aa7c-4cce-9ac9-28f195c73fd7","html_url":"https://github.com/LimitlessGreen/SignaVis","commit_stats":null,"previous_names":["limitlessgreen/audio-workbench","limitlessgreen/signavis"],"tags_count":43,"template":false,"template_full_name":null,"purl":"pkg:github/LimitlessGreen/SignaVis","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LimitlessGreen%2FSignaVis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LimitlessGreen%2FSignaVis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LimitlessGreen%2FSignaVis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LimitlessGreen%2FSignaVis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LimitlessGreen","download_url":"https://codeload.github.com/LimitlessGreen/SignaVis/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LimitlessGreen%2FSignaVis/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32897941,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-10T13:40:02.631Z","status":"online","status_checked_at":"2026-05-11T02:00:05.975Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio-annotation","audio-player","audio-visualization","bioacoustics","birdnet","ecology","fft","javascript","jupyter","labeling-tool","librosa","mel-spectrogram","pcen","pypi","python","scientific-visualization","spectrogram","waveform","webgl","xeno-canto"],"created_at":"2026-05-11T14:00:47.088Z","updated_at":"2026-05-11T14:01:25.686Z","avatar_url":"https://github.com/LimitlessGreen.png","language":"TypeScript","funding_links":["https://github.com/sponsors/LimitlessGreen"],"categories":[],"sub_categories":[],"readme":"\r\n\u003e ⚠️ **Early development — Unstable**\r\n\u003e\r\n\u003e This project is in active early development. APIs, features, and build artifacts may change or break without notice. You're encouraged to try it and provide feedback, but do not expect a stable release or backward compatibility yet. If you require stability, pin to a specific commit or wait for an official release. Contributions and bug reports are welcome.\r\n\r\n# SignaVis\n\r\n\u003cp align=\"center\"\u003e\r\n  \u003cimg src=\"docs/img/screenshot.png\" alt=\"SignaVis Screenshot\" width=\"900\" /\u003e\r\n\u003c/p\u003e\r\n\r\n\u003cdiv align=\"center\"\u003e\r\n\u003ctable align=\"center\" cellpadding=\"12\" cellspacing=\"0\" style=\"border:1px solid #e1e4e8;background:#f6f8fa;border-radius:6px;\"\u003e\r\n  \u003ctr\u003e\r\n    \u003ctd align=\"center\"\u003e\r\n      \u003ch3\u003e💡 Try it — Demo\u003c/h3\u003e\r\n      \u003cp\u003eInteractive demo and a full labeling app (BirdNET detection \u0026amp; annotation). Try them in your browser:\u003c/p\u003e\r\n      \u003cp\u003e\r\n        \u003ca href=\"https://limitlessgreen.github.io/SignaVis/\"\u003e\u003cimg src=\"https://img.shields.io/badge/Live%20Demo-%E2%96%B6%20Open-brightgreen?style=for-the-badge\" alt=\"Live Demo\"/\u003e\u003c/a\u003e\r\n        \u003ca href=\"https://limitlessgreen.github.io/SignaVis/demo/labeling-app.html?xcid=1\"\u003e\u003cimg src=\"https://img.shields.io/badge/Labeling%20App-%E2%96%B6%20Open-blue?style=for-the-badge\" alt=\"Labeling App\"/\u003e\u003c/a\u003e\r\n      \u003c/p\u003e\r\n      \u003cp\u003e\r\n        \u003ca href=\"https://github.com/LimitlessGreen/SignaVis/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/LimitlessGreen/SignaVis/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"/\u003e\u003c/a\u003e\r\n        \u003ca href=\"https://www.npmjs.com/package/signavis\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/signavis.svg\" alt=\"NPM\"/\u003e\u003c/a\u003e\r\n        \u003ca href=\"https://pypi.org/project/signavis/\"\u003e\u003cimg src=\"https://img.shields.io/pypi/v/signavis.svg\" alt=\"PyPI\"/\u003e\u003c/a\u003e\r\n        \u003ca href=\"https://github.com/LimitlessGreen/SignaVis/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-AGPL--3.0--only-blue.svg\" alt=\"License\"/\u003e\u003c/a\u003e\r\n      \u003c/p\u003e\r\n    \u003c/td\u003e\r\n  \u003c/tr\u003e\r\n\u003c/table\u003e\r\n\u003c/div\u003e\r\n\r\nDAW-like audio player (waveform + spectrogram + transport controls) as a standalone library — built for bioacoustic analysis, annotation, and embedding.\r\n\r\n## Table of contents\r\n\r\n- [signavis](#signavis)\r\n  - [Table of contents](#table-of-contents)\r\n  - [Features](#features)\r\n  - [Install](#install)\r\n  - [Quickstart](#quickstart)\r\n  - [Player Options](#player-options)\r\n  - [Usage Examples](#usage-examples)\r\n    - [ESM (Vite / Vanilla)](#esm-vite--vanilla)\r\n    - [Load from URL](#load-from-url)\r\n    - [File Input](#file-input)\r\n    - [React](#react)\r\n    - [Vue](#vue)\r\n    - [Svelte](#svelte)\r\n    - [CDN / IIFE](#cdn--iife)\r\n    - [Streamlit (Python)](#streamlit-python)\r\n    - [Jupyter Notebook](#jupyter-notebook)\r\n  - [Demos](#demos)\r\n  - [Python wrapper](#python-wrapper)\r\n  - [Contributing](#contributing)\r\n  - [License](#license)\r\n\r\n## ✨ Highlights\r\n\r\n- **Customizable spectrogram rendering** — adjust scale, contrast, gain, color mapping, and more\r\n- **Synced waveform + spectrogram** with zoom and scroll\r\n- **Label annotation** — draw, drag, resize, undo, redo\r\n- **BirdNET suggestions** — accept or discard detections in one click\r\n- **Xeno-canto integration** — search, import, and enrich recordings\r\n- **Bandpass playback** — listen to specific frequency regions\r\n- **Fast frequency zoom** — wheel, slider, and drag controls\r\n\r\n## Install\r\n\r\n```bash\r\nnpm i signavis\r\n```\r\n\r\nNote: signavis expects `wavesurfer.js` as a peer dependency (v7). Install it with:\r\n\r\n```bash\r\nnpm i wavesurfer.js@^7\r\n```\r\n\r\nOr include `wavesurfer.js` from a CDN in the browser:\r\n\r\n```html\r\n\u003cscript src=\"https://unpkg.com/wavesurfer.js@7\"\u003e\u003c/script\u003e\r\n```\r\n\r\nOr for Python:\r\n\r\n```bash\r\npip install signavis\r\n```\r\n\r\nSee [PyPI](https://pypi.org/project/signavis) and the [python-wrapper/README.md](python-wrapper/README.md) for full Python usage.\r\n\r\n## Quickstart\r\n```js\r\nimport { BirdNETPlayer } from 'signavis'\r\nimport 'signavis/style'\r\n\r\nconst player = new BirdNETPlayer(document.getElementById('player'))\r\nawait player.ready\r\n```\r\n```bash\r\nnpm ci\r\nnpm run typecheck\r\nnpm test\r\nnpm run build\r\nnpm run build:css\r\n# Inspect what would be published\r\nnpm pack --dry-run\r\n```\r\n\r\nPublishing via CI:\r\n\r\n- The CI workflow runs on push and for tags; it publishes when a tag matching `v*` is pushed.\r\n- To enable automatic publishing to npm, add an `NPM_TOKEN` secret in GitHub repository settings (Settings → Secrets → Actions → `NPM_TOKEN`).\r\n- Create and push a semver tag to trigger a release:\r\n\r\n```bash\r\ngit tag -a v0.3.1 -m \"release v0.3.1\"\r\ngit push origin v0.3.1\r\n```\r\n\r\n\r\nThe release job will build artifacts, publish to npm and PyPI, and create a GitHub Release including built files.\r\n\r\nHow to create tokens \u0026 add GitHub secrets\r\n\r\n- NPM (automation token): create an automation token on https://www.npmjs.com/settings/\u003cyour-username\u003e/tokens (Create New Token → Automation). Copy the token and add it to your repository secrets as `NPM_TOKEN` (Settings → Secrets → Actions → New repository secret). You can also set it via the GitHub CLI:\r\n\r\n```bash\r\ngh secret set NPM_TOKEN --body 'PASTE_TOKEN_HERE' -R owner/repo\r\n```\r\n\r\n- PyPI: create an API token on https://pypi.org/manage/account/#api-tokens and add it as `PYPI_API_TOKEN` in repository secrets. The CI uses this secret when uploading the Python package.\r\n\r\nPackaging notes:\r\n\r\n- The package includes model files under `models/` (e.g., `models/birdnet-v2.4/`) — verify with `npm pack --dry-run`.\r\n\r\n## Player Options\r\n\r\n| Option | Type | Default | Description |\r\n|---|---|---|---|\r\n| `viewMode` | string | `'both'` | `'both'`, `'waveform'`, `'spectrogram'` — visible analysis views |\r\n| `transportStyle` | string | `'default'` | `'default'`, `'hero'` — transport button style |\r\n| `transportOverlay` | boolean | `false` | Centered play overlay, no toolbar height |\r\n| `showFileOpen` | boolean | `true` | Show Open button and file input |\r\n| `showTransport` | boolean | `true` | Show transport controls (play/pause/stop) |\r\n| `showTime` | boolean | `true` | Show time display |\r\n| `showVolume` | boolean | `true` | Show volume controls |\r\n| `showViewToggles` | boolean | `true` | Show Follow/Loop/Fit/Reset buttons |\r\n| `showZoom` | boolean | `true` | Show zoom slider |\r\n| `showFFTControls` | boolean | `true` | Show FFT size, max frequency, color scheme |\r\n| `showDisplayGain` | boolean | `true` | Show floor/ceiling sliders, auto contrast |\r\n| `showStatusbar` | boolean | `true` | Show bottom status bar |\r\n| `showOverview` | boolean | `true` | Show overview navigator |\r\n| `showWaveformTimeline` | boolean | `true` | Show bottom timeline in waveform view |\r\n| `compactToolbar` | string | `'auto'` | `'auto'`, `'on'`, `'off'` — responsive toolbar compaction |\r\n| `labelTaxonomy` | array | see docs | Custom label presets (name, color, shortcut) |\r\n| ... | ... | ... | ... |\r\n\r\nSee the [API section](#api) for usage examples and more details.\r\n\r\n## Usage Examples\r\n\r\n### ESM (Vite / Vanilla)\r\n```js\r\nimport { BirdNETPlayer } from 'signavis'\r\nimport 'signavis/style'\r\n\r\nconst player = new BirdNETPlayer(document.getElementById('player'))\r\nawait player.ready\r\n```\r\n\r\n### Load from URL\r\n```js\r\nawait player.loadUrl('/audio/birdsong.mp3')\r\nplayer.play()\r\n```\r\n\r\n### File Input\r\n```js\r\nconst input = document.querySelector('#audio')\r\ninput.addEventListener('change', async () =\u003e {\r\n  const file = input.files?.[0]\r\n  if (!file) return\r\n  await player.loadFile(file)\r\n})\r\n```\r\n\r\n### React\r\n```jsx\r\nimport { useEffect, useRef } from 'react'\r\nimport { BirdNETPlayer } from 'signavis'\r\nimport 'signavis/style'\r\n\r\nexport default function Player() {\r\n  const ref = useRef(null)\r\n  useEffect(() =\u003e {\r\n    if (!ref.current) return\r\n    const p = new BirdNETPlayer(ref.current)\r\n    return () =\u003e p.destroy()\r\n  }, [])\r\n  return \u003cdiv ref={ref} /\u003e\r\n}\r\n```\r\n\r\n### Vue\r\n```js\r\nimport { onMounted, onBeforeUnmount, ref } from 'vue'\r\nimport { BirdNETPlayer } from 'signavis'\r\nimport 'signavis/style'\r\n\r\nconst root = ref(null)\r\nlet player\r\n\r\nonMounted(() =\u003e { player = new BirdNETPlayer(root.value) })\r\nonBeforeUnmount(() =\u003e player?.destroy())\r\n```\r\n\r\n### Svelte\r\n```svelte\r\n\u003cscript\u003e\r\n  import { onMount } from 'svelte'\r\n  import { BirdNETPlayer } from 'signavis'\r\n  import 'signavis/style'\r\n\r\n  let el\r\n  let player\r\n  onMount(() =\u003e {\r\n    player = new BirdNETPlayer(el)\r\n    return () =\u003e player.destroy()\r\n  })\r\n\u003c/script\u003e\r\n\r\n\u003cdiv bind:this={el}\u003e\u003c/div\u003e\r\n```\r\n\r\n### CDN / IIFE\r\n```html\r\n\u003cscript src=\"https://unpkg.com/wavesurfer.js@7\"\u003e\u003c/script\u003e\r\n\u003cscript src=\"https://unpkg.com/signavis/dist/birdnet-player.iife.js\"\u003e\u003c/script\u003e\r\n\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/signavis/dist/birdnet-player.css\" /\u003e\r\n\u003cdiv id=\"player\"\u003e\u003c/div\u003e\r\n\u003cscript\u003e\r\n  const player = new BirdNETPlayerModule.BirdNETPlayer(document.getElementById('player'))\r\n\u003c/script\u003e\r\n```\r\n\r\n### Streamlit (Python)\r\n```python\r\nfrom signavis import render_daw_player\r\nimport streamlit.components.v1 as components\r\n\r\ncomponents.html(render_daw_player(audio_bytes), height=620, scrolling=False)\r\n```\r\n\r\n### Jupyter Notebook\r\n```python\r\nfrom IPython.display import HTML\r\nfrom signavis import render_daw_player\r\n\r\nHTML(render_daw_player(audio_bytes))\r\n```\r\n\r\n## Demos\r\n\r\n- **[Live Demo (GitHub Pages)](https://limitlessgreen.github.io/SignaVis/)** — component storybook with configurable stories\r\n- **[Labeling App](https://limitlessgreen.github.io/SignaVis/demo/labeling-app.html?xcid=1)** — full-featured annotation tool with BirdNET detection, Xeno-canto integration, label management and spectrogram settings (`demo/labeling-app.html`)\r\n- **[Google Colab Demo Notebook](https://colab.research.google.com/github/LimitlessGreen/SignaVis/blob/main/python-wrapper/demo_colab.ipynb) [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LimitlessGreen/SignaVis/blob/main/python-wrapper/demo_colab.ipynb)**\r\n- **Streamlit:**\r\n  ```bash\r\n  streamlit run python-wrapper/demo_streamlit.py\r\n  ```\r\n- **Gradio:**\r\n  ```bash\r\n  pip install gradio\r\n  python python-wrapper/demo_gradio.py\r\n  ```\r\n\r\n## Python wrapper\r\n\r\nThe Python wrapper allows embedding the player in Streamlit, Jupyter, and Gradio. See [python-wrapper/README.md](python-wrapper/README.md) for full usage, options, and advanced features.\r\n\r\nInstall:\r\n```bash\r\npip install signavis\r\n```\r\n\r\nDocs \u0026 PyPI: https://pypi.org/project/signavis\r\n\r\n## Contributing\r\n\r\nSee the repository on GitHub and open issues/PRs: https://github.com/LimitlessGreen/SignaVis\r\n\r\n## License\r\n\r\nGNU AGPL-3.0\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flimitlessgreen%2Fsignavis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flimitlessgreen%2Fsignavis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flimitlessgreen%2Fsignavis/lists"}