773 lines
38 KiB
Python
773 lines
38 KiB
Python
# __init__.py - Package entry point
|
|
|
|
import os
|
|
import sys
|
|
import warnings
|
|
|
|
try:
|
|
from ._version import __version__
|
|
except ImportError:
|
|
try:
|
|
from _version import __version__
|
|
except ImportError:
|
|
__version__ = "unknown"
|
|
|
|
|
|
# ============================================================
|
|
# Export top-level functions from audio_parser
|
|
# ============================================================
|
|
|
|
try:
|
|
from .audio_parser import (
|
|
batch_get_metadata,
|
|
batch_get_duration,
|
|
batch_get_metadata_by_type,
|
|
get_audio_duration,
|
|
get_audio_metadata,
|
|
)
|
|
except ImportError:
|
|
try:
|
|
from audio_parser import (
|
|
batch_get_metadata,
|
|
batch_get_duration,
|
|
batch_get_metadata_by_type,
|
|
get_audio_duration,
|
|
get_audio_metadata,
|
|
)
|
|
except ImportError:
|
|
# Define as None if audio_parser not available
|
|
batch_get_metadata = None
|
|
batch_get_duration = None
|
|
batch_get_metadata_by_type = None
|
|
get_audio_duration = None
|
|
get_audio_metadata = None
|
|
|
|
def is_full_performance() -> bool:
|
|
"""Check if running in full performance mode."""
|
|
info = _auto_check_runtime()
|
|
return info.get('is_full_performance', False) if info else False
|
|
|
|
def get_runtime_info() -> dict:
|
|
"""Get runtime information dictionary."""
|
|
info = _auto_check_runtime()
|
|
return info.copy() if info else {}
|
|
# ============================================================
|
|
# Banner
|
|
# ============================================================
|
|
|
|
if os.environ.get('AP_DS_HIDE_SUPPORT_PROMPT') != '1':
|
|
print(f"AP_DS © - Audio Library By DVS v{__version__} | https://apds.top")
|
|
|
|
|
|
# ============================================================
|
|
# Runtime Environment Detection
|
|
# ============================================================
|
|
|
|
SUPPRESS_WARNINGS = os.environ.get('AP_DS_SUPPRESS_WARNINGS', '').lower() in ('1', 'true', 'yes', 'on')
|
|
SHOW_CONGRATS = os.environ.get('AP_DS_SHOW_CONGRATS', '').lower() not in ('0', 'false', 'no', 'off')
|
|
_AUTO_CHECK_SKIP = os.environ.get('AP_DS_SKIP_AUTO_CHECK', '1').lower() in ('1', 'true', 'yes', 'on')
|
|
# ============================================================
|
|
# Show Technical Manual (User-Initiated)
|
|
# ============================================================
|
|
|
|
def show_tech_manual() -> None:
|
|
"""
|
|
Display the complete AP_DS 0.0.1a3 Technical Manual.
|
|
|
|
This function prints a comprehensive technical reference including:
|
|
- Library architecture
|
|
- Supported audio formats
|
|
- Core components description
|
|
- API reference
|
|
- Performance tuning
|
|
- Environment variables
|
|
- Cross-platform notes
|
|
- Troubleshooting guide
|
|
|
|
User must call this function explicitly. It will NOT be called automatically.
|
|
|
|
Examples:
|
|
>>> from ap_ds import show_tech_manual
|
|
>>> show_tech_manual()
|
|
"""
|
|
manual = r"""
|
|
╔═══════════════════════════════════════════════════════════════════════════════╗
|
|
║ ║
|
|
║ AP_DS 0.0.1a3 TECHNICAL MANUAL ║
|
|
║ Audio Library By DVS - https://apds.top ║
|
|
║ ║
|
|
╚═══════════════════════════════════════════════════════════════════════════════╝
|
|
|
|
┌───────────────────────────────────────────────────────────────────────────────┐
|
|
│ 1. OVERVIEW │
|
|
└───────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
AP_DS (Audio Playback & Data Service) is a cross-platform, high-performance
|
|
audio library for Python applications. Built on SDL2 and SDL2_mixer, it provides:
|
|
|
|
• Low-latency audio playback
|
|
• Accurate metadata parsing (pure Python, no external dependencies)
|
|
• Smart WAV handling with automatic mode switching
|
|
• DAP (Dvs Audio Playlist) recording with O(1) deduplication
|
|
• Batch metadata extraction with multi-core parallelism
|
|
• Fade in/out controls with position seeking
|
|
• Memory-efficient caching with automatic cleanup
|
|
|
|
┌───────────────────────────────────────────────────────────────────────────────┐
|
|
│ 2. SUPPORTED AUDIO FORMATS │
|
|
└───────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
┌──────────────┬─────────────┬─────────────────────────────────────────┐
|
|
│ Format │ Extension │ Notes │
|
|
├──────────────┼─────────────┼─────────────────────────────────────────┤
|
|
│ MP3 │ .mp3 │ Frame-by-frame scanning, >98% accuracy │
|
|
│ WAV │ .wav │ RIFF chunk parsing, 100% accuracy │
|
|
│ FLAC │ .flac │ STREAMINFO block, 100% accuracy │
|
|
│ OGG Vorbis │ .ogg │ Granule position, 99.99% accuracy │
|
|
│ AAC (ADTS) │ .aac │ ADTS frame parsing, >99% accuracy │
|
|
│ OPUS │ .opus │ libopusfile decode, waveOut playback │
|
|
└──────────────┴─────────────┴─────────────────────────────────────────┘
|
|
|
|
┌───────────────────────────────────────────────────────────────────────────────┐
|
|
│ 2.1 OPUS SUPPORT (NEW in 0.0.1a3) │
|
|
└───────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
AP_DS 0.0.1a3 adds native Opus playback support via libopusfile + winmm waveOut.
|
|
This is a separate playback path from SDL2, automatically selected when the
|
|
audio file is an Opus (.opus) file.
|
|
|
|
Key Features:
|
|
• Automatic detection: Opus files are routed to OpusAudio sub-player
|
|
• AID mapping: Main library AID <-> Opus sub-library AID (1:1)
|
|
• Auto-download: Opus DLLs downloaded from https://dvsyun.top
|
|
• Hash verification: SHA256 verified after download
|
|
• Full control: play / pause / resume / stop / seek / volume / fade
|
|
|
|
Modules:
|
|
• opusplayer.py - OpusAudio class (Opus playback engine)
|
|
• _opusdll.py - DLL loader + auto-download + hash verification
|
|
|
|
OpusAudio class:
|
|
class OpusAudio(frequency=48000, channels=2, volume_pct=80)
|
|
Same API as AudioLibrary for Opus files:
|
|
play_from_file / new_aid / play_from_memory
|
|
pause_audio / play_audio / stop_audio / seek_audio
|
|
set_volume / get_volume
|
|
fadein_music / fadein_music_pos / fadeout_music
|
|
get_audio_metadata / get_audio_duration / batch_*
|
|
|
|
Usage (automatic routing through AudioLibrary):
|
|
from ap_ds import AudioLibrary
|
|
lib = AudioLibrary()
|
|
aid = lib.play_from_file("song.opus") # auto-routed to OpusAudio
|
|
|
|
Direct usage:
|
|
from ap_ds import OpusAudio
|
|
opus = OpusAudio()
|
|
aid = opus.play_from_file("song.opus")
|
|
|
|
Opus DLLs (auto-downloaded from https://dvsyun.top/ap_ds/download/):
|
|
• libopusfile-0.dll (Opus file decoding)
|
|
• libopus-0.dll (Opus codec core)
|
|
• libogg-0.dll (Ogg container)
|
|
• libopusurl-0.dll (Opus URL streaming)
|
|
|
|
┌───────────────────────────────────────────────────────────────────────────────┐
|
|
│ 3. CORE COMPONENTS │
|
|
└───────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
3.1 AudioLibrary (player.py)
|
|
────────────────────────────
|
|
Main class providing all audio playback and management functionality.
|
|
|
|
Methods:
|
|
• play_from_file(file_path, loops=0, start_pos=0.0) -> int
|
|
Play audio directly from file, returns AID
|
|
|
|
• play_from_memory(file_path, loops=0, start_pos=0.0) -> int
|
|
Play audio from memory cache, returns AID
|
|
|
|
• new_aid(file_path) -> int
|
|
Generate AID without playing (preloads to cache)
|
|
|
|
• pause_audio(aid) -> None
|
|
Pause audio playback
|
|
|
|
• stop_audio(aid) -> float
|
|
Stop playback and return played duration
|
|
|
|
• seek_audio(aid, position) -> None
|
|
Seek to specified position in seconds
|
|
|
|
• set_volume(aid, volume) -> bool
|
|
Set volume (0-128)
|
|
|
|
• get_volume(aid) -> int
|
|
Get current volume
|
|
|
|
• fadein_music(aid, loops=-1, ms=0) -> bool
|
|
Fade in music
|
|
|
|
• fadein_music_pos(aid, loops=-1, ms=0, position=0.0) -> bool
|
|
Fade in music from position
|
|
|
|
• fadeout_music(ms=0) -> bool
|
|
Fade out music
|
|
|
|
• clear_memory_cache() -> None
|
|
Clear all cached audio data
|
|
|
|
• save_dap_to_json(save_path) -> bool
|
|
Save DAP recordings to .ap-ds-dap file
|
|
|
|
• get_dap_recordings() -> List[Dict]
|
|
Get current DAP recordings
|
|
|
|
• clear_dap_recordings() -> None
|
|
Clear all DAP recordings
|
|
|
|
|
|
3.2 Metadata Parsers (audio_parser.py)
|
|
──────────────────────────────────────
|
|
Pure-Python parsers for audio metadata extraction.
|
|
|
|
Functions:
|
|
• get_audio_duration(file_path) -> int
|
|
Get duration in seconds
|
|
|
|
• get_audio_metadata(file_path) -> Dict
|
|
Get complete metadata (duration, sample_rate, channels, bitrate)
|
|
|
|
• batch_get_metadata(file_paths, max_workers=None, show_progress=False) -> List[Dict]
|
|
Parse multiple files in parallel
|
|
|
|
• batch_get_duration(file_paths, max_workers=None) -> Dict[str, int]
|
|
Get durations for multiple files
|
|
|
|
• batch_get_metadata_by_type(file_paths, file_type, max_workers=None) -> List[Dict]
|
|
Filter results by format
|
|
|
|
|
|
3.3 SDL2 Loader (_sdl2.py)
|
|
──────────────────────────
|
|
Cross-platform SDL2 library loader with automatic fallback.
|
|
|
|
Loading order (Linux):
|
|
1. Package directory
|
|
2. User config (~/.config/ap_ds/sdl_paths.conf)
|
|
3. System libraries
|
|
4. Auto-install via package manager
|
|
5. Interactive setup
|
|
|
|
Loading order (Windows/macOS):
|
|
1. Package directory
|
|
2. System path
|
|
3. Automatic download from CDN
|
|
|
|
┌───────────────────────────────────────────────────────────────────────────────┐
|
|
│ 4. DAP (Dvs Audio Playlist) SYSTEM │
|
|
└───────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
The DAP system automatically records every audio file that is played or loaded
|
|
through the AudioLibrary. Features:
|
|
|
|
• O(1) Deduplication: Uses Python set for fast duplicate checking
|
|
• Fallback O(n): Linear scan if set deduplication fails
|
|
• Persistent Storage: Save to .ap-ds-dap JSON files
|
|
• Memory Efficient: Stores only metadata, not audio data
|
|
|
|
Record Structure:
|
|
{
|
|
"path": "/path/to/audio.mp3",
|
|
"duration": 240,
|
|
"bitrate": 320000,
|
|
"channels": 2
|
|
}
|
|
|
|
┌───────────────────────────────────────────────────────────────────────────────┐
|
|
│ 5. WAV SMART MODE │
|
|
└───────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
WAV files are automatically handled differently based on duration:
|
|
|
|
┌────────────────────┬─────────────────┬────────────────────────────────┐
|
|
│ Duration │ Mode │ SDL2 API Used │
|
|
├────────────────────┼─────────────────┼────────────────────────────────┤
|
|
│ < WAV_THRESHOLD │ Sound Effect │ Mix_PlayChannel (memory) │
|
|
│ >= WAV_THRESHOLD │ Music │ Mix_PlayMusic (streaming) │
|
|
└────────────────────┴─────────────────┴────────────────────────────────┘
|
|
|
|
Default threshold: 6 seconds
|
|
Configure via: AP_DS_WAV_THRESHOLD environment variable
|
|
|
|
┌───────────────────────────────────────────────────────────────────────────────┐
|
|
│ 6. ENVIRONMENT VARIABLES │
|
|
└───────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
AP_DS_WAV_THRESHOLD
|
|
─────────────────
|
|
WAV mode switching threshold in seconds.
|
|
Default: 6
|
|
Range: 0-29 (values >=30 reset to 6)
|
|
Example: AP_DS_WAV_THRESHOLD=10
|
|
|
|
AP_DS_SUPPRESS_WARNINGS
|
|
─────────────────────
|
|
Suppress GIL warning messages.
|
|
Default: 0 (warnings enabled)
|
|
Values: 1, true, yes, on
|
|
Example: AP_DS_SUPPRESS_WARNINGS=1
|
|
|
|
AP_DS_SHOW_CONGRATS
|
|
─────────────────
|
|
Show congratulations message when GIL is disabled.
|
|
Default: 1 (show)
|
|
Values: 0, false, no, off (to hide)
|
|
Example: AP_DS_SHOW_CONGRATS=0
|
|
|
|
AP_DS_SKIP_AUTO_CHECK
|
|
───────────────────
|
|
Skip runtime self-check on import.
|
|
Default: 1 (skip)
|
|
Values: 1, true, yes, on (to skip)
|
|
Example: AP_DS_SKIP_AUTO_CHECK=0 # Show self-check
|
|
|
|
AP_DS_HIDE_SUPPORT_PROMPT
|
|
──────────────────────
|
|
Hide the support prompt banner.
|
|
Default: 0 (show banner)
|
|
Values: 1
|
|
Example: AP_DS_HIDE_SUPPORT_PROMPT=1
|
|
|
|
┌───────────────────────────────────────────────────────────────────────────────┐
|
|
│ 7. PERFORMANCE OPTIMIZATION │
|
|
└───────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
7.1 Free-Threading Support
|
|
──────────────────────────
|
|
AP_DS 0.0.1a3 is optimized for Python 3.15t (free-threading mode).
|
|
When running with GIL disabled, performance improves significantly:
|
|
|
|
• Batch metadata parsing uses ProcessPoolExecutor
|
|
• Multiple audio operations can run in parallel
|
|
• Lower latency for concurrent playback
|
|
|
|
To enable free-threading:
|
|
Download Python 3.15t from:
|
|
https://mirrors.huaweicloud.com/python/3.15.0/python-3.15.0b4t-amd64.zip
|
|
|
|
|
|
7.2 Batch Processing
|
|
────────────────────
|
|
Use batch APIs for processing multiple files:
|
|
|
|
metadata = batch_get_metadata(directory, max_workers=4, show_progress=True)
|
|
|
|
Workers default to CPU count. Adjust based on:
|
|
• I/O bound: Use more workers (CPU count * 2)
|
|
• CPU bound: Use CPU count (or CPU count - 1 on 4+ cores)
|
|
|
|
|
|
7.3 Memory Management
|
|
─────────────────────
|
|
Audio data is cached in memory. To manage memory:
|
|
|
|
• Use new_aid() to preload without playing
|
|
• Call clear_memory_cache() periodically for long-running apps
|
|
• WAV files under 6 seconds are cached as Mix_Chunk in memory
|
|
• WAV files over 6 seconds stream via Mix_Music
|
|
|
|
┌───────────────────────────────────────────────────────────────────────────────┐
|
|
│ 8. CROSS-PLATFORM NOTES │
|
|
└───────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
8.1 Windows
|
|
───────────
|
|
• DLLs automatically downloaded from CDN
|
|
• SDL2.dll and SDL2_mixer.dll placed in package directory
|
|
• os.add_dll_directory() used for modern Windows
|
|
• PATH environment variable updated automatically
|
|
|
|
8.2 macOS
|
|
─────────
|
|
• Frameworks downloaded as DMG and auto-extracted
|
|
• SDL2.framework and SDL2_mixer.framework
|
|
• DYLD_FRAMEWORK_PATH updated automatically
|
|
• Supports both Intel (x64) and Apple Silicon (ARM)
|
|
|
|
8.3 Linux
|
|
─────────
|
|
• No automatic download (distribution compatibility)
|
|
• Uses system package manager when possible
|
|
• Manual installation instructions provided
|
|
• Supports: Ubuntu/Debian (apt), Fedora (dnf), Arch (pacman)
|
|
• LD_LIBRARY_PATH updated when loading from package
|
|
|
|
┌───────────────────────────────────────────────────────────────────────────────┐
|
|
│ 9. TROUBLESHOOTING │
|
|
└───────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
9.1 "Failed to load music file"
|
|
──────────────────────────────
|
|
• Verify file exists and is readable
|
|
• Check if SDL2_mixer supports the format
|
|
• For WAV files > 6s, ensure file is valid PCM
|
|
|
|
9.2 "SDL initialization failed"
|
|
────────────────────────────────
|
|
• SDL2 library not loaded properly
|
|
• On Windows, check antivirus isn't blocking DLLs
|
|
• On Linux, install SDL2 development packages
|
|
|
|
9.3 "audio_parser not available"
|
|
──────────────────────────────────
|
|
• audio_parser.py missing from package
|
|
• Reinstall ap_ds: pip install --upgrade ap_ds
|
|
|
|
9.4 "GIL is enabled" warning
|
|
──────────────────────────────
|
|
• Running on standard Python (non-free-threading)
|
|
• Upgrade to Python 3.15t for full performance
|
|
• Or suppress with AP_DS_SUPPRESS_WARNINGS=1
|
|
|
|
9.5 DAP recordings not saving
|
|
──────────────────────────────
|
|
• Check file extension: must be .ap-ds-dap
|
|
• Verify write permissions on save location
|
|
• Ensure at least one file was played/loaded
|
|
|
|
┌───────────────────────────────────────────────────────────────────────────────┐
|
|
│ 10. API REFERENCE │
|
|
└───────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
10.1 AudioLibrary Class
|
|
───────────────────────
|
|
class AudioLibrary(frequency=44100, format=MIX_DEFAULT_FORMAT,
|
|
channels=2, chunksize=2048)
|
|
|
|
参数:
|
|
frequency: Audio sample rate (Hz)
|
|
format: Audio format (MIX_DEFAULT_FORMAT)
|
|
channels: Number of channels (1=mono, 2=stereo)
|
|
chunksize: Audio buffer size
|
|
|
|
10.2 AID (Audio ID) System
|
|
──────────────────────────
|
|
Every audio playback/load returns a unique AID.
|
|
Use AID to control playback:
|
|
aid = lib.play_from_file("song.mp3")
|
|
lib.pause_audio(aid)
|
|
lib.seek_audio(aid, 30.0)
|
|
lib.stop_audio(aid)
|
|
|
|
10.3 Channel vs Music
|
|
─────────────────────
|
|
Sound Effect Mode (Mix_PlayChannel):
|
|
• Up to 8 simultaneous sounds
|
|
• Loaded into memory (Mix_Chunk)
|
|
• Low latency
|
|
• Best for short sounds (<6s)
|
|
|
|
Music Mode (Mix_PlayMusic):
|
|
• One at a time
|
|
• Streamed from disk (Mix_Music)
|
|
• Supports seeking and fading
|
|
• Best for long tracks (>=6s)
|
|
|
|
┌───────────────────────────────────────────────────────────────────────────────┐
|
|
│ 10.4 Opus Error Codes (NEW in 0.0.1a3) │
|
|
└───────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
Opus-specific error codes (2000+):
|
|
┌──────────┬────────────────────────────────────────────┬──────────────────────────────────┐
|
|
│ Code │ Name │ Description │
|
|
├──────────┼────────────────────────────────────────────┼──────────────────────────────────┤
|
|
│ 2001 │ AP_DS_ERR_OPUS_LIB_LOAD_FAILED │ libopusfile-0.dll load failed │
|
|
│ 2002 │ AP_DS_ERR_OPUS_DLL_DEPENDENCY │ DLL dependency missing │
|
|
│ 2003 │ AP_DS_ERR_OPUS_OPEN_FAILED │ Opus file open failed │
|
|
│ 2004 │ AP_DS_ERR_OPUS_HEADER_CORRUPT │ OpusHead header corrupt │
|
|
│ 2005 │ AP_DS_ERR_OPUS_TAGS_PARSE_FAILED │ OpusTags tag parse failed │
|
|
│ 2006 │ AP_DS_ERR_OPUS_DECODE_FAILED │ Opus decode failed │
|
|
│ 2007 │ AP_DS_ERR_OPUS_SEEK_FAILED │ Opus seek failed │
|
|
│ 2008 │ AP_DS_ERR_OPUS_BITRATE_UNAVAILABLE │ Bitrate unavailable │
|
|
│ 2009 │ AP_DS_ERR_OPUS_NOT_SEEKABLE │ Stream not seekable │
|
|
│ 2010 │ AP_DS_ERR_OPUS_CHANNEL_INVALID │ Invalid channel count │
|
|
└──────────┴────────────────────────────────────────────┴──────────────────────────────────┘
|
|
|
|
┌───────────────────────────────────────────────────────────────────────────────┐
|
|
│ 11. VERSION HISTORY │
|
|
└───────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
Version 0.0.1a3 (Current)
|
|
────────────────────────
|
|
• Opus playback support (libopusfile + waveOut)
|
|
• OpusAudio class with automatic routing
|
|
• Opus DLL auto-download + SHA256 verification
|
|
• Opus-specific error codes (2001-2010)
|
|
• Opus batch parsing
|
|
• Opus vs original format distinction
|
|
|
|
Version 0.0.1a1
|
|
─────────────
|
|
• Python 3.15t free-threading support
|
|
• Lazy imports for Python 3.15+
|
|
• DAP O(1) deduplication
|
|
• Batch metadata extraction
|
|
• Smart WAV mode switching
|
|
• Audio metadata parsers (pure Python)
|
|
• Cross-platform SDL2 loader
|
|
|
|
Version 3.x
|
|
───────────
|
|
• Initial SDL2 bindings
|
|
• Audio playback and control
|
|
• Volume control
|
|
• Basic metadata support
|
|
|
|
┌───────────────────────────────────────────────────────────────────────────────┐
|
|
│ 12. CONTRIBUTING & SUPPORT │
|
|
└───────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
Website: https://apds.top
|
|
Source Code: https://gitcode.com/dvsxt/ap_ds
|
|
Documentation: https://apds.top/docs
|
|
Issues: https://gitcode.com/dvsxt/ap_ds/issues
|
|
License: MIT
|
|
|
|
Author: DVS
|
|
Email: support@apds.top
|
|
|
|
╔═══════════════════════════════════════════════════════════════════════════════╗
|
|
║ END OF MANUAL ║
|
|
║ AP_DS 0.0.1a3 - August 2026 ║
|
|
║ ║
|
|
║ 📖 For detailed Markdown documentation, visit: ║
|
|
║ https://apds.top ║
|
|
║ https://gitcode.com/dvsxt/ap_ds ║
|
|
║ ║
|
|
║ 📝 View source code: ║
|
|
║ https://gitcode.com/dvsxt/ap_ds ║
|
|
║ ║
|
|
║ 💬 Report issues: ║
|
|
║ https://gitcode.com/dvsxt/ap_ds/issues ║
|
|
║ ║
|
|
║ 💡 Quick start: ║
|
|
║ from ap_ds import AudioLibrary ║
|
|
║ lib = AudioLibrary() ║
|
|
║ aid = lib.play_from_file("music.mp3") ║
|
|
╚═══════════════════════════════════════════════════════════════════════════════╝
|
|
"""
|
|
print(manual)
|
|
def _check_runtime_mode():
|
|
"""
|
|
Check GIL status and notify the user accordingly.
|
|
|
|
Returns:
|
|
bool: True if GIL is enabled, False if disabled (free-threading)
|
|
"""
|
|
try:
|
|
gil_enabled = sys._is_gil_enabled()
|
|
except AttributeError:
|
|
gil_enabled = True
|
|
|
|
if not gil_enabled:
|
|
if SHOW_CONGRATS:
|
|
print("🎉 ap_ds: GIL disabled (free-threading mode)")
|
|
else:
|
|
if not SUPPRESS_WARNINGS:
|
|
warnings.warn(
|
|
"⚠️ ap_ds: GIL is enabled (multi-core parallelism limited).\n"
|
|
" For full performance, upgrade to Python 3.15t:\n"
|
|
" https://mirrors.huaweicloud.com/python/3.15.0/python-3.15.0b4t-amd64.zip\n"
|
|
" To suppress this warning, set AP_DS_SUPPRESS_WARNINGS=1",
|
|
RuntimeWarning,
|
|
stacklevel=2
|
|
)
|
|
return gil_enabled
|
|
def _auto_check_runtime():
|
|
"""
|
|
Automatic runtime self-check on library import.
|
|
|
|
Prints diagnostic information including:
|
|
- Python version
|
|
- GIL status
|
|
- Profiling availability
|
|
- Performance mode
|
|
- CPU cores
|
|
- Platform
|
|
- Library info (name, version, install path, website, author)
|
|
|
|
Can be disabled by setting environment variable:
|
|
AP_DS_SKIP_AUTO_CHECK=1
|
|
|
|
Returns:
|
|
dict: Runtime information dictionary
|
|
"""
|
|
if _AUTO_CHECK_SKIP:
|
|
return None
|
|
|
|
print("\n" + "=" * 60)
|
|
print("🔍 ap_ds Runtime Self-Check")
|
|
print("=" * 60)
|
|
|
|
# Library Info
|
|
print(f"📚 Library: AP_DS (Audio Library By DVS)")
|
|
print(f"📌 Version: {__version__}")
|
|
print(f"📂 Install Path: {os.path.dirname(os.path.abspath(__file__))}")
|
|
print(f"🌐 Website: https://apds.top")
|
|
print(f"📦 PyPI: https://pypi.org/project/ap-ds/")
|
|
print(f"📦 Mirror: https://pypi.tuna.tsinghua.edu.cn/simple/ap-ds/")
|
|
print()
|
|
print("📥 Installation:")
|
|
print(" pip install ap-ds==0.0.1a3")
|
|
print(" pip install ap-ds==0.0.1a3 -i https://pypi.tuna.tsinghua.edu.cn/simple")
|
|
print(" pip install /path/to/ap-ds-0.0.1a3-py3-none-any.whl")
|
|
print(f"👤 Author: DVS")
|
|
print()
|
|
print("📖 Description:")
|
|
print(" AP_DS (Audio Playback & Data Service) is a cross-platform audio")
|
|
print(" library built on SDL2 and SDL2_mixer, designed for Python applications")
|
|
print(" requiring high-performance audio playback and metadata management.")
|
|
print()
|
|
print(" Core Features:")
|
|
print(" • Audio Playback: MP3, WAV, FLAC, OGG, AAC, and more")
|
|
print(" • Smart WAV Handling: Auto-switch between music/sound effect mode")
|
|
print(" • Metadata Parsing: Duration, sample rate, channels, bitrate")
|
|
print(" • DAP Recording: O(1) deduplication playlist generation")
|
|
print(" • Batch Processing: Multi-core parallel metadata extraction")
|
|
print(" • Fade Control: Fade in/out with position seeking support")
|
|
print(" • Memory Management: Efficient caching with automatic cleanup")
|
|
print()
|
|
print(" Performance:")
|
|
print(" • Native SDL2 bindings with zero-copy audio processing")
|
|
print(" • Free-threading support (Python 3.15t) for maximum parallelism")
|
|
print(" • ProcessPoolExecutor for CPU-bound batch operations")
|
|
print()
|
|
print(" Platform Support:")
|
|
print(" • Windows (x64) • macOS (x64/ARM) • Linux (x64/ARM)")
|
|
print()
|
|
print(" Documentation: https://apds.top/docs")
|
|
print(" Source Code: https://gitcode.com/dvsxt/ap_ds")
|
|
print(" License: DVS Audio Library (ap_ds) Open Source License Version 2.0")
|
|
print()
|
|
print(f"🐍 Python: {sys.version.split()[0]} ({sys.implementation.name})")
|
|
|
|
try:
|
|
gil_enabled = sys._is_gil_enabled()
|
|
print(f"🔒 GIL: {'Enabled' if gil_enabled else 'Disabled (Free-Threading)! 🎉'}")
|
|
except AttributeError:
|
|
gil_enabled = True
|
|
print(f"🔒 GIL: Unknown (pre-3.14, assumed Enabled)")
|
|
|
|
try:
|
|
import profiling
|
|
has_profiling = True
|
|
print(f"📊 Profiling: Available (Python 3.15+)")
|
|
except ImportError:
|
|
has_profiling = False
|
|
print(f"📊 Profiling: Not available (requires Python 3.15+)")
|
|
|
|
is_full = has_profiling and not gil_enabled
|
|
print(f"🚀 Full Performance Mode: {'✅ YES! (3.15t)' if is_full else '❌ No (degraded mode)'}")
|
|
|
|
print(f"💻 CPU Cores: {os.cpu_count() or 0}")
|
|
print(f"🖥️ Platform: {sys.platform}")
|
|
print("=" * 60)
|
|
|
|
if not is_full:
|
|
print("💡 Tip: Upgrade to Python 3.15t for full performance:")
|
|
print(" https://mirrors.huaweicloud.com/python/3.15.0/python-3.15.0b4t-amd64.zip")
|
|
print(" To suppress this auto-check, set AP_DS_SKIP_AUTO_CHECK=1")
|
|
else:
|
|
print("🎉 You're running in full performance mode! Enjoy!")
|
|
|
|
print("=" * 60 + "\n")
|
|
|
|
return {
|
|
"library_name": "AP_DS",
|
|
"library_version": __version__,
|
|
"library_install_path": os.path.dirname(os.path.abspath(__file__)),
|
|
"library_website": "https://apds.top",
|
|
"library_author": "DVS",
|
|
"python_version": sys.version.split()[0],
|
|
"gil_enabled": gil_enabled,
|
|
"has_profiling": has_profiling,
|
|
"is_full_performance": is_full,
|
|
"cpu_count": os.cpu_count() or 0,
|
|
"platform": sys.platform,
|
|
}
|
|
# ============================================================
|
|
# Runtime Self-Check on Import
|
|
# ============================================================
|
|
|
|
_RUNTIME_CHECKED = False
|
|
|
|
def ensure_runtime_checked():
|
|
"""Ensure runtime check is performed only once."""
|
|
global _RUNTIME_CHECKED
|
|
if not _RUNTIME_CHECKED:
|
|
_check_runtime_mode()
|
|
_RUNTIME_CHECKED = True
|
|
|
|
ensure_runtime_checked()
|
|
|
|
# Execute auto self-check on import (user can call again later)
|
|
_auto_check_runtime()
|
|
|
|
|
|
# ============================================================
|
|
# Import Player Module (AudioLibrary and all core functions)
|
|
# ============================================================
|
|
|
|
try:
|
|
from .player import *
|
|
except ImportError:
|
|
from player import *
|
|
|
|
# ============================================================
|
|
# Opus Support (opusplayer.py)
|
|
# ============================================================
|
|
try:
|
|
from .opusplayer import OpusAudio
|
|
except ImportError:
|
|
try:
|
|
from opusplayer import OpusAudio
|
|
except ImportError:
|
|
OpusAudio = None
|
|
|
|
# ============================================================
|
|
# Export Self-Check Functions (users can call manually)
|
|
# ============================================================
|
|
|
|
try:
|
|
# Try direct assignment first (functions already defined in this module)
|
|
auto_check_runtime = _auto_check_runtime
|
|
check_runtime_mode = _check_runtime_mode
|
|
except Exception:
|
|
# Fallback: import from current package
|
|
try:
|
|
from . import _auto_check_runtime as auto_check_runtime
|
|
from . import _check_runtime_mode as check_runtime_mode
|
|
except Exception:
|
|
# Final fallback: define as None
|
|
auto_check_runtime = None
|
|
check_runtime_mode = None
|
|
|
|
# ============================================================
|
|
# Public API
|
|
# ============================================================
|
|
# __init__.py
|
|
__all__ = [
|
|
"__version__",
|
|
"AudioLibrary",
|
|
"OpusAudio",
|
|
"get_audio_duration",
|
|
"get_audio_metadata",
|
|
"batch_get_metadata",
|
|
"batch_get_duration",
|
|
"batch_get_metadata_by_type",
|
|
"auto_check_runtime",
|
|
"check_runtime_mode",
|
|
"show_tech_manual",
|
|
]
|