Initial commit: ap_ds 音频播放库 (Audio Player By DVS AFS)
This commit is contained in:
@@ -0,0 +1,772 @@
|
||||
# __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",
|
||||
]
|
||||
Reference in New Issue
Block a user