OfSpectrum Audio Watermarking SDK
Project description
OfSpectrum Python SDK
Official Python SDK for the OfSpectrum audio watermarking API.
Installation
pip install ofspectrum
Or install from source:
pip install -e /path/to/neo/sdk
Quick Start
from ofspectrum import OfSpectrum
client = OfSpectrum(api_key="your_api_key")
# Create a Standard token.
token = client.tokens.create(name="Production Token")
print(f"Created token: {token.id}")
# Encode and save watermarked audio.
result = client.audio.encode(
audio="input.mp3",
token_id=token.id,
)
result.save("watermarked.mp3")
print(f"Encoded {result.audio_duration}s of audio")
# Decode watermark from audio.
decode = client.audio.decode("suspect.mp3")
if decode.watermarked:
print(f"Watermark detected. Token ID: {decode.token_id}")
else:
print("No watermark detected")
# Check your quota.
quota = client.quotas.get_encode_quota()
print(f"Remaining encode quota: {quota.remaining}/{quota.quota_limit} seconds")
Token Management
Standard tokens are the simplest option. Pro tokens support workflow-specific verification-key configuration. Enterprise token configuration is available for eligible enterprise accounts or existing enterprise tokens.
import os
# List all tokens.
tokens = client.tokens.list()
# Get a specific token.
token = client.tokens.get("token-uuid")
# Create a Pro token when your workflow requires a configurable verification key.
verification_key = int(os.environ["OFSPECTRUM_PUBLIC_KEY"])
token = client.tokens.create(
name="Pro Token",
token_type="pro",
public_key=verification_key,
)
# Update a token name.
token = client.tokens.update(
token_id="token-uuid",
name="New Name",
)
# Update a Pro or eligible Enterprise token verification key.
token = client.tokens.update(
token_id="token-uuid",
public_key=verification_key,
)
Token deletion is not available via API. Tokens are consumable resources.
Audio Watermarking
result = client.audio.encode(
audio="input.mp3",
token_id=token.id,
strength=1.0,
smooth=True,
)
result.save("output.mp3")
decode = client.audio.decode("suspect.mp3")
if decode.watermarked:
print(f"Token: {decode.token_id}")
Use decode(..., public_key=verification_key) only when your workflow requires an explicit verification key.
Streaming PCM Encode
Use stream_encode_pcm() when your application already works with raw PCM audio or needs low-latency streaming from a file-processing pipeline, microphone, call, meeting, or live stream.
The input must be raw PCM float32 little-endian bytes. 48 kHz mono is recommended. The SDK does not currently decode MP3/WAV/FLAC files, resample audio, or convert containers for this streaming method.
def chunk_pcm(pcm_bytes: bytes, chunk_seconds: float = 0.5):
sample_rate = 48000
channels = 1
bytes_per_second = sample_rate * channels * 4
chunk_size = int(bytes_per_second * chunk_seconds)
for offset in range(0, len(pcm_bytes), chunk_size):
yield pcm_bytes[offset:offset + chunk_size]
result = client.audio.stream_encode_pcm(
pcm_chunks=chunk_pcm(pcm_f32le_bytes),
token_id=token.id,
sample_rate=48000,
channels=1,
smooth=True,
)
encoded_pcm = result.encoded_pcm
print(f"Encoded {result.audio_duration:.2f}s of PCM")
encoded_pcm is raw PCM float32 little-endian, not WAV or MP3. Wrap it in a WAV container or encode it to your desired output format before playback or download.
Notebook Management
Attach notes and media files to tokens. Private notebooks require a credential, and limits depend on your account and token configuration.
notebook = client.notebooks.create(
token_id=token.id,
note_name="Release Notes",
text_content="## Version 1.0\n\nRelease notes.",
is_public=True,
)
private_notebook = client.notebooks.create(
token_id=token.id,
note_name="Private Notes",
text_content="Confidential content",
is_public=False,
credential_val="choose-a-secure-credential",
)
client.notebooks.upload_media(
note_id=notebook.id,
file="cover.jpg",
)
notebooks = client.notebooks.list(token_id=token.id)
Quota Checking
quota = client.quotas.get_encode_quota()
print(f"Remaining encode quota: {quota.remaining}")
decode_quota = client.quotas.get_decode_quota()
print(f"Remaining decode quota: {decode_quota.remaining}")
if client.quotas.check_encode_available(duration_seconds=300):
result = client.audio.encode(audio="input.mp3", token_id=token.id)
Error Handling
from ofspectrum import (
OfSpectrumError,
AuthenticationError,
RateLimitError,
QuotaExceededError,
WatermarkExistsError,
ResourceNotFoundError,
)
try:
result = client.audio.encode(audio="input.mp3", token_id="...")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after} seconds")
except QuotaExceededError as e:
print(f"Quota exceeded for {e.service}")
except WatermarkExistsError:
print("Audio already has a watermark")
except AuthenticationError:
print("Invalid API key")
except OfSpectrumError as e:
print(f"API error: {e.code} - {e.message}")
Context Manager
with OfSpectrum(api_key="your_api_key") as client:
tokens = client.tokens.list()
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ofspectrum-1.1.4.tar.gz.
File metadata
- Download URL: ofspectrum-1.1.4.tar.gz
- Upload date:
- Size: 21.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fedf9e4e3859ac3a51b983df306385c037fdb8c349795ce9f9d83d80dcf6515a
|
|
| MD5 |
45b0b62a2acba0a7c4062483b39c6fc4
|
|
| BLAKE2b-256 |
e9443e95dce31cf92f047dff4f0182cf183ecb009492f6fb5110a0202f078a10
|
Provenance
The following attestation bundles were made for ofspectrum-1.1.4.tar.gz:
Publisher:
publish.yml on ofspectrum/python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ofspectrum-1.1.4.tar.gz -
Subject digest:
fedf9e4e3859ac3a51b983df306385c037fdb8c349795ce9f9d83d80dcf6515a - Sigstore transparency entry: 2011003504
- Sigstore integration time:
-
Permalink:
ofspectrum/python-sdk@2c32efcbd8b79a761574ab6cba5fed455ad1d118 -
Branch / Tag:
refs/tags/v1.1.4 - Owner: https://github.com/ofspectrum
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2c32efcbd8b79a761574ab6cba5fed455ad1d118 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file ofspectrum-1.1.4-py3-none-any.whl.
File metadata
- Download URL: ofspectrum-1.1.4-py3-none-any.whl
- Upload date:
- Size: 26.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81f877112fe58c8ad08637c278007129bf0ded95ceefc33f1ac4c288abd9d30b
|
|
| MD5 |
1df1ce2d71afc0271321fb378c0b76f6
|
|
| BLAKE2b-256 |
9b9cad663bdd06ea2fae76cccbb4637d2c5c8ccdc20235ce077147cb8762d60a
|
Provenance
The following attestation bundles were made for ofspectrum-1.1.4-py3-none-any.whl:
Publisher:
publish.yml on ofspectrum/python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ofspectrum-1.1.4-py3-none-any.whl -
Subject digest:
81f877112fe58c8ad08637c278007129bf0ded95ceefc33f1ac4c288abd9d30b - Sigstore transparency entry: 2011003585
- Sigstore integration time:
-
Permalink:
ofspectrum/python-sdk@2c32efcbd8b79a761574ab6cba5fed455ad1d118 -
Branch / Tag:
refs/tags/v1.1.4 - Owner: https://github.com/ofspectrum
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2c32efcbd8b79a761574ab6cba5fed455ad1d118 -
Trigger Event:
workflow_dispatch
-
Statement type: