Metadata-Version: 2.4
Name: ap-ds-afs
Version: 0.0.1a1
Summary: Audio Player By DVS AFS - Audio processing and playback with Opus native support
Home-page: https://apds.top
Author: DVS
Author-email: me@dvsyun.top
License: Custom Open Source License
Project-URL: Documentation, https://apds.top
Project-URL: License Info, https://apds.top
Project-URL: Source Code, https://gitcode.com/dvsxt/ap_ds
Keywords: audio music player playback opus sdl2 dvs afs all-format-support
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: Other/Proprietary License
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Multimedia :: Sound/Audio
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE.md
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: license-file
Dynamic: project-url
Dynamic: requires-python
Dynamic: summary

# 🎉 ap_ds AFS 0.0.1-AFS Pre-release — The Permanent Home of Opus Support

⚠️ **Important:** 0.0.1-AFS is a **pre-release test version** for feedback collection and bug reporting. The first stable release **1.0.0** is planned for **September 2026**.

This is the first release of the **AFS (All Format Support)** branch — a standalone fork of ap_ds ecosystem built specifically for **Opus** and all future new formats, with **permanent support commitment**.

If you encounter any issues, please contact us immediately:

📧 **Primary:** me@dvsyun.top
📧 **Backup:** dvs6666@163.com
⏱️ **We guarantee:** Fix within 3 business days

Your feedback is crucial! Together, let's polish Opus support to perfection.

> "We don't just support a new format — we open the door to higher quality, smaller size, and greater freedom." — DVS Development Team, August 2026

---

## 📦 Installation

### Install the Package

```bash
# AFS pre-release (includes Opus, for testing feedback)
pip install ap-ds-afs==0.0.1a1

# AFS stable release (coming September 2026)
pip install ap-ds-afs==1.0.0
```

### Import — Same as Always!

**No matter which package you installed** (`ap-ds` or `ap-ds-afs`), the import is **exactly the same**:

```python
from ap_ds import AudioLibrary
```

✅ Zero migration cost — just change the package name in `requirements.txt`
✅ No code changes needed — your existing code works as-is

### 🛡️ Foolproof Design — Conflict Detection

If a user accidentally installs **both** `ap-ds` and `ap-ds-afs` simultaneously, the library detects the conflict and **exits immediately** with a clear message:

```python
>>> import ap_ds
Checking for package conflicts...
WARNING: Package conflict detected!
The following packages exist simultaneously:
  - ap-ds and ap-ds-afs
Please uninstall one of them.
# Python process exits directly 💀
```

This is **not a bug** — it's a **foolproof design** to prevent hard-to-debug import issues caused by conflicting packages.

---

## 🚀 Quick Start Guide

### Basic Audio Playback

```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.5s
lib.set_volume(aid, 80)       # Set volume (0-128)

# Stop and get elapsed time
elapsed = lib.stop_audio(aid)
print(f"Played {elapsed:.2f} seconds")
```

### Playing Opus Files (via AudioLibrary — Recommended)

```python
from ap_ds import AudioLibrary

lib = AudioLibrary()
aid = lib.play_from_file("song.opus")  # Auto-routed to Opus engine

# All control methods are identical
lib.pause_audio(aid)
lib.seek_audio(aid, 30.0)
lib.set_volume(aid, 80)
lib.stop_audio(aid)
```

### Playing Opus Files (Directly Using OpusAudio)

```python
from ap_ds import OpusAudio

opus = OpusAudio()
aid = opus.play_from_file("song.opus")
opus.pause_audio(aid)
opus.seek_audio(aid, 30.0)
opus.stop_audio(aid)
```

### Getting Audio Metadata

```python
from ap_ds import get_audio_metadata

meta = get_audio_metadata("song.opus")
print(meta["duration"])       # 265
print(meta["sample_rate"])    # 48000
print(meta["channels"])       # 2
print(meta["bitrate"])        # 105351
```

### Batch Parsing (Parallel Processing)

```python
from ap_ds import batch_get_metadata

# Parse 120 MP3s in just 0.33 seconds!
results = batch_get_metadata("/music/playlist/", max_workers=8)

for meta in results:
    print(f"{meta['path']}: {meta['duration']}s, {meta['bitrate']}bps")
```

**⚠️ Windows Users:** You MUST protect your entry point with `if __name__ == "__main__"`:

```python
from ap_ds import batch_get_metadata

def main():
    results = batch_get_metadata("/music/", max_workers=4)
    print(f"Parsed {len(results)} files")

if __name__ == "__main__":
    main()
```

### DAP Playlist System

```python
# Files are recorded automatically into DAP (DVS Audio Playlist)
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 as JSON
lib.save_dap_to_json("my_playlist.ap-ds-dap")
```

DAP stores only metadata (path, duration, bitrate, channels), not audio data. Each record takes approximately 150 bytes of memory.

---

## 📢 A Letter to All Audio Developers

Friends, colleagues, music lovers, and everyone who has ever stayed up late wrestling with audio formats:

Today, we announce — **ap_ds AFS 0.0.1-AFS** is officially released! The **AFS (All Format Support)** branch makes its debut, providing **permanent support** for the Opus audio format for the first time!

But before excitement takes over, we must be honest with you:

**This is a pre-release version.**

What does that mean? It means:

✅ All core features are implemented and tested
✅ 229 Opus-specific tests all pass
✅ Cross-platform (Windows/Linux/macOS) playback verified
⚠️ Some edge-case bugs may still exist that we haven't found
⚠️ We need real users to test in diverse environments

So we're giving this version to **you** — our users — to help us test.

> **"AFS is the permanent home of Opus and all future new formats."**

This is part of ap_ds's dual-track strategy. We'll explain in detail in the following sections.

---

## 🚨 Important Notes on Version 0.0.1-AFS Positioning

### 1. This is a Pre-release

0.0.1-AFS is **not** an LTS or final stable version. It is a **pre-release** aimed at:

- Collecting real-world usage feedback
- Discovering edge-case bugs not covered by tests
- Verifying cross-platform compatibility
- Gathering data for the 1.0.0 stable release

### 2. AFS Branch — The Permanent Home of Opus

This is a critical statement:

**The AFS branch is the permanent home for Opus and all future new formats.**

Unlike the mainline (`ap-ds` 4.x), the AFS branch will **permanently retain** Opus support and continuously add new formats.

| Version | Opus Support | Description |
|---------|-------------|-------------|
| 0.0.1-AFS | ✅ Yes | First AFS pre-release |
| 1.0.0 (Sep 2026) | ✅ Yes | First AFS stable release |
| Future AFS | ✅ Yes | Permanent support |
| Mainline 4.2.0+ | ❌ No | Returns to lightweight positioning |

**Why?**

Because ap_ds mainline's core promise is **2.5MB lightweight**. Opus support (including DLLs) pushes the size to ~3.87MB. Mainline will remove Opus to return to 2.5MB. The AFS branch is specifically designed to carry Opus and future formats, at ~2.8-3.5MB.

So if you need Opus support:

- **Short-term testing:** Use 0.0.1-AFS pre-release
- **Long-term use:** Use AFS branch (`pip install ap-ds-afs`), with 1.0.0 stable coming in September
- Both packages use **identical imports** (`from ap_ds import AudioLibrary`) — zero migration cost

### 3. Bug Reporting & Fix Commitment

If you find any issues with 0.0.1-AFS:

📧 me@dvsyun.top
📧 dvs6666@163.com (CC both for delivery guarantee)

**We promise:**
- Fix within **3 business days**
- Patch releases will be published promptly

**When reporting, please provide:**
- OS and version
- Python version (`python --version`)
- Full error message (if any)
- Reproduction steps
- Audio file sample (if possible)

Every piece of feedback helps us build a better ap_ds. 🙏

---

## 🤔 Why Opus? — The Technical Imperative

### 1. Quality & Compression Ceiling

Opus is an open audio codec jointly developed by the Xiph.Org Foundation and IETF, combining SILK (speech) and CELT (general audio) algorithms with adaptive bitrate from 6 kbps to 510 kbps. This means:

- At low bitrates (<32 kbps), Opus voice clarity far exceeds MP3 and AAC
- At medium-high bitrates (64-128 kbps), Opus quality matches or exceeds MP3 at 320kbps
- Ultra-low latency (as low as 5ms), ideal for real-time communication and gaming

### 2. Open Source & Freedom — A Philosophical Fit

Opus uses a BSD-like license with **no patent restrictions**, completely free. This aligns perfectly with ap_ds's commitment to openness, freedom, and zero burden.

### 3. Mature Ecosystem & Clear Demand

Opus is widely used in:
- **WebRTC** (real-time audio/video communication)
- **Discord, WhatsApp, Signal** and other instant messaging apps
- **Game engines** (Unity, Unreal both support Opus)
- **Audio streaming** (broadcasting, podcasting)
- **Embedded devices** (low power, high compression)

As more audio content is published in Opus format, ap_ds as a general-purpose audio library must respond to this trend.

### 4. Paving the Way for the AFS Branch

Opus is the first member of the AFS (All Format Support) branch. Through the 0.0.1-AFS pre-release, we validate cross-platform Opus playback solutions and accumulate experience for the 1.0.0 stable release.

---

## 😅 Why Didn't We Support Opus Before? — The Upstream Dependency Story

This is a great question. Honestly, we've wanted to support Opus since ap_ds v1.0. But the reality is:

ap_ds has always relied on **SDL2 and SDL2_mixer** for audio playback.

SDL2 is an excellent cross-platform multimedia library that handles audio device abstraction, mixing, and buffering across Windows, macOS, and Linux. SDL2_mixer supports MP3, WAV, OGG, FLAC and other formats out of the box.

But the problem is — **SDL2_mixer's Opus support was never stable enough.**

| Platform | Issue |
|----------|-------|
| Windows | Official SDL2_mixer Windows binaries often lack Opus support or have incomplete compile flags, causing `Mix_LoadMUS` to return NULL for `.opus` files |
| macOS | SDL2_mixer Framework builds frequently have version mismatches and `libopusfile`/`libogg` dependency issues, causing runtime crashes |
| Linux | SDL2_mixer depends on system-installed `libopusfile-dev`, but package names and versions vary widely across distributions |
| API Inconsistency | Even when Opus loads, SDL2_mixer's metadata extraction (duration, bitrate, etc.) often returns 0 or errors |

We tried multiple approaches:

- Compiling our own Opus-enabled SDL2_mixer binaries → Bloated, high maintenance cost
- Forcing users to install `libopusfile-dev` on Linux → Poor UX, and Windows/macOS issues remained
- Waiting for upstream SDL2_mixer fixes across multiple versions → Issues persisted

**Conclusion:** SDL2_mixer's upstream support was insufficient to provide stable Opus playback.

Therefore, before AFS, we made a difficult decision — **temporarily not support Opus** to avoid giving users an unstable experience.

### How Does 0.0.1-AFS Solve This?

**Because SDL2 doesn't work, we decided to not use SDL2 at all!**

In the AFS branch, we completely bypass SDL2 and SDL2_mixer, building a **dedicated playback pipeline** for Opus:

```
User passes .opus file
       ↓
  Detects .opus extension
       ↓
  libopusfile decodes
       ↓
  Cross-platform audio output engine
   ├── Windows → winmm waveOut
   ├── Linux   → ALSA (libasound.so)
   └── macOS   → Core Audio AudioQueue
       ↓
  Audio output to speakers
```

This pipeline is **completely independent of SDL2**, free from SDL2_mixer's limitations.

Meanwhile, Windows users don't need to hunt for DLLs — ap_ds automatically downloads the required four DLLs (`libopusfile-0.dll`, `libopus-0.dll`, `libogg-0.dll`, `libopusurl-0.dll`) on first run with **SHA256 hash verification** ensuring file integrity.

This is why AFS can support Opus, and why we couldn't before. It's not that we didn't want to — we had to find a reliable, stable, truly cross-platform solution. Now we have one.

---

## 🧬 Technical Deep Dive — What We Actually Did

### 1. New Modules & Architecture

To integrate Opus support without affecting mainline stability, we carefully designed the project structure:

| File | Responsibility | Description |
|------|---------------|-------------|
| `opusplayer.py` | Opus playback core | `OpusAudio` class — fully independent of SDL2, encapsulates all Opus playback, control, metadata and batch APIs |
| `_opusdll.py` | Opus library loader | Cross-platform loading (Windows auto-download, Linux/macOS system detection + install guide), unified libopusfile client |
| `player.py` (modified) | Opus routing integration | `AudioLibrary` auto-detects `.opus` files and forwards to `OpusAudio` sub-player, fully transparent playback |
| `__init__.py` (modified) | Export OpusAudio | Users can use `from ap_ds import OpusAudio` directly or seamlessly through `AudioLibrary` |

**Key Design: AID 1:1 Mapping**

When a user plays via `AudioLibrary.play_from_file("song.opus")`, the library internally creates an `OpusAudio` instance and generates a sub-AID, then maps the main library AID to the sub-library AID via a dictionary. All subsequent controls (pause, resume, volume, seek) route correctly to the Opus engine, completely transparent to user code.

```python
# User code — exactly the same as before!
from ap_ds import AudioLibrary

lib = AudioLibrary()
aid = lib.play_from_file("song.opus")  # Auto-routed to Opus engine
lib.pause_audio(aid)                   # Auto-routed to Opus engine
lib.seek_audio(aid, 30.0)              # Auto-routed to Opus engine
lib.stop_audio(aid)                    # Auto-routed to Opus engine
```

**Fully transparent, zero learning curve.**

### 2. Cross-Platform Playback Backends — Three Platform Engines Rewritten for Opus

Opus playback cannot rely on SDL2, so we decided to completely bypass SDL2 and use native OS audio APIs directly with `libopusfile` decoding.

| Platform | Playback Solution | Tech Stack |
|----------|------------------|------------|
| **Windows** | winmm waveOut | libopusfile decode → waveOutWrite multi-buffer (4 buffers, 50ms/block) |
| **Linux** | ALSA | libasound.so.2 → snd_pcm_open → snd_pcm_writei (direct PCM output) |
| **macOS** | Core Audio AudioQueue | Apple official C API → AudioQueue callback fill (consistent with official examples) |

**Platform Implementation Details:**

**Windows** (`_play_worker_windows`):
- Uses `waveOutOpen` to open default audio device
- Uses `CreateEventW` + `WaitForSingleObject` for buffer completion synchronization
- 4 buffers rotating to eliminate stuttering
- `WAVEHDR` structure with `c_void_p` for 64-bit compatibility

**Linux** (`_play_worker_linux`):
- Uses `snd_pcm_open` with "default" device
- Uses `snd_pcm_set_params` for PCM parameters (S16_LE, interleaved mode)
- Uses `snd_pcm_writei` for PCM data write
- On `-EPIPE` (buffer underrun), calls `snd_pcm_recover` for auto-recovery

**macOS** (`_play_worker_macos`):
- Uses `AudioQueueNewOutput` to create output queue
- Uses `AudioQueueAllocateBuffer` for buffer allocation
- Callback `HandleOutputBuffer` decodes Opus and fills `mAudioData`
- Uses `AudioQueueStart` to start, `AudioQueueStop` to stop

### 3. Opus-Specific Error Codes (2001-2010)

To make Opus-related errors clearer and more traceable, we added 10 dedicated error codes:

| Code | Constant | Meaning | Suggested Action |
|------|----------|---------|-----------------|
| 2001 | AP_DS_ERR_OPUS_LIB_LOAD_FAILED | libopusfile load failed | Check DLL existence/locks |
| 2002 | AP_DS_ERR_OPUS_DLL_DEPENDENCY | DLL dependency missing | Ensure libopus-0.dll and libogg-0.dll exist |
| 2003 | AP_DS_ERR_OPUS_OPEN_FAILED | Opus file open failed | File may be corrupted or not valid Opus |
| 2004 | AP_DS_ERR_OPUS_HEADER_CORRUPT | OpusHead header corrupt | Invalid or corrupted header info |
| 2005 | AP_DS_ERR_OPUS_TAGS_PARSE_FAILED | Tag parse failed | Corrupted or invalid tag data |
| 2006 | AP_DS_ERR_OPUS_DECODE_FAILED | Opus decode failed | Corrupted audio data |
| 2007 | AP_DS_ERR_OPUS_SEEK_FAILED | Opus seek failed | Stream may not support seeking to this position |
| 2008 | AP_DS_ERR_OPUS_BITRATE_UNAVAILABLE | Bitrate unavailable | Cannot determine bitrate for this Opus stream |
| 2009 | AP_DS_ERR_OPUS_NOT_SEEKABLE | Stream not seekable | This Opus stream doesn't support seeking |
| 2010 | AP_DS_ERR_OPUS_CHANNEL_INVALID | Invalid channel count | Invalid channel count in Opus stream |

All Opus errors include:
- Machine-readable error code (for programmatic handling)
- Human-readable error message (for developer understanding)
- Actionable suggestion (for user problem resolution)

### 4. Auto DLL Download & Hash Verification (Windows)

Windows users don't need to manually find DLLs. When ap_ds first detects Opus support is needed, it:

1. Checks if the 4 required DLLs exist in the package directory
2. Downloads from `https://dvsyun.top/ap_ds/download/` if missing or hash verification fails
3. Performs SHA256 hash verification after download
4. Auto-retries if hash mismatch

| File | Size | SHA256 |
|------|------|--------|
| libopusfile-0.dll | 55,884 B | fc8ff75c5e0180e73b0528dc78c51ed0fb493741375cdc227f50c2a33cabf727 |
| libopus-0.dll | 500,112 B | 90aa25a0a6525d7da48a7ae8dd3306e45b0c28ce09a73d2a02b56cd95418d5be |
| libogg-0.dll | 40,580 B | 3038ce8d161324a6349bf7c83b78493857ff6a3501e3adb3d541c6a07bd94a57 |
| libopusurl-0.dll | 76,772 B | a6cde968a23f2d0067332a13718c52e265653a2c35d65862e8dff4cf2a0346d9 |

### 5. Cross-Platform Opus Library Loading

**Windows:**
- Check package directory for DLLs → Auto-download if missing → SHA256 verify → Load via `ctypes.CDLL`

**Linux:**
- User config check (`~/.config/ap_ds/opus_paths.conf`) → System library check (`ctypes.util.find_library("opusfile")`) → Auto-install (apt-get/dnf/pacman, interactive sudo) → Interactive setup

**macOS:**
- System library detection (find_library + common Homebrew/MacPorts paths) → MacPorts auto-install (`sudo port install opus opusfile libogg`) → Homebrew auto-install (`brew install opus opusfile libogg`) → Manual installation guide

### 6. OpusAudio Class — Complete API

The `OpusAudio` class provides an API nearly identical to `AudioLibrary`, but fully based on `libopusfile` and native audio output:

| Method | Function |
|--------|----------|
| `play_from_file(file_path, loops=0, start_pos=0.0)` | Play Opus file |
| `play_from_memory(file_path, loops=0, start_pos=0.0)` | Play from cache |
| `new_aid(file_path)` | Preload Opus file |
| `play_audio(aid)` | Resume playback |
| `pause_audio(aid)` | Pause playback |
| `stop_audio(aid)` | Stop playback, return elapsed time |
| `seek_audio(aid, position)` | Seek to position (seconds) |
| `set_volume(aid, volume)` | Set volume (0-128) |
| `get_volume(aid)` | Get volume |
| `fadein_music(aid, loops=-1, ms=0)` | Fade in during playback |
| `fadein_music_pos(aid, loops=-1, ms=0, position=0.0)` | Fade in from position |
| `fadeout_music(ms=0)` | Fade out and stop |
| `is_music_playing()` | Check if playing |
| `is_music_paused()` | Check if paused |
| `get_music_fading()` | Get fade in/out status |
| `get_audio_metadata(file_path)` | Get Opus metadata |
| `get_audio_duration(file_path)` | Get Opus duration |
| `get_audio_extended_metadata(file_path)` | Get extended tags (title/artist/album etc.) |
| `batch_get_metadata(file_paths, max_workers=None)` | Batch parse Opus metadata |
| `batch_get_duration(file_paths, max_workers=None)` | Batch get Opus duration |
| `cleanup_function()` | Release all resources |

### 7. Library Size Changes

Due to the addition of `opusplayer.py` (~45KB) and `_opusdll.py` (~25KB) plus Windows DLLs (~673KB total), this 0.0.1-AFS pre-release temporarily expands to ~3.87 MB.

| Version | Opus Support | Size | Description |
|---------|-------------|------|-------------|
| 4.0.x | ❌ | ~2.5MB | Stable, no Opus |
| **AFS 0.0.1-AFS** | ✅ | **~3.87MB** | **AFS pre-release with Opus** |
| 4.2.0+ (mainline) | ❌ | ~2.5MB | Mainline returns to lightweight |
| AFS 1.0.0+ | ✅ | ~2.8-3.5MB | AFS permanent home for Opus |

---

## 🌿 AFS Branch — ap_ds's "Dual-Track" Future

### Why Split?

With Opus added, the mainline package size grew from 2.5MB to 3.87MB. Every new format will increase size. If we stuff all formats into mainline, ap_ds will eventually become a bloated monster, betraying the original "lightweight" vision.

**So we decided: split the family.**

**AFS (All Format Support)** is a brand new independent branch that will carry all new format support, "beyond the 2.5MB limit."

| Aspect | Mainline (ap-ds) | AFS Branch (ap-ds-afs) |
|--------|-----------------|----------------------|
| PyPI package | `ap-ds` | `ap-ds-afs` |
| Import name | `ap_ds` | `ap_ds` (**identical!**) |
| Version | 4.x (continues) | 0.0.1-AFS → 1.0.0+ |
| Opus support | ❌ (except 4.1.0) | ✅ **Permanent** |
| Core formats | MP3/WAV/FLAC/OGG/AAC | Same + Opus + all future formats |
| Size | ~2.5MB | ~2.8-3.5MB |
| Update strategy | Security fixes only | Mainline sync + own new formats |
| Target users | Minimalist developers | Developers needing special formats |

**Key Design: Same Import Name**

```python
# Regardless of whether user installed ap-ds or ap-ds-afs
# The import method is exactly the same!
from ap_ds import AudioLibrary
```

This means users can switch between the two packages seamlessly by just changing the package name in `requirements.txt` or `pip install`.

### Which One Should You Choose?

| Your Need | Recommendation |
|-----------|---------------|
| Only MP3/WAV/FLAC/OGG/AAC | Mainline (`ap-ds` 4.2.0+) — lightweight, stable |
| Need Opus, willing to test pre-release | AFS (`ap-ds-afs` 0.0.1-AFS) — early adopter, feedback |
| Need Opus, want long-term stability | AFS (`ap-ds-afs` 1.0.0, September 2026) — full-featured, LTS |
| Not sure about future format needs | Install mainline, switch to AFS later (same import!) |

---

## ⚠️ Windows Multiprocessing Warning

If you're using ap_ds AFS 0.0.1-AFS on Windows... please read this carefully. Your program's ability to run depends on it.

**What's the problem?**

On Windows, Python's `multiprocessing` module uses the `spawn` method to create new processes. This means each child process re-imports your main module.

If you call `batch_get_metadata()` or any batch function that uses `ProcessPoolExecutor` directly at the top level of your script, child processes will execute these calls again when re-importing, causing infinite recursion and eventually a `BrokenProcessPool` error.

**Your program will crash. Directly.**

**Affected APIs:**
- `batch_get_metadata()`
- `batch_get_duration()`
- `batch_get_metadata_by_type()`
- Opus batch parsing is also affected

**How to fix?**

Simply wrap your batch parsing code inside `if __name__ == "__main__":`.

**❌ Wrong (Will crash on Windows):**
```python
from ap_ds import batch_get_metadata

# This will crash directly on Windows!
results = batch_get_metadata("/music/", max_workers=4)
print(f"Parsed {len(results)} files")
```

**✅ Correct:**
```python
from ap_ds import batch_get_metadata

def main():
    results = batch_get_metadata("/music/", max_workers=4)
    print(f"Parsed {len(results)} files")

if __name__ == "__main__":
    main()
```

**✅ Correct (with config function):**
```python
from ap_ds import batch_get_metadata

def load_config():
    return {"audio_dir": "/music/"}

def main():
    config = load_config()
    results = batch_get_metadata(config["audio_dir"], max_workers=4)
    print(f"Parsed {len(results)} files")

if __name__ == "__main__":
    main()
```

**✅ Jupyter Notebook Users:**
Put the batch call inside a function, then execute it in a cell:
```python
def run_batch():
    from ap_ds import batch_get_metadata
    return batch_get_metadata("/music/", max_workers=4)

results = run_batch()
```

**Why don't Linux and macOS have this problem?**

Linux and macOS use `fork` by default to create child processes, which copy the parent process's memory space without re-executing the main module code.

However, we still recommend using `if __name__ == "__main__"` entry point protection on all platforms. It's good programming practice and ensures cross-platform compatibility.

---

## 📊 Version Comparison Overview

| Aspect | Mainline 4.0.x | AFS 0.0.1-AFS | Mainline 4.2.0+ (planned) | AFS 1.0.0 (planned) |
|--------|---------------|---------------|--------------------------|---------------------|
| Opus support | ❌ | ✅ | ❌ | ✅ |
| Playback formats | MP3/WAV/FLAC/OGG/AAC | +Opus | MP3/WAV/FLAC/OGG/AAC | +Opus + future formats |
| Playback engine | SDL2 only | SDL2 + Opus native | SDL2 only | SDL2 + Opus native |
| Opus error codes | ❌ | ✅ 2001-2010 | ❌ | ✅ 2001-2010 |
| Auto DLL download | SDL2 | SDL2 + Opus DLLs | SDL2 | SDL2 + Opus DLLs |
| AFS branch | ❌ | ✅ (AFS itself) | ❌ | ✅ (AFS itself) |
| Test coverage | 421 tests | 650+ tests | 421 tests | 650+ tests |
| Library size | ~2.5MB | ~3.87MB | ~2.5MB | ~2.8-3.5MB |
| Version status | Stable | **Pre-release** | Planned | Planned (Sep 2026) |

### Version Relationship

| Version | Type | Support Period | Use Case |
|---------|------|---------------|----------|
| v3.0.0 LTS | LTS | Until Mar 2031 | Production |
| v4.0.x | LFV | ~6 months | Early adopters |
| **AFS 0.0.1-AFS** | **Pre-release** | **~1 month** | **Opus testing & feedback** |
| AFS 1.0.0+ (planned) | Stable | TBD | Opus permanent home (Sep 2026) |
| Mainline 4.2.0+ | LFV | ~6 months | Returns to lightweight |

### Upgrade Recommendations

| User Type | Recommendation |
|-----------|---------------|
| Production | Continue with v3.0.0 LTS, or wait for AFS 1.0.0 |
| Dev/Test | Try AFS 0.0.1-AFS with Opus, help test & feedback |
| Need Opus, willing to test | Use AFS 0.0.1-AFS, report bugs |
| Need Opus, want long-term stability | Wait for AFS 1.0.0 (September 2026) |
| No Opus needed, want lightweight | Wait for mainline 4.2.0+, or continue with 4.0.x |
| Affected by v3.1.x metadata bug | Must upgrade to v4.0.0+ |

---

## 🧪 CI/CD Test Results — Comprehensive Coverage, All Passed

### Opus Test Suite (OPUS_TEST.py)

AFS 0.0.1-AFS includes a complete Opus test suite covering 16 test categories:

| Category | Test Items | Description |
|----------|-----------|-------------|
| OP-1 | Module imports/constants/error codes | Verify all Opus modules, constants, error codes |
| OP-2 | DLL loading & auto-download | Verify `_opusdll.py` loading, DLL existence, hash verification |
| OP-3 | Metadata parsing | Verify Opus duration, sample rate, channels, bitrate, extended tags |
| OP-4 | Playback functions | Verify `play_from_file`, `play_from_memory`, `new_aid` |
| OP-5 | Playback control | Verify `pause_audio`, `play_audio`, `stop_audio` |
| OP-6 | Volume control | Verify `set_volume` (0-128 boundary values) and `get_volume` |
| OP-7 | Seek functionality | Verify `seek_audio` with various positions and boundary values |
| OP-8 | Fade in/out | Verify `fadein_music`, `fadein_music_pos`, `fadeout_music` |
| OP-9 | Opus vs native format distinction | Verify `_is_opus_file` and `AudioLibrary` auto-routing |
| OP-10 | Batch parsing | Verify `batch_get_metadata`, `batch_get_duration`, `batch_by_type` |
| OP-11 | Error code triggering | Confirm all 10 Opus error codes trigger correctly |
| OP-12 | AID 1:1 mapping | Verify main AID ↔ Opus sub-AID full lifecycle |
| OP-13 | Resource management | Verify `cleanup_function` releases resources correctly |
| OP-14 | Boundary & error tests | Verify invalid parameter types, out-of-range values |
| OP-15 | DLL-specific tests | Verify DLL file sizes, hashes, load idempotency |
| OP-16 | Error code trigger specific tests | Verify each Opus error code trigger in real scenarios |

**Test Results:**
```
==================================================================
 Opus Test Summary
==================================================================
   Passed : 229
   Failed : 0
   Skipped: 0
==================================================================
```

**All 229 tests passed, 0 failed, 0 skipped.**

### Comprehensive CICD Test Suite (CI,CD_TEST.py)
```
==================================================================
 CICD Test Summary
==================================================================
   Passed : 650+
   Failed : 0
   Skipped: 0
==================================================================
```

### API Import Verification Test (IMPORT_TEST.py)
```
============================================================
📊 FINAL SUMMARY
============================================================
🎉 ALL APIs EXIST! Documentation is accurate.
============================================================
✅ Passed: 47
❌ Failed: 0
```

**All 47 API checks passed!**

---

## 📖 Technical Manual Update

`show_tech_manual()` has been updated for AFS 0.0.1-AFS with:

- **Section 2.1 OPUS SUPPORT** (New chapter) — Opus format introduction, playback backend architecture, auto DLL download, OpusAudio class API reference, AID 1:1 mapping mechanism
- **Section 10.4 Opus Error Codes** (New section) — Complete 10 Opus error codes list (2001-2010), meanings and suggested actions
- **Version History** — AFS 0.0.1-AFS entry, Opus support, cross-platform playback backend, AFS branch establishment

---

## 🌐 apds.top Is Now Live!

The ap_ds official project homepage is now live with TLS encryption!

**🎉 Visit: https://apds.top**

**Website Features:**
- 📄 Full documentation: API reference, user guide, FAQ
- 📦 Version distribution: All version download links and changelogs
- 🔗 Repository navigation: GitCode (primary), Gitee (China mirror), GitHub (compatibility mirror)
- ✉️ Feedback system: Users can submit feedback directly through the website
- 🔒 Full-site TLS encryption

---

## 📦 Repository Strategy

| Platform | Status | Purpose |
|----------|--------|---------|
| apds.top | ✅ Permanent home | Official source code, docs, downloads |
| GitCode | ✅ Primary mirror | Global code hosting |
| GitHub | ✅ Compatibility mirror | For GitHub developers (new!) |
| Gitee | ✅ China mirror | Fast access for Chinese users |
| GitLab (JiHu) | ❌ Deprecated | No longer maintained |

---

## ℹ️ Overview

**ap_ds AFS** is a lightweight (~3.87MB) Python audio library for playback and high-precision metadata parsing of MP3, FLAC, OGG, WAV, and **Opus** files. Zero external Python dependencies — only uses the Python standard library with non-blocking playback suitable for GUI applications.

**Core Features:**
- 🎵 **Native Opus support** — Dedicated playback pipeline independent of SDL2, cross-platform native audio output
- 📦 **Zero Python dependencies** — Standard library only
- 🎯 **High-precision metadata** — WAV/FLAC 100%, OGG 99.99%, MP3 >98%, Opus 100%
- ⚡ **Batch parsing** — Parallel processing of hundreds of files using `batch_get_metadata()`
- 🖥️ **Non-blocking playback** — Ideal for GUI applications
- 🌍 **Cross-platform** — Windows, macOS, Linux, embedded ARM64
- 📝 **DAP recording system** — Automatic playback history, metadata only
- 🧵 **Python 3.15t support** — No-GIL true parallelism, full multi-core performance
- 🏠 **AFS permanent support** — Permanent home for Opus and all future formats

---

## 📧 Contact & Support

📧 **License inquiries:** me@dvsyun.top or dvs6666@163.com — 7 business days response

🛠️ **Technical support:** apds.top · GitCode Issues · GitHub Issues · Gitee Issues · Email (completely free)

**Author:** DVS (DvsXT)
**Personal homepage & blog:** https://dvsx.top (under maintenance)
**Author profile:** https://dvsyun.top/me/dvs
**Email:** me@dvsyun.top · dvs6666@163.com

**ap_ds Official Portal:**
- 🎵 **Official website:** https://apds.top — Permanent official homepage, full documentation, releases, license center
- 📦 **PyPI:** https://pypi.org/project/ap_ds/
- 🌐 **Mirror docs:** https://www.dvsyun.top/ap_ds
