# ap_ds
**Repository Path**: dssxt/ap_ds
## Basic Information
- **Project Name**: ap_ds
- **Description**: ap_ds: Redefining Lightweight Python Audio Development
Starting from 2.5MB, ending the era of bloated audio libraries
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-03-21
- **Last Updated**: 2026-03-22
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# ap_ds: A Lightweight Python Audio Library
**Current Stable Version: v2.4.1 (Released March 1, 2026)**
---
## π’ Latest Updates
### v2.4.1 (March 1, 2026) - Documentation Update
- Updated PyPI documentation with complete 2.4.0 feature descriptions
- Added detailed examples and environment variable documentation
- **No code changes** from v2.4.0
### v2.4.0 (March 1, 2026) - Audio Effects & Engineering
- **New fade functions:** `fadein_music()`, `fadein_music_pos()`, `fadeout_music()`
- **State queries:** `is_music_playing()`, `is_music_paused()`, `get_music_fading()`
- **Smart welcome message:** Controllable via `AP_DS_HIDE_SUPPORT_PROMPT`
- **Centralized version management:** Auto-generated `_version.py`
- **Robust import system:** Two-layer fallback for all environments
- Unified project URL: **https://apds.top**
---
## β οΈ Important Version Information
Versions `2.2.0` through `2.3.2` contain a critical cross-platform bug that prevents the library from functioning correctly on non-Windows operating systems (macOS and Linux). This has been **fixed** in subsequent versions.
| Version | Release Date | Status | Recommendation |
|---------|--------------|--------|----------------|
| **v2.4.1** | March 1, 2026 | β
Latest Stable | **Current release - Recommended** |
| v2.4.0 | March 1, 2026 | β
Stable | Safe to use |
| v2.3.6 | February 27, 2026 | β
Stable | Documentation update |
| v2.3.5 | February 26, 2026 | β
Stable | Embedded validation & fixes |
| v2.3.4 | February 10, 2026 | β
Stable | Safe to use |
| v2.3.3 | February 9, 2026 | β
Stable | First fixed version |
| v2.3.2 | February 9, 2026 | β YANKED | Do not use |
| v2.3.1 | February 9, 2026 | β YANKED | Do not use |
| v2.3.0 | January 31, 2026 | β YANKED | Do not use |
| v2.2.0 | January 19, 2026 | β YANKED | Do not use |
---
**Action Required:** Run `pip install --upgrade ap_ds` immediately to update to the latest stable version `v2.4.1`.
We sincerely apologize for any inconvenience caused by earlier versions. The integrity and functionality of the library across all supported platforms are now ensured.
## Overview
ap_ds is a lightweight (2.5MB) Python audio library for playback and accurate metadata parsing of MP3, FLAC, OGG, and WAV files. It has zero external Python dependencies, utilizing only the Python standard library, and provides non-blocking playback for smooth GUI applications.
**Key Features:**
- **Extreme Lightweight:** Only 2.5MB (Windows) / 3.36MB (macOS) complete solution
- **Zero Python Dependencies:** Uses only standard library
- **Accurate Metadata:** 100% for WAV/FLAC, 99.99% for OGG, >98% for MP3
- **Non-blocking Playback:** Perfect for GUI applications
- **Cross-Platform:** Windows, macOS, Linux, and embedded ARM64
- **DAP Recording System:** Automatic playback history with metadata only
---
## Installation
```bash
pip install ap_ds
```
To upgrade from an older version:
```bash
pip install --upgrade ap_ds
```
---
## Quick Start
```python
from ap_ds import AudioLibrary
# Initialize the library
lib = AudioLibrary()
# Play an audio file
aid = lib.play_from_file("music/song.mp3")
# Control playback
lib.pause_audio(aid) # Pause
lib.play_audio(aid) # Resume
lib.seek_audio(aid, 30.5) # Seek to 30.5 seconds
# Stop and get duration played
duration = lib.stop_audio(aid)
print(f"Played for {duration:.2f} seconds")
```
---
## DAP Playlist System
Audio files are automatically recorded to DAP (Dvs Audio Playlist) upon playback:
```python
# Files are automatically recorded
aid1 = lib.play_from_file("song1.mp3")
aid2 = lib.play_from_file("song2.ogg")
# Get all recordings
recordings = lib.get_dap_recordings()
print(f"Recorded {len(recordings)} files")
# Save to JSON
success = lib.save_dap_to_json("my_playlist.ap_ds-dap")
```
DAP stores only metadata (path, duration, bitrate, channels), not audio data. Memory usage is approximately 150 bytes per recording.
---
## Platform Support
### Windows
- Automatic download of SDL2.dll and SDL2_mixer.dll
- No manual configuration required
- Supports Windows 7 and later
### macOS
- Automatic download of SDL2.framework and SDL2_mixer.framework
- No manual configuration required
- Supports macOS 10.9 and later
### Linux
**Intelligent Multi-Layer Import System:**
1. **System Library Check:** Uses system-installed SDL2 libraries
2. **User Configuration:** Checks saved paths from previous runs
3. **Automatic Installation:** Detects package manager and installs required packages
4. **Interactive Guidance:** Manual options if all else fails
**Package Manager Support:**
```bash
# Ubuntu/Debian
sudo apt-get install libsdl2-dev libsdl2-mixer-dev
# Fedora
sudo dnf install SDL2-devel SDL2_mixer-devel
# Arch
sudo pacman -S sdl2 sdl2_mixer
```
### Embedded ARM64
Tested on:
- **Orange Pi 4 Pro** (Allwinner A733, 2xA76 + 6xA55 @ 2.0GHz)
- **Raspberry Pi 5** (BCM2712, 4xA76 @ 2.4GHz)
Both run Ubuntu 22.04 with full audio support via 3.5mm output. Memory growth after extensive testing: ~4MB.
---
## Environment Variables
### WAV Playback Threshold
Controls whether WAV files use sound effect mode (no seek) or music mode (full seek):
```bash
# Set threshold to 10 seconds (default: 6)
export AP_DS_WAV_THRESHOLD=10
# Files < threshold β sound effect mode (no seek)
# Files >= threshold β music mode (full seek)
```
**Validation Rules:**
- Values >= 30 are reset to 6 (prevents memory issues)
- Negative values are reset to 6
- Invalid values fall back to default
### Linux SDL2 Library Paths
For custom-compiled SDL2 libraries:
```bash
export AP_DS_SDL2_PATH=/usr/local/lib/libSDL2.so
export AP_DS_SDL2_MIXER_PATH=/usr/local/lib/libSDL2_mixer.so
```
Paths are automatically saved to `~/.config/ap_ds/sdl_paths.conf` after first use.
---
## SSL Certificate Verification
### The Problem
On some older or enterprise-configured systems, you might encounter SSL certificate verification errors during the initial download of SDL2 libraries:
```
SSL certificate verification failed: unable to get local issuer certificate
```
**Common Causes:**
- Old Windows systems (7/8) with outdated root certificates
- Enterprise networks with proxy servers and custom certificates
- Lightweight installations with minimal certificate stores
- Incorrect system time
### The Solution
ap_ds implements a **layered download strategy**:
```python
def download_with_ssl(url):
try:
# First attempt: Standard SSL verification
return urllib.request.urlopen(url)
except SSL error:
# Second attempt: Unverified context (compatibility mode)
# Only triggered when standard verification fails
return download_with_unverified_context(url)
```
### Security Analysis
**Is this safe? Yes.**
1. **Limited Scope:** Unverified context is ONLY used for downloading two specific DLLs (SDL2 and SDL2_mixer) from official sources.
2. **Fallback Only:** Standard verification is ALWAYS tried first. Unverified mode is only a fallback for legitimate certificate issues.
3. **Limited Capability:** Even if a DLL were tampered with (extremely unlikely), SDL2 libraries are audio renderers with:
- No network capabilities
- No file system access beyond opening audio files
- No ability to create processes
- No access to system resources beyond audio output
4. **Attack Economics:** Creating a functional malicious replacement for SDL2 requires:
- Complete replication of complex audio functionality
- Mimicking normal behavior to avoid detection
- Surviving antivirus scanning
- Targeting a niche Python audio library
The cost dramatically outweighs any potential benefit.
5. **Multi-Layer Protection:** Any malicious behavior would be immediately detected by:
- Windows Defender / 360 / other antivirus software
- User observation (abnormal CPU, network activity)
- System-level protections (UAC, sandboxing)
### Manual Alternative
If you have security concerns, manually download the libraries:
1. Download SDL2 and SDL2_mixer from [official libsdl.org](https://www.libsdl.org/)
2. Place DLLs in your system PATH or project directory
3. ap_ds will automatically use existing local libraries instead of downloading
---
## API Reference
### AudioLibrary Class
```python
__init__(frequency=44100, format=MIX_DEFAULT_FORMAT, channels=2, chunksize=2048)
```
### Core Methods
| Method | Description | Return |
|--------|-------------|--------|
| `play_from_file(path, loops=0, start_pos=0.0)` | Play audio from file | int (AID) |
| `play_from_memory(path, loops=0, start_pos=0.0)` | Play from cache | int (AID) |
| `new_aid(path)` | Pre-load audio into memory | int (AID) |
| `pause_audio(aid)` | Pause playback | None |
| `play_audio(aid)` | Resume playback | None |
| `stop_audio(aid)` | Stop and free resources | float (duration) |
| `seek_audio(aid, position)` | Seek to position (seconds) | None |
| `set_volume(aid, volume)` | Set volume (0-128) | bool |
| `get_volume(aid)` | Get current volume | int |
| `get_audio_duration(source, is_file=False)` | Get duration | int (seconds) |
| `get_audio_metadata(source, is_file=False)` | Get metadata | Dict or None |
### DAP Methods
| Method | Description | Return |
|--------|-------------|--------|
| `save_dap_to_json(path)` | Save DAP records to JSON | bool |
| `get_dap_recordings()` | Get all DAP records | List[Dict] |
| `clear_dap_recordings()` | Clear DAP records | None |
## v2.4.0 & v2.4.1 Release Notes
---
### π Overview
Version 2.4.0 marks a significant milestone in ap_ds evolution, introducing **professional audio transitions** and **major engineering improvements** under the hood. v2.4.1 follows immediately with **complete documentation updates** to ensure users can fully leverage the new features.
| Version | Release Date | Type | Focus |
|---------|--------------|------|-------|
| **v2.4.1** | March 1, 2026 | Documentation | PyPI docs, examples, environment variables |
| **v2.4.0** | March 1, 2026 | Feature + Engineering | Fade functions, version management, import system |
---
## β¨ What's New in v2.4.0
### π΅ Audio Effects: Professional Transitions
The most visible addition is a complete set of **fade in/out functions**, transforming ap_ds from a simple playback library into a tool capable of professional audio transitions.
#### New Functions
| Function | Description | Parameters |
|----------|-------------|------------|
| `fadein_music(aid, loops=-1, ms=0)` | Fade in audio over specified milliseconds | `aid`: Audio instance ID
`loops`: -1 = infinite, 0 = once, N = N times
`ms`: Fade duration in milliseconds |
| `fadein_music_pos(aid, loops=-1, ms=0, position=0.0)` | Fade in from specific position | Same as above, plus:
`position`: Start position in seconds |
| `fadeout_music(ms=0)` | Fade out currently playing music | `ms`: Fade duration in milliseconds |
| `is_music_playing()` | Check if music is currently playing | None |
| `is_music_paused()` | Check if music is paused | None |
| `get_music_fading()` | Get current fade state | Returns: `0` (no fade), `1` (fading out), `2` (fading in) |
#### Usage Examples
```python
from ap_ds import AudioLibrary
import time
lib = AudioLibrary()
# Basic fade in over 2 seconds
aid = lib.play_from_file("song.mp3")
lib.fadein_music(aid, loops=-1, ms=2000)
# Fade in from the 30-second mark
aid2 = lib.play_from_file("podcast.mp3")
lib.fadein_music_pos(aid2, loops=1, ms=1500, position=30.0)
# Let it play for a while
time.sleep(5)
# Smooth fade out over 3 seconds
lib.fadeout_music(ms=3000)
# Query states
if lib.is_music_playing():
print("Music is playing")
fade_state = lib.get_music_fading()
if fade_state == 1: # MIX_FADING_OUT
print("Fading out...")
```
#### Underlying SDL2 Implementation
These functions directly wrap the following SDL2_mixer APIs:
- `Mix_FadeInMusic()` β `fadein_music()`
- `Mix_FadeInMusicPos()` β `fadein_music_pos()`
- `Mix_FadeOutMusic()` β `fadeout_music()`
- `Mix_PlayingMusic()` β `is_music_playing()`
- `Mix_PausedMusic()` β `is_music_paused()`
- `Mix_FadingMusic()` β `get_music_fading()`
---
### π§ Engineering Improvements
#### 1. Smart Welcome Message
The startup banner is now cleaner and **user-controllable**:
```python
# Default behavior (shows once when library loads)
import ap_ds
# Output: AP_DS Β© - Audio Library By DVS v2.4.0 | https://apds.top
# Silence it completely with environment variable
import os
os.environ['AP_DS_HIDE_SUPPORT_PROMPT'] = '1'
import ap_ds # No output at all
```
**Why this matters:**
- Cleaner integration for GUI applications
- No unwanted console output in production
- Still visible by default for new users
#### 2. Centralized Version Management
Version is now defined **once** in `setup.py` and automatically generates `_version.py`:
```python
# setup.py
VERSION = "2.4.0"
def write_version_file():
version_file_path = os.path.join("ap_ds", "_version.py")
with open(version_file_path, "w", encoding="utf-8") as f:
f.write(f'__version__ = "{VERSION}"\n')
```
**Benefits:**
- Single source of truth for version
- No more manual version updates across files
- Prevents version mismatch errors
#### 3. Robust Import System
Two-layer fallback ensures compatibility across **all Python environments**:
```python
# Version import with fallback
try:
from ._version import __version__
except ImportError:
try:
from _version import __version__
except ImportError:
__version__ = "unknown"
# Core module import with same pattern
try:
from .player import *
except ImportError:
from player import *
```
**Why this is important:**
- Works in both package and direct script contexts
- Handles different Python path configurations
- Graceful degradation if version file is missing
#### 4. Unified Project URL
All project references now point to the central hub: **[https://apds.top](https://apds.top)**
This consolidates:
- Documentation
- Version history
- Contact information
- Future announcements
---
## π v2.4.1: Documentation Update
While v2.4.0 delivered the code, **v2.4.1 ensures users can actually use it**.
### What Was Updated
#### PyPI Project Description
- Complete rewrite to reflect all v2.4.0 features
- Clear function descriptions with parameters and return values
- Multiple code examples for each new feature
#### Environment Variable Documentation
- `AP_DS_WAV_THRESHOLD` β WAV playback mode threshold (from v2.3.5)
- `AP_DS_HIDE_SUPPORT_PROMPT` β Control startup message (new in v2.4.0)
#### Quick Start Guide Enhancements
- Before/after examples showing migration from v2.3.x
- Common usage patterns for fade functions
- State query integration examples
#### Version History
- Complete changelog from v1.0.0 to v2.4.1
- Clear indication of yanked versions
- Upgrade recommendations
---
## π§ Environment Variables Reference
| Variable | Default | Description | Since |
|----------|---------|-------------|-------|
| `AP_DS_WAV_THRESHOLD` | `6` | WAV threshold in seconds (β₯ threshold = music mode with seek support) | v2.3.5 |
| `AP_DS_HIDE_SUPPORT_PROMPT` | not set | Set to `1` to hide the startup welcome message | v2.4.0 |
---
## π¦ Migration Guide
### From v2.3.x to v2.4.x
**No code changes required** β all existing applications continue to work unchanged.
To start using new features:
```python
# Before (v2.3.x)
aid = lib.play_from_file("song.mp3")
time.sleep(5)
lib.stop_audio(aid) # Abrupt stop
# After (v2.4.0) - Professional!
aid = lib.play_from_file("song.mp3")
time.sleep(5)
lib.fadeout_music(ms=3000) # Smooth exit over 3 seconds
```
### Installation
```bash
# Install or upgrade to latest version
pip install --upgrade ap_ds
# Verify installation
python -c "import ap_ds; print(ap_ds.__version__)" # Should show 2.4.1
```
---
## β‘ Performance & Compatibility
| Metric | Value |
|--------|-------|
| **Package Size** | Windows: 2.5MB / macOS: 3.36MB / Linux: depends on system SDL2 |
| **Memory Growth** | ~4MB after extensive testing |
| **Python Support** | 3.7+ (all versions) |
| **Platform Support** | Windows, macOS, Linux (x86_64, ARM64) |
| **API Compatibility** | 100% backward compatible with v2.3.x |
---
## π― Summary
**v2.4.0 transforms ap_ds from a "playback library" into a professional audio tool:**
- β
Smooth audio transitions (fade in/out)
- β
Complete state querying
- β
Cleaner, more professional startup
- β
Industrial-strength version management
- β
Bulletproof import system
**v2.4.1 ensures every user can fully leverage these features:**
- β
Comprehensive PyPI documentation
- β
Detailed code examples
- β
Clear environment variable documentation
**All while maintaining the core promise:** lightweight, zero external Python dependencies, and true cross-platform compatibility.
---
### Metadata Format
```python
{
'format': 'MP3', # File format
'duration': 240, # Duration in seconds
'sample_rate': 44100, # Sample rate in Hz
'channels': 2, # Number of channels
'bitrate': 320000 # Bitrate in bps
}
```
### DAP Record Format
```python
{
'path': '/Music/song.mp3', # File path
'duration': 240, # Duration in seconds
'bitrate': 320000, # Bitrate in bps
'channels': 2 # Number of channels
}
```
---
## Complete Examples
### Get Audio Metadata
```python
from ap_ds import get_audio_parser
parser = get_audio_parser()
metadata = parser.get_audio_metadata("song.mp3")
if metadata:
print(f"Format: {metadata['format']}")
print(f"Duration: {metadata['duration']} seconds")
print(f"Sample Rate: {metadata['sample_rate']}Hz")
print(f"Channels: {metadata['channels']}")
print(f"Bitrate: {metadata['bitrate']}bps")
```
### Advanced Playback Control
```python
# Pre-load audio files
effect = lib.new_aid("sound.wav")
music = lib.new_aid("track.flac")
# Play from memory (instant start)
lib.play_audio(effect)
# Volume control
lib.set_volume(effect, 80)
current = lib.get_volume(effect)
# Get duration for progress bar
duration = lib.get_audio_duration(effect)
print(f"Duration: {duration}s")
```
### Listening Habit Analyzer
```python
import json
class ListeningAnalyzer:
def analyze(self, dap_path):
with open(dap_path, 'r', encoding='utf-8') as f:
records = json.load(f)
total_seconds = sum(r['duration'] for r in records)
hours = total_seconds // 3600
bitrate_stats = {}
for r in records:
bitrate_stats[r['bitrate']] = bitrate_stats.get(r['bitrate'], 0) + 1
return {
"total_songs": len(records),
"total_hours": hours,
"bitrate_distribution": bitrate_stats
}
```
### Cross-Platform Player
```python
import platform
from ap_ds import AudioLibrary
class Player:
def __init__(self):
self.lib = AudioLibrary()
print(f"Running on {platform.system()}")
def play(self, path):
try:
aid = self.lib.play_from_file(path)
print(f"Playing: {path}")
return aid
except Exception as e:
print(f"Error: {e}")
return None
```
---
## Format Support and Precision
| Format | Playback | Duration Precision | Metadata |
|:-------|:--------:|:------------------:|:---------|
| **MP3** | β
Full | >98% | Sample Rate, Bitrate |
| **FLAC** | β
Full | 100% | All Metadata |
| **OGG** | β
Full | 99.99% | All Metadata |
| **WAV** | β
Full | 100% | All Metadata |
---
## Size Comparison
| Solution | Size | Ratio |
|----------|------|-------|
| **ap_ds (Windows)** | 2.5 MB | 1x |
| **ap_ds (macOS)** | 3.36 MB | 1.34x |
| **FFmpeg-based** | 160+ MB | 64x |
| **Pygame + parsers** | 50+ MB | 20x |
**Breakdown:**
- SDL2.dll: 2.1 MB
- SDL2_mixer.dll: 400 KB
- Python code: 42 KB
- **Total: 2.5 MB**
---
## Frequently Asked Questions
### Which version should I use?
**v2.3.5 is the latest stable release and is recommended for all users.** It includes all fixes from previous versions plus embedded platform testing.
v2.3.3 was the first version to fix the critical cross-platform crash and is also stable. v2.3.4 added Linux intelligent import. All three are safe to use.
### Can I use this in commercial products?
Yes, absolutely. The license explicitly permits any commercial use, including integration into commercial products, cloud services, and SaaS platforms, completely free of charge. You must comply with the attribution requirements.
### Why is it so small?
ap_ds focuses precisely on playback and parsing for the four most common formats, avoiding the bloat of editing/transcoding features. It's built on the efficient SDL2 C library and is meticulously optimized.
### How accurate is MP3 parsing?
MP3 duration parsing is >98% accurate. This is due to the format's variable header complexities. For WAV and FLAC we guarantee 100% accuracy, and for OGG 99.99%.
### Does it work on embedded devices?
Yes! v2.3.5 includes testing on Orange Pi 4 Pro and Raspberry Pi 5 (ARM64) running Ubuntu 22.04. Memory growth is minimal (~4MB after extensive testing).
### What are the system requirements?
- **Windows:** Windows 7+, Python 3.7+
- **macOS:** macOS 10.9+, Python 3.7+
- **Linux:** Modern distributions, Python 3.7+, SDL2 libraries
- **Embedded:** ARM64 devices with Ubuntu 22.04 or similar
### How do I configure the WAV threshold?
Set the environment variable:
```bash
# Linux/macOS
export AP_DS_WAV_THRESHOLD=10
# Windows Command Prompt
set AP_DS_WAV_THRESHOLD=10
# Windows PowerShell
$env:AP_DS_WAV_THRESHOLD=10
```
### Is the SSL fallback safe?
Yes. It only activates when standard verification fails, only downloads two specific audio libraries, and those libraries have extremely limited capabilities. See the SSL Certificate Verification section for detailed analysis.
---
## Technical Architecture
### Core Components
```
ap_ds/
βββ player.py # Main player logic, platform abstraction
βββ audio_parser.py # Metadata parsing
βββ audio_info.py # Format-specific parsers
βββ __init__.py # Package initialization
```
### AID Management System
```python
self._audio_cache = {} # path -> Mix_Chunk
self._music_cache = {} # path -> Mix_Music
self._channel_info = {} # channel ID -> playback info
self._aid_to_filepath = {} # AID -> path
```
### DAP Memory Layout
```python
self._dap_recordings = [] # List of record dicts
# Memory: ~150 bytes per record
# 10,000 records β ~1.5 MB RAM
# 10,000 records β ~2-3 MB JSON file
```
---
## Support and Community
- **Official Website:** https://www.dvsyun.top/ap_ds
- **PyPI:** https://pypi.org/project/ap_ds/
- **Author Email:** me@dvsyun.top
- **GitHub Repository:** Coming Soon
---
## License
For detailed information, please refer to: AP_DS_LICENSE.MD or AP_DS_LICENSE_v2.0_ZHCN.MD
For instructions, please refer to: AP_DS_GUIDE_v2.0_ZHCN.MD or AP_DS_GUIDE_v2.0_EN.MD
Thank you.
---
## Version History
### v2.4.1 (March 1, 2026) - Documentation Update
This version updates the PyPI documentation to fully reflect the new features introduced in v2.4.0, including detailed API descriptions, usage examples, and environment variable documentation.
**Changes:**
- Updated PyPI project description with complete 2.4.0 feature documentation
- Added detailed examples for all new fade functions
- Documented `AP_DS_HIDE_SUPPORT_PROMPT` environment variable
- Improved quick start guide with common usage patterns
**Note:** This release contains no code changes from v2.4.0βonly documentation improvements.
---
### v2.4.0 (March 1, 2026) - Audio Effects & Engineering Improvements
**β
This version introduces professional audio transitions and significant internal engineering upgrades.**
---
#### π΅ New Audio Control Features
**Fade In/Out Functions:**
| Function | Description |
|----------|-------------|
| `fadein_music(aid, loops=-1, ms=0)` | Fade in music over specified milliseconds |
| `fadein_music_pos(aid, loops=-1, ms=0, position=0.0)` | Fade in from specific position |
| `fadeout_music(ms=0)` | Fade out currently playing music |
| `is_music_playing()` | Check if music is currently playing |
| `is_music_paused()` | Check if music is paused |
| `get_music_fading()` | Get current fade state (fading in/out/none) |
**Implementation Details:**
```python
# Fade in over 2 seconds
aid = lib.play_from_file("song.mp3")
lib.fadein_music(aid, loops=-1, ms=2000)
# Fade in from 30-second mark
lib.fadein_music_pos(aid, loops=-1, ms=1500, position=30.0)
# Fade out over 3 seconds
lib.fadeout_music(ms=3000)
# Check states
if lib.is_music_playing():
print("Music is playing")
fade_state = lib.get_music_fading() # Returns MIX_NO_FADING, MIX_FADING_OUT, MIX_FADING_IN
```
**Underlying SDL2 Functions:**
- `Mix_FadeInMusic()` - Basic fade in
- `Mix_FadeInMusicPos()` - Positioned fade in
- `Mix_FadeOutMusic()` - Fade out
- `Mix_PlayingMusic()` - Play state check
- `Mix_PausedMusic()` - Pause state check
- `Mix_FadingMusic()` - Fade state query
---
#### π§ Engineering Improvements
**1. Smart Welcome Message**
The startup banner is now cleaner and user-controllable:
```python
# Default behavior (shows once)
import ap_ds # Prints: AP_DS Β© - Audio Library By DVS v2.4.0 | https://apds.top
# Silence it with environment variable
import os
os.environ['AP_DS_HIDE_SUPPORT_PROMPT'] = '1'
import ap_ds # No output
```
**2. Centralized Version Management**
Version is now defined once in `setup.py` and automatically generates `_version.py`:
```python
# setup.py
VERSION = "2.4.0"
def write_version_file():
version_file_path = os.path.join("ap_ds", "_version.py")
with open(version_file_path, "w", encoding="utf-8") as f:
f.write(f'__version__ = "{VERSION}"\n')
```
**3. Robust Import System**
Two-layer fallback ensures compatibility across all Python environments:
```python
try:
from ._version import __version__
except ImportError:
try:
from _version import __version__
except ImportError:
__version__ = "unknown"
# Same pattern for core modules
try:
from .player import *
except ImportError:
from player import *
```
**4. Unified Project URL**
All project references now point to the central hub: **https://apds.top**
---
#### π Full API Changes
| Function | Parameters | Return | Description |
|----------|------------|--------|-------------|
| `fadein_music` | `aid: int, loops: int = -1, ms: int = 0` | `None` | Fade in audio instance |
| `fadein_music_pos` | `aid: int, loops: int = -1, ms: int = 0, position: float = 0.0` | `None` | Fade in from position |
| `fadeout_music` | `ms: int = 0` | `None` | Fade out current music |
| `is_music_playing` | `()` | `bool` | Check playing state |
| `is_music_paused` | `()` | `bool` | Check paused state |
| `get_music_fading` | `()` | `int` | Get fade state (0=no fade, 1=fade out, 2=fade in) |
---
#### π§ Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `AP_DS_WAV_THRESHOLD` | `6` | WAV threshold in seconds (from v2.3.5) |
| `AP_DS_HIDE_SUPPORT_PROMPT` | not set | Set to `1` to hide startup message |
---
#### β‘ Performance & Compatibility
- **Zero API breakage** β All existing code continues to work
- **No size increase** β Still under 4MB across all platforms
- **Full backward compatibility** β v2.3.x applications run unchanged
- **Python 3.7+ support** β Maintained
---
#### π¦ Migration Guide
No migration needed. Simply upgrade and enjoy the new features:
```bash
pip install --upgrade ap_ds
```
To use the new fade functions in existing code:
```python
# Before (v2.3.x)
aid = lib.play_from_file("song.mp3")
time.sleep(5)
lib.stop_audio(aid)
# After (v2.4.0) - Professional transitions!
aid = lib.play_from_file("song.mp3")
lib.fadeout_music(ms=3000) # Smooth exit
```
---
#### π― Summary
v2.4.0 transforms ap_ds from a "playback library" into a **professional audio tool** with:
- Smooth audio transitions (fade in/out)
- Complete state querying
- Cleaner, more professional startup
- Industrial-strength version management
- Bulletproof import system
**All while maintaining the core promise: lightweight, zero external Python dependencies, and cross-platform compatibility.**
---
*Next: Planning v2.5.0 with potential audio capture features*
### v2.3.6 (February 27, 2026)
This version updates the PyPi documentation, adding detailed license information and version history, and adding more examples.
### v2.3.5 (February 26, 2026) - Stability Optimization & Embedded Validation
#### Stability & Testing
**Six-Dimension Test Coverage:**
1. **Library Loading & Initialization**
- Cross-platform SDL2 loading validation
- Network failure, file corruption, permission error recovery
- AudioLibrary parameter verification
- Default settings validation across devices
2. **Playback Testing**
- MP3, FLAC, OGG, WAV format validation
- Variable bitrate and non-standard file handling
- Non-blocking playback verification
- Concurrent audio playback testing
3. **Seek Testing**
- Precision validation across formats
- Boundary condition testing (start, end, beyond duration)
- Seek during paused/stopped states
4. **Memory Pressure & Leak Detection**
- Long-duration playback monitoring
- Repeated load/unload cycles
- Cache behavior validation
- **Result:** ~4MB growth after extensive testing
5. **Metadata Parsing Accuracy**
- Sample collection from diverse sources
- Edge case analysis
- Format-specific parser validation
6. **DAP System Validation**
- Automatic recording verification
- Save/load reliability
- Memory cleanup on clear
#### Embedded Platform Support
**Tested Environments:**
| Platform | SoC | Cores | RAM | OS | Audio Output |
|----------|-----|-------|-----|-----|--------------|
| Orange Pi 4 Pro | Allwinner A733 | 2xA76 + 6xA55 @ 2.0GHz | 8GB LPDDR5 | Ubuntu 22.04 ARM64 | 3.5mm β TPA3116D2 @ 2Γ8Ξ© 5W |
| Raspberry Pi 5 | BCM2712 | 4xA76 @ 2.4GHz | 8GB LPDDR4X | Ubuntu 22.04 ARM64 | 3.5mm β TPA3116D2 @ 2Γ8Ξ© 5W |
**Results:**
- Intelligent package management: Working normally
- Audio output: Normal via 3.5mm
- AID management system: Working normally
- Memory growth: ~4MB after comprehensive testing
**Important Note:** ap_ds is a wrapper library. Low-level concerns (power optimization, I2S/HDMI/ALSA output, fine-grained memory management) are handled by SDL2 and the operating system. Python's language nature limits fine resource control. We have tested and confirmed functionality; no embedded-specific optimizations are planned as they fall outside our scope.
#### Bug Fixes
**WAV Playback Mode Selection**
Fixed an issue where WAV files were incorrectly treated as sound effects, preventing seek operations.
**New Logic:**
- Files < threshold (default 6s) β Sound effect mode (no seek)
- Files >= threshold β Music mode (full seek support)
- Configurable via `AP_DS_WAV_THRESHOLD` environment variable
**Validation:**
```python
WAV_THRESHOLD = int(os.environ.get('AP_DS_WAV_THRESHOLD', '6'))
if WAV_THRESHOLD >= 30: # Reset to default to prevent memory issues
WAV_THRESHOLD = 6
elif WAV_THRESHOLD < 0:
WAV_THRESHOLD = 6
```
#### Error Message Decision
**Design Decision: Keep Existing Simple Error Format**
**Proposed Change Rejected:** Structured error messages with causes and suggestions were considered but rejected.
**Reasons:**
1. **Limited Help for Complex Errors**
- Simple errors are easy to debug
- Complex errors cannot be accurately diagnosed by the library
- LLM integration for error analysis was considered but rejected due to cost and security concerns
2. **Target Users Are Developers**
- Developers can read error messages
- Beginners can ask ChatGPT or search engines
- Pre-written suggestions add little value
3. **Maintenance Burden**
- Modifying all error paths is time-consuming
- High risk of introducing new bugs
- Existing format works: `raise RuntimeError(f"Failed to load: {file_path}")`
**Final Decision:** Maintain existing simple exception format with clear error messages.
#### SSL Certificate Issue: R12 Certificate Compatibility
**Problem:** On some Windows systems, R12 certificates cause verification failures during SDL2 download.
**Solution Implemented:**
```python
def download_with_ssl(url):
try:
# First attempt: Standard SSL verification
return urllib.request.urlopen(url)
except (URLError, SSLError) as e:
# Fallback: Unverified context
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
opener = urllib.request.build_opener(
urllib.request.HTTPSHandler(context=ssl_context)
)
urllib.request.install_opener(opener)
return urllib.request.urlopen(url)
```
**Security Rationale:**
- Standard verification ALWAYS tried first
- Fallback only activates when legitimate certificate issues prevent installation
- Downloaded files are standard SDL2 libraries with limited capabilities
- Any malicious behavior would be detected by antivirus software
---
v1.0.0 (July 8, 2025) - Initial Release
Milestone: Project birth, foundational functionality
Core Features
Basic audio playback: MP3, WAV, FLAC, OGG formats
Playback control: Play, Pause, Stop, Seek basic APIs
Lightweight design: Initial version ~2MB
Technical Characteristics
SDL2-based audio processing
Pure Python encapsulation, no complex dependencies
Clean API design
v2.0.0 (November 5, 2025) - Architecture Refactoring
Milestone: Introduction of modern audio management system
Major Improvements
AID System: Audio ID for unified audio instance management
Architecture Refactoring: Modular design for improved maintainability
Smart Memory Management: Automatic cleanup of unused audio resources
State Management: Unified playback state tracking
Technical Upgrades
Introduction of AudioLibrary class as core manager
Audio instance lifecycle management
Error handling and recovery mechanisms
v2.1.0 (December 26, 2025) - Feature Enhancement
Milestone: Professional functionality expansion
New Features
Volume Control: Real-time volume adjustment (0-100%)
Metadata Enhancement: More precise audio information parsing
Playback Accuracy Improvement: Better time control and seeking
Optimization Improvements
Enhanced audio format compatibility
Optimized memory usage efficiency
More user-friendly API interface
v2.1.4 (January 18, 2026) - Stable Version
Milestone: Production environment stable release
Version Highlights
Core Stability: Thoroughly tested with no known critical bugs
Extreme Lightweight: Complete solution at only 2.5MB
Pain Point Resolution: Fills Python audio development gap
Complete Documentation: Detailed technical manual and examples
Market Positioning "2.5MB Windows Python Audio Solution"
Technical Specifications Size Analysis:
βββ SDL2.dll: 2.1MB
βββ SDL2_mixer.dll: 400KB
βββ Python Code: 42KB
Comparison Advantages:
βββ FFmpeg Solution: At least 160MB (64x larger!)
βββ Pygame Solution: Bloated with incomplete features
βββ ap_ds: 2.5MB perfect solution β
v2.2.0 (January 19, 2026) - Cross-Platform Revolution
Milestone: From single-platform to cross-platform
Major New Features
1. Complete macOS Support
Automatic download and installation of SDL2.framework, SDL2_mixer.framework
Smart .dmg file extraction and framework loading
Maintains extreme lightweight: Only 3.36MB (vs 2.5MB Windows version)
Cross-platform unified API, code requires no modification
2. Enhanced Automatic Dependency Management
Cross-platform intelligent download strategy:
Windows: Automatic .dll download
macOS: Automatic .framework download and extraction
Complete error handling and retry mechanisms
Dependency file local caching to avoid repeated downloads
3. Strengthened Platform Position Statement
Explicit Linux non-support with detailed technical reasoning
Professional rejection strategy and alternative solution suggestions
Focus on serving real user needs (Windows/macOS developers)
Performance & Optimization Size Control Breakthrough:
Windows Version: 2.5MB
βββ SDL2.dll: 2.1MB
βββ SDL2_mixer.dll: 400KB
βββ Python Code: 42KB
macOS Version: 3.36MB
βββ SDL2.framework: 1.82MB
βββ SDL2_mixer.framework: 1.54MB
βββ Python Code: 42KB
Comparison with Traditional Solutions:
βββ FFmpeg Solution: At least 160MB (47x larger than ap_ds!)
βββ Pygame + Parser Libraries: Bloated with incomplete features
βββ ap_ds: 3.36MB complete solution β
Loading Performance Optimization
First load: Automatic dependency download
Subsequent loads: Use local cache
Cross-platform loading logic unified and efficient
Technical Architecture Improvements Cross-Platform Loading System:
def import_sdl2():
"""Intelligent SDL2 library loading (Windows/macOS)"""
if platform == "win32":
# Load .dll
elif platform == "darwin":
# Load .framework
else:
# Explicitly reject unsupported platforms
Enhanced Error Handling
More user-friendly error messages
Detailed troubleshooting suggestions
Intelligent environment detection and problem diagnosis
Documentation & Examples Update
Windows Installation: pip install ap_ds (fully automatic)
macOS Installation: pip install ap_ds (fully automatic, requires network download)
Linux: Clear explanation of non-support reasons and alternatives
Design Philosophy Reiteration
Audio playback only, no editing/transcoding
Serves real needs: Python desktop application developers
Willingness to say no: No Linux support, no AAC support
Market Positioning Upgrade From: "2.5MB Windows Python Audio Solution"
To: "3.36MB Cross-Platform Python Audio Solution"
v2.3.0 (January 31, 2026) - DAP Recording System
Milestone: From playback to memory, introducing audio playback history recording system
DAP (Dvs Audio Playlist) is a major functional extension of the ap_ds library, providing developers with a complete solution for audio playback history recording. This is not a traditional playlist manager, but a lightweight system focused on recording and memory.
Core Characteristics
1. Intelligent Automatic Recording
Seamless integration: Automatically triggered in play_from_file(), play_from_memory()
Precise timing: Records only during actual playback, avoiding misoperations
Complete metadata: Records path, duration, bitrate, channel count, and other key information
2. Lightweight Design Philosophy
Metadata only: No audio data storage, maintaining extremely low memory usage
Intelligent deduplication: Automatically avoids duplicate records of the same file
On-demand persistence: Runtime memory storage, explicit call required for file saving
3. Standardized File Format
Dedicated extension: .ap_ds-dap ensures format recognition
Standard JSON: Easy parsing, editing, and exchange
Format validation: Enforced extension, ensuring data integrity
New API Details
DAP Recording Function List
1. _add_to_dap_recordings(file_path: str) -> None Function: Add audio file metadata to memory record list
Characteristics:
Internal use only (automatically triggered via playback methods)
Automatic audio metadata extraction (duration, bitrate, channel count)
Intelligent deduplication mechanism
Standardized recording format
Usage Example:
# Automatically triggered via playback
lib.play_from_file("song.mp3") # Automatically recorded to DAP
# Log output: Recorded DAP file: song.mp3
2. save_dap_to_json(save_path: str) -> bool Function: Save DAP records from memory to JSON file
Mandatory Requirements:
File extension must be .ap_ds-dap
UTF-8 encoding for multilingual compatibility
Pretty JSON format (2-space indentation)
Return Value:
True: Save successful
False: Save failed (error logged)
Error Handling:
try:
success = lib.save_dap_to_json("history.ap_ds-dap")
except ValueError as e:
print(f"Format error: {e}") # Extension doesn't meet requirements
3. get_dap_recordings() -> List[Dict] Function: Get deep copy of all current DAP records
Data Format:
[
{
"path": "/music/song1.mp3",
"duration": 240,
"bitrate": 320000,
"channels": 2
}
]
Usage Scenarios:
Display playback history statistics
Export to other formats
Custom interface display
4. clear_dap_recordings() -> None Function: Clear all DAP records from memory
Characteristics:
Irreversible operation (unless already saved)
Clear operation logging
Immediate memory release
Technical Architecture Design
Workflow:
User plays audio
Calls play_from_file()
Automatically calls _add_to_dap_recordings()
Extracts metadata via get_audio_metadata_by_path()
Creates standardized record
Adds to _dap_recordings list
Intelligent deduplication check
Stores in memory
User optionally calls save_dap_to_json()
Extension validation
JSON serialization
File saving
Memory Management Design:
class AudioLibrary:
def __init__(self):
# DAP memory storage
self._dap_recordings = [] # List[Dict]
# Approximate memory usage per record:
# path: ~100 bytes
# metadata: ~50 bytes
# total: ~150 bytes/record
Performance Characteristics:
Record operation: O(1) complexity (adding new records)
Deduplication check: O(n) complexity (linear check)
Memory usage: ~1.5MB per 10,000 records
File size: ~2-3MB per 10,000 records (JSON format)
v2.3.1(February 9, 2026) - Documentation Update
Milestone: Improved documentation and minor fixes
Changes:
Updated README.md with better examples and explanations
Minor bug fixes in documentation examples
Improved error messages for common usage scenarios
Enhanced installation instructions for different platforms
v2.3.2 (February 9, 2026) - Linux Support Enhancement
Milestone: Extended Linux support with interactive setup
Major New Features:
1. Interactive Linux Support
Three options for Linux users:
Use system-installed libraries (via package manager)
Specify paths to compiled .so files
Get detailed compilation instructions
Smart platform detection and guidance
Unified API across all platforms
2. Enhanced Cross-Platform Compatibility
Windows: Full auto-download support for SDL2 libraries
macOS: Full auto-download support for SDL2 frameworks
Linux: Interactive setup with user guidance
3. Improved User Experience
Clear platform-specific installation guidance
Better error handling for library loading failures
Enhanced troubleshooting documentation
Technical Implementation:
def import_sdl2():
"""Main function: Import SDL2 libraries with cross-platform support"""
platform = sys.platform
if platform == "win32":
# Windows - auto-download and load .dll
elif platform == "darwin":
# macOS - auto-download and load .framework
elif platform.startswith("linux"):
# Linux - interactive setup with options:
print("Linux SDL2 Library Loading")
print("Options:")
print("1. Use system-installed libraries (if available)")
print("2. Specify path to your compiled .so files")
print("3. Get compilation instructions")
# User interaction and library loading
Market Positioning Upgrade From: "3.36MB Cross-Platform Python Audio Solution"
To: "Complete Cross-Platform Python Audio Solution (Windows, macOS, Linux)"
Performance & Optimization:
Maintains lightweight design across all platforms
Intelligent dependency management for each platform
Consistent API experience regardless of platform
Backward Compatibility:
All existing code continues to work unchanged
New Linux support doesn't affect Windows/macOS users
DAP system fully functional on all platforms
v2.3.3 (February 9, 2026) - Critical Bug Fix & Platform Stabilization
π¨ This is a critical update that fixes a major bug. Previous versions (2.2.0, 2.3.0, 2.3.1, 2.3.2) have been yanked from PyPI due to this issue. Please upgrade immediately.
Critical Fix
Resolved Cross-Platform Crash: Fixed a critical segmentation fault bug that prevented the library from functioning on macOS and Linux. The issue was caused by missing C function prototypes (ctypes argtypes/restype) on non-Windows platforms.
Root Cause: In earlier versions, the platform-specific code only defined essential C function bindings (prototypes) for Windows (win32), causing memory access violations on other operating systems.
Solution: The library now unconditionally defines all necessary C function bindings immediately after loading the SDL2 libraries, regardless of the operating system. This ensures stable and safe calls across Windows, macOS, and Linux.
Enhanced Stability & Integrity
Guaranteed Functionality: The core promiseβpip install ap_ds followed by functional playback and parsingβis now reliably fulfilled on all three major platforms.
Validated Workflow: The existing, user-friendly platform-handling logic (auto-download for Windows/macOS, interactive guidance for Linux) has been fully stabilized and verified end-to-end.
What This Means for You
For All Users: If you are using any version prior to 2.3.4, you are affected. Please run pip install --upgrade ap_ds now.
For Linux/macOS Users: The library will now work correctly. The interactive Linux setup (choosing system libraries, specifying paths, or getting compilation help) functions as intended.
For Windows Users: While you may not have experienced crashes, upgrading is essential to stay on the supported, stable release.
Technical Summary
This patch (2.3.2 β 2.3.4) is a PATCH-level version change under Semantic Versioning, signifying a backward-compatible bug fix that resolves incorrect behavior. The core API, features, and user experience remain unchanged and now operate reliably everywhere.
Maintainer's Note: We sincerely apologize for the disruption. Upholding stability and a professional standard for all users is our top priority. Version 2.3.4 represents that commitment.
v2.3.4 (February 10, 2026) - Linux Intelligent Import System
π This update revolutionizes Linux support with an intelligent, multi-layer import system that dramatically improves user experience.
Intelligent Linux Import System
Four-Layer Fallback Strategy: Implements a sophisticated, progressive library discovery system:
System Library Check: First attempts to use system-installed SDL2 libraries via standard library paths
User Configuration: Checks for user-saved library paths from previous successful configurations
Automatic Installation: Intelligently detects package manager and attempts non-interactive installation
Interactive Guidance: Only presents manual options when all automatic methods fail
Package Manager Detection & Auto-Install:
Ubuntu/Debian: Auto-detects apt-get and installs libsdl2-dev libsdl2-mixer-dev
Fedora: Auto-detects dnf and installs SDL2-devel SDL2_mixer-devel
Arch: Auto-detects pacman and installs sdl2 sdl2_mixer
All installations use non-interactive mode (-y/--noconfirm) for seamless setup
Configuration Persistence & Smart Memory
Automatic Path Saving: User-specified library paths are automatically saved to both:
Environment variables (AP_DS_SDL2_PATH, AP_DS_SDL2_MIXER_PATH)
Persistent config file (~/.config/ap_ds/sdl_paths.conf)
One-Time Setup: Linux users only need to configure paths once; subsequent runs use saved configurations automatically
Configuration Validation: Saved paths are validated before use to ensure libraries are still accessible
Enhanced User Experience
Reduced User Interaction: Most users will experience automatic setup without any manual input
Clear Progress Feedback: Real-time status updates during each layer of the discovery process
Intelligent Fallback: System gracefully degrades through each layer, always providing the next-best option
Technical Implementation Highlights
def import_sdl2():
"""Intelligent multi-layer SDL2 import system"""
if platform.startswith("linux"):
# Layer 1: System library check
if find_system_libraries():
return load_from_system()
# Layer 2: User-configured paths
if check_user_config():
return load_from_user_config()
# Layer 3: Automatic package manager installation
if try_auto_install():
return load_from_newly_installed()
# Layer 4: Interactive guidance (only if all else fails)
return interactive_setup_and_save()
Platform-Specific Improvements
Windows/macOS: Unchanged - continue with seamless auto-download functionality
Linux: Transformed from manual setup to intelligent automatic configuration
All Platforms: Consistent API experience with zero changes to user code
Performance & Stability
Faster First-Time Setup: Linux users experience dramatically reduced setup time
Reduced Error Rates: Intelligent validation prevents common configuration mistakes
Enhanced Reliability: Multi-layer approach ensures maximum compatibility across diverse Linux distributions
What This Means for You
For New Linux Users: Installation is now as simple as Windows/macOS - pip install ap_ds followed by automatic setup in most cases
For Existing Linux Users: Your saved configurations continue to work; new users benefit from the intelligent system
For All Users: The library maintains its lightweight design (still under 4MB) while gaining sophisticated platform intelligence
---
## Final Notes
ap_ds is built on a simple philosophy: **focus on playback and parsing, stay lightweight, and let developers build great applications.**
We welcome feedback, bug reports, and contributions. For questions or issues, please reach out through the official channels.
**Thank you for using ap_ds!**
---