# 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!** ---