cjm-fasthtml-web-audio
Install
pip install cjm_fasthtml_web_audio
Project Structure
nbs/
├── components.ipynb # FastHTML component helpers for the Web Audio API manager
├── js.ipynb # JavaScript generation for the Web Audio API manager
└── models.ipynb # Configuration and HTML ID types for the Web Audio API manager
Total: 3 notebooks
Module Dependencies
graph LR
components[components<br/>components]
js[js<br/>js]
models[models<br/>models]
components --> js
components --> models
js --> models
3 cross-module dependencies detected
CLI Reference
No CLI commands found in this project.
Module Overview
Detailed documentation for each module in the project:
components (components.ipynb)
FastHTML component helpers for the Web Audio API manager
Import
from cjm_fasthtml_web_audio.components import (
DEFAULT_STATIC_MOUNT_PATH,
render_audio_urls_input,
render_web_audio_script,
mount_web_audio_static,
render_initial_speed_sync,
render_speed_selector
)
Functions
def render_audio_urls_input(
config: WebAudioConfig, # Instance configuration
audio_urls: List[str], # Audio file URLs to load
oob: bool = False, # Whether to render as OOB swap
) -> Any: # Hidden input element with JSON-encoded URLs
"Render a hidden input storing audio URLs as JSON."
def render_web_audio_script(
config: WebAudioConfig, # Instance configuration
focus_input_id: str, # Hidden input ID for focused index
card_stack_id: str, # Card stack container ID
nav_down_btn_id: str = "", # Nav down button ID (for auto-navigate)
) -> Any: # Script element with complete Web Audio JS
"Render the complete Web Audio API script for a configured instance."
def mount_web_audio_static(
app, # FastHTML/Starlette app
mount_path: str = DEFAULT_STATIC_MOUNT_PATH, # URL prefix to mount static dir at
) -> str: # URL of the SoundTouch worklet processor
"""
Mount the library's vendored static assets (SoundTouch worklet, license).
Inserts the Mount at `app.routes[0]` so it's matched BEFORE any catch-all
routes FastHTML may have registered. Returns the URL where the SoundTouch
worklet processor is served; when `mount_path` is the default the URL equals
`DEFAULT_WORKLET_URL` — so `WebAudioConfig(enable_speed=True)` with no explicit
`worklet_url` just works.
"""
def render_initial_speed_sync(
config: WebAudioConfig, # Instance configuration
speed: float, # Persisted playback speed (e.g. from step state)
) -> Any: # Script element (empty if speed is default or speed is disabled)
"""
Render a <Script> that syncs the JS state's playbackSpeed to `speed` after insertion.
Polls briefly (~1 second, 20ms intervals) for `window.set{Ns}Speed` so the helper
works regardless of whether the web-audio script or the toolbar script runs first.
Returns an empty Script when `speed == 1.0` (state_init already defaults to 1.0)
or when `config.enable_speed` is False.
"""
def render_speed_selector(
config: WebAudioConfig, # Instance configuration (must have enable_speed=True for sync to fire)
current_speed: float = 1.0, # Current / persisted playback speed
change_url: str = "", # URL to POST speed changes to (empty → no server persist)
label: Optional[str] = "Speed:", # Leading label text (None/"" → omit label span)
) -> Any: # Div(Span?, Select, sync Script)
"""
Render the shared playback speed selector.
Emits a DaisyUI `<select>` whose `onchange` calls `window.set{Ns}Speed(...)` for
immediate JS state update. When `change_url` is provided, also POSTs to that URL
via HTMX for server-side persistence (consumers typically return `Script(generate_speed_change_js(...))`).
Also emits `render_initial_speed_sync(config, current_speed)` so the JS state
reconciles to `current_speed` on initial render and OOB swaps — the `<option selected>`
attribute only restores the dropdown visually.
"""
Variables
DEFAULT_STATIC_MOUNT_PATH = '/static/cjm-web-audio'
js (js.ipynb)
JavaScript generation for the Web Audio API manager
Import
from cjm_fasthtml_web_audio.js import (
DEFAULT_WORKLET_URL,
PLAYBACK_SPEEDS,
generate_state_init,
generate_init_audio,
generate_stop_audio,
generate_play_segment,
generate_optional_features,
generate_speed_change_js,
generate_focus_change,
generate_htmx_settle_handler,
generate_web_audio_js
)
Functions
def generate_state_init(
config: WebAudioConfig, # Instance configuration
) -> str: # JS code that initializes the state object
"Generate JS code to initialize the namespaced state object."
def generate_init_audio(
config: WebAudioConfig, # Instance configuration
) -> str: # JS init function
"""
Generate JS function that loads and decodes audio files in parallel.
When `config.enable_speed=True`, the SoundTouch worklet processor is registered
on the AudioContext before decoding. On registration failure, `workletRegistered`
remains false and the play path falls back to naive (pitch-shifting) playbackRate.
"""
def generate_stop_audio(
config: WebAudioConfig, # Instance configuration
) -> str: # JS stop function
"Generate JS function that stops current playback."
def generate_play_segment(
config: WebAudioConfig, # Instance configuration
nav_down_btn_id: str = "", # Nav down button ID (for auto-navigate)
) -> str: # JS play function
"""
Generate JS function that plays a segment from a specific buffer.
When `config.enable_speed=True` and speed != 1.0 and the SoundTouch worklet is
registered, audio flows BufferSource -> SoundTouchNode -> destination, with
pitch auto-compensated by the worklet so tempo changes preserve pitch. Otherwise
audio flows BufferSource -> destination (naive path; pitch shifts at non-1x).
"""
def _speed_values_js_array() -> str: # JS array literal of speed values
"""Render PLAYBACK_SPEEDS values as a JS array literal (e.g., '[0.5, 0.75, ...]')."""
return "[" + ", ".join(str(s) for s, _ in PLAYBACK_SPEEDS) + "]"
def generate_optional_features(
config: WebAudioConfig, # Instance configuration
) -> str: # JS for optional feature functions (empty if none enabled)
"Render PLAYBACK_SPEEDS values as a JS array literal (e.g., '[0.5, 0.75, ...]')."
def generate_optional_features(
config: WebAudioConfig, # Instance configuration
) -> str: # JS for optional feature functions (empty if none enabled)
"""
Generate JS for optional features based on config flags.
When `config.enable_speed=True`, emits `set{Ns}Speed`, `cycle{Ns}SpeedTo`,
`cycle{Ns}SpeedUp`, `cycle{Ns}SpeedDown`. The cycle helpers drive the shared
speed `<select>` via a synthetic `change` event so the dropdown, JS state, and
HTMX-backed server persistence stay in sync through a single code path.
"""
def generate_speed_change_js(
config: WebAudioConfig, # Instance configuration
speed: float, # New playback speed
) -> str: # JS snippet: updates JS playbackSpeed via set{Ns}Speed
"""
Generate the JS body returned by a consumer's `/speed_change` POST handler.
Consumers wrap this in a `Script(...)` and return it so the client-side state
updates after the server persists the new speed. Guarded with `if (window.set{Ns}Speed)`
to tolerate the Script running before the web-audio script initializes.
"""
def generate_focus_change(
config: WebAudioConfig, # Instance configuration
focus_input_id: str, # Hidden input ID for focused index (kept for API compat; no longer written to)
) -> str: # JS focus change callback
"Generate JS focus change callback for card stack integration."
def generate_htmx_settle_handler(
config: WebAudioConfig, # Instance configuration
card_stack_id: str, # Card stack container ID
) -> str: # JS HTMX afterSettle handler
"""
Generate HTMX afterSettle handler for card stack navigation.
When `config.should_play_fn` is set, delegates the play guard to a consumer-defined
window function (e.g., `window.shouldAlignPlay()`). Otherwise uses the default
inline guard based on zone active state and auto-navigate flag.
"""
def generate_web_audio_js(
config: WebAudioConfig, # Instance configuration
focus_input_id: str, # Hidden input ID for focused index
card_stack_id: str, # Card stack container ID
nav_down_btn_id: str = "", # Nav down button ID (for auto-navigate)
) -> str: # Complete JS code for this instance
"Generate the complete Web Audio API JS for a configured instance."
Variables
DEFAULT_WORKLET_URL = '/static/cjm-web-audio/soundtouch-processor.js'
PLAYBACK_SPEEDS = [8 items]
models (models.ipynb)
Configuration and HTML ID types for the Web Audio API manager
Import
from cjm_fasthtml_web_audio.models import (
WebAudioConfig,
WebAudioHtmlIds
)
Classes
@dataclass
class WebAudioConfig:
"Configuration for a Web Audio API manager instance."
namespace: str # Unique prefix (e.g., "align", "review")
indicator_selector: str # CSS selector for playing indicators
data_index_attr: str = 'audioFileIndex' # Data attr name for buffer index
data_start_attr: str = 'startTime' # Data attr name for start time
data_end_attr: str = 'endTime' # Data attr name for end time
enable_speed: bool = False # Playback speed support (pitch-preserving via SoundTouch worklet)
enable_replay: bool = False # Replay current segment support
enable_auto_nav: bool = False # Auto-navigate on completion support
should_play_fn: str = '' # Named window function for custom play guard (replaces default zone guard)
worklet_url: Optional[str] # URL of vendored soundtouch-processor.js; None -> default mount path
def ns(self) -> str: # Capitalized namespace for JS function names
"""Capitalized namespace for JS function names (e.g., 'align' -> 'Align')."""
return self.namespace.capitalize()
@property
def state_key(self) -> str: # JS state object key
"Capitalized namespace for JS function names (e.g., 'align' -> 'Align')."
def state_key(self) -> str: # JS state object key
"JS global state object key (e.g., '_webAudio_align')."
class WebAudioHtmlIds:
"HTML ID generators for Web Audio manager elements."
def audio_urls_input(
namespace: str # Instance namespace
) -> str: # HTML ID for audio URLs hidden input
"ID for the hidden input storing audio file URLs as JSON."
def speed_select(
namespace: str # Instance namespace
) -> str: # HTML ID for the playback speed <select>
"ID for the playback speed selector element."
Metadata
Release files for cjm-fasthtml-web-audio 0.0.16
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| cjm_fasthtml_web_audio-0.0.16.tar.gz | 45.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cjm_fasthtml_web_audio-0.0.16-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 93.3 kB
Release files / cjm_fasthtml_web_audio-0.0.16.tar.gz
| Download URL | cjm_fasthtml_web_audio-0.0.16.tar.gz |
|---|---|
| Size | 45.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b56409b1a07c323572735f794707ccf5119f0f3ba6d26e634bca0adcbb670392
|
|
BLAKE2b-256 checksum How to use checksums |
56ed06fbe424c86eaad2df15e66a8a36afaf305225c778e0c85a14ef174fe10d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / cjm_fasthtml_web_audio-0.0.16-py3-none-any.whl
| Download URL | cjm_fasthtml_web_audio-0.0.16-py3-none-any.whl |
|---|---|
| Size | 47.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7dbf86fd532955316939bdbe9c631b2d6e392db29a3018ec8b0fd5a37dc7eeaa
|
|
BLAKE2b-256 checksum How to use checksums |
ae6834bf58fd7281368daaa3babf5758ab01f6beb04675ee4582d28a3eb4b371
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Security for cjm-fasthtml-web-audio 0.0.16
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.