679 lines
28 KiB
HTML
679 lines
28 KiB
HTML
<!-- 英文 SEO 标签 -->
|
||
<meta name="description" content="ap_ds is an ultra-lightweight Python audio library (2.5MB) for high-quality playback & precise metadata parsing of MP3, FLAC, OGG, WAV. Zero external dependencies, non-blocking architecture. Created by Dvs (DvsXT), released 2026-03-01. A precise revolution in Python audio.">
|
||
<meta name="keywords" content="Python audio library, lightweight audio player, MP3, FLAC, OGG, WAV metadata, non-blocking playback, ap_ds, DvsXT, zero dependencies, 2026 Python ecosystem">
|
||
<meta property="og:title" content="ap_ds: Ultra-Lightweight Python Audio Library (2.5MB)">
|
||
<meta property="og:description" content="Zero external deps, non-blocking playback, precise metadata parsing for MP3/FLAC/OGG/WAV. Released 2026-03-01 by Dvs (DvsXT).">
|
||
<meta property="og:type" content="software">
|
||
<meta name="twitter:card" content="summary">
|
||
<meta name="twitter:title" content="ap_ds - Python Audio Library, 2.5MB">
|
||
<meta name="twitter:description" content="Solve the lightweight vs completeness contradiction in Python audio. Non-blocking, zero deps, 4 major formats.">
|
||
|
||
<!-- 中文 SEO 标签 -->
|
||
<meta name="description" lang="zh-CN" content="ap_ds 是一个超轻量级 Python 音频库(仅 2.5MB),支持 MP3、FLAC、OGG、WAV 四种主流格式的高质量播放和精确元数据解析。零外部 Python 依赖,非阻塞播放架构让 GUI 应用流畅运行。由 Dvs (DvsXT) 创作,发布于 2026-03-01,是 Python 音频领域的精准革命。">
|
||
<meta name="keywords" lang="zh-CN" content="Python音频库, 轻量级音频播放, MP3, FLAC, OGG, WAV元数据解析, 非阻塞播放, ap_ds, DvsXT, 零依赖, 2026 Python生态">
|
||
<meta property="og:title" content="ap_ds:超轻量级 Python 音频库 (2.5MB)">
|
||
<meta property="og:description" lang="zh-CN" content="零外部依赖,非阻塞播放,精准解析 MP3/FLAC/OGG/WAV。2026-03-01 由 Dvs (DvsXT) 发布。终结 Python 音频库的「完整性与轻量化」矛盾。">
|
||
|
||
<!-- 新增:官方自建代码仓库说明 -->
|
||
<meta name="description" content="This domain is the official self-hosted code repository for ap_ds. Direct source, stable releases, and authoritative documentation.">
|
||
<meta name="description" lang="zh-CN" content="本域名是 ap_ds 官方自建代码仓库。提供直接源代码、稳定版本及权威文档。"> {% extends "base.html" %}
|
||
|
||
{% block title %}ap_ds · lightweight Python audio solution ap_ds · 轻量级Python音频库{% endblock %}
|
||
|
||
{% block extra_head %}
|
||
<link rel="canonical" href="https://apds.top" />
|
||
<link rel="me" href="https://gitee.com/dssxt/ap_ds" />
|
||
<link rel="me" href="https://gitcode.com/dvsxt/ap_ds" />
|
||
<link rel="nofollow" href="https://github.com/dvs-web/ap_ds" />
|
||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-tomorrow.min.css">
|
||
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.min.js"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-python.min.js"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-bash.min.js"></script>
|
||
<style>
|
||
/* 首页自定义样式 - 基于 css.css 变量 */
|
||
.home-container {
|
||
max-width: 1280px;
|
||
margin: 0 auto;
|
||
padding: var(--repo-spacing-6) var(--repo-spacing-4);
|
||
}
|
||
|
||
/* Hero 区域 */
|
||
.hero-section {
|
||
text-align: center;
|
||
padding: var(--repo-spacing-10) 0 var(--repo-spacing-8);
|
||
background: linear-gradient(135deg, var(--repo-color-bg) 0%, var(--repo-color-bg-secondary) 100%);
|
||
border-radius: var(--repo-radius-xl);
|
||
margin-bottom: var(--repo-spacing-8);
|
||
}
|
||
|
||
.hero-title {
|
||
font-size: 3rem;
|
||
font-weight: 700;
|
||
margin-bottom: var(--repo-spacing-4);
|
||
background: linear-gradient(135deg, var(--repo-color-primary) 0%, #6366f1 100%);
|
||
-webkit-background-clip: text;
|
||
background-clip: text;
|
||
color: transparent;
|
||
}
|
||
|
||
.hero-subtitle {
|
||
font-size: var(--repo-font-size-xl);
|
||
color: var(--repo-color-text-secondary);
|
||
margin-bottom: var(--repo-spacing-6);
|
||
}
|
||
|
||
.version-badges {
|
||
display: flex;
|
||
justify-content: center;
|
||
gap: var(--repo-spacing-3);
|
||
flex-wrap: wrap;
|
||
margin-top: var(--repo-spacing-4);
|
||
}
|
||
|
||
/* 目录 */
|
||
.toc-section {
|
||
background: var(--repo-color-bg-secondary);
|
||
border-radius: var(--repo-radius-lg);
|
||
padding: var(--repo-spacing-6);
|
||
margin-bottom: var(--repo-spacing-8);
|
||
border-left: 4px solid var(--repo-color-primary);
|
||
}
|
||
|
||
.toc-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||
gap: var(--repo-spacing-2);
|
||
margin-top: var(--repo-spacing-4);
|
||
}
|
||
|
||
.toc-link {
|
||
color: var(--repo-color-text-secondary);
|
||
text-decoration: none;
|
||
font-size: var(--repo-font-size-sm);
|
||
padding: var(--repo-spacing-1) 0;
|
||
display: inline-block;
|
||
}
|
||
|
||
.toc-link:hover {
|
||
color: var(--repo-color-primary);
|
||
text-decoration: none;
|
||
}
|
||
|
||
/* 内容区块 */
|
||
.content-card {
|
||
background: var(--repo-color-bg);
|
||
border: 1px solid var(--repo-color-border);
|
||
border-radius: var(--repo-radius-lg);
|
||
padding: var(--repo-spacing-8);
|
||
margin-bottom: var(--repo-spacing-8);
|
||
box-shadow: var(--repo-shadow-sm);
|
||
}
|
||
|
||
.content-card h2 {
|
||
font-size: var(--repo-font-size-2xl);
|
||
font-weight: 600;
|
||
margin-bottom: var(--repo-spacing-6);
|
||
padding-bottom: var(--repo-spacing-3);
|
||
border-bottom: 2px solid var(--repo-color-border);
|
||
color: var(--repo-color-text);
|
||
}
|
||
|
||
.content-card h3 {
|
||
font-size: var(--repo-font-size-xl);
|
||
font-weight: 600;
|
||
margin-top: var(--repo-spacing-6);
|
||
margin-bottom: var(--repo-spacing-4);
|
||
color: var(--repo-color-text);
|
||
}
|
||
|
||
.content-card h4 {
|
||
font-size: var(--repo-font-size-lg);
|
||
font-weight: 600;
|
||
margin-top: var(--repo-spacing-4);
|
||
margin-bottom: var(--repo-spacing-3);
|
||
color: var(--repo-color-text);
|
||
}
|
||
|
||
/* 特性网格 */
|
||
.feature-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||
gap: var(--repo-spacing-5);
|
||
margin-bottom: var(--repo-spacing-8);
|
||
}
|
||
|
||
.feature-card {
|
||
background: var(--repo-color-bg-secondary);
|
||
border-radius: var(--repo-radius-lg);
|
||
padding: var(--repo-spacing-5);
|
||
border: 1px solid var(--repo-color-border);
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
.feature-card:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: var(--repo-shadow-md);
|
||
border-color: var(--repo-color-primary);
|
||
}
|
||
|
||
.feature-icon {
|
||
font-size: 2rem;
|
||
margin-bottom: var(--repo-spacing-3);
|
||
}
|
||
|
||
.feature-title {
|
||
font-weight: 600;
|
||
font-size: var(--repo-font-size-lg);
|
||
margin-bottom: var(--repo-spacing-2);
|
||
color: var(--repo-color-text);
|
||
}
|
||
|
||
.feature-desc {
|
||
color: var(--repo-color-text-secondary);
|
||
font-size: var(--repo-font-size-sm);
|
||
}
|
||
|
||
/* 对比表格 */
|
||
.comparison-table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
margin: var(--repo-spacing-4) 0;
|
||
}
|
||
|
||
.comparison-table th,
|
||
.comparison-table td {
|
||
border: 1px solid var(--repo-color-border);
|
||
padding: var(--repo-spacing-3) var(--repo-spacing-4);
|
||
text-align: left;
|
||
}
|
||
|
||
.comparison-table th {
|
||
background: var(--repo-color-bg-secondary);
|
||
font-weight: 600;
|
||
}
|
||
|
||
/* 提示框 */
|
||
.note-box {
|
||
background: #eef2ff;
|
||
border-left: 4px solid var(--repo-color-primary);
|
||
border-radius: var(--repo-radius-md);
|
||
padding: var(--repo-spacing-4) var(--repo-spacing-6);
|
||
margin: var(--repo-spacing-4) 0;
|
||
color: #1e40af;
|
||
}
|
||
|
||
.warning-box {
|
||
background: #fffbeb;
|
||
border-left: 4px solid #f59e0b;
|
||
border-radius: var(--repo-radius-md);
|
||
padding: var(--repo-spacing-4) var(--repo-spacing-6);
|
||
margin: var(--repo-spacing-4) 0;
|
||
color: #92400e;
|
||
}
|
||
|
||
.success-box {
|
||
background: #ecfdf5;
|
||
border-left: 4px solid #10b981;
|
||
border-radius: var(--repo-radius-md);
|
||
padding: var(--repo-spacing-4) var(--repo-spacing-6);
|
||
margin: var(--repo-spacing-4) 0;
|
||
color: #065f46;
|
||
}
|
||
|
||
/* 代码块 */
|
||
.code-block {
|
||
position: relative;
|
||
background: #0f172a;
|
||
border-radius: var(--repo-radius-lg);
|
||
margin: var(--repo-spacing-4) 0;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.code-block pre {
|
||
margin: 0;
|
||
padding: var(--repo-spacing-5);
|
||
overflow-x: auto;
|
||
background: transparent !important;
|
||
}
|
||
|
||
.code-block code {
|
||
font-family: var(--repo-font-family-mono);
|
||
font-size: var(--repo-font-size-sm);
|
||
color: #f8fafc;
|
||
}
|
||
|
||
.copy-btn {
|
||
position: absolute;
|
||
top: 12px;
|
||
right: 16px;
|
||
background: #334155;
|
||
color: #f1f5f9;
|
||
border: none;
|
||
border-radius: var(--repo-radius-full);
|
||
padding: 4px 14px;
|
||
font-size: var(--repo-font-size-xs);
|
||
cursor: pointer;
|
||
transition: 0.2s;
|
||
opacity: 0.7;
|
||
}
|
||
|
||
.copy-btn:hover {
|
||
opacity: 1;
|
||
background: #475569;
|
||
}
|
||
|
||
.copy-btn.copied {
|
||
background: #059669;
|
||
}
|
||
|
||
/* 许可证区域 */
|
||
.license-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||
gap: var(--repo-spacing-4);
|
||
margin-top: var(--repo-spacing-6);
|
||
}
|
||
|
||
.license-card {
|
||
background: var(--repo-color-bg-secondary);
|
||
border-radius: var(--repo-radius-lg);
|
||
padding: var(--repo-spacing-5);
|
||
border: 1px solid var(--repo-color-border);
|
||
}
|
||
|
||
.license-card h4 {
|
||
margin-top: 0;
|
||
margin-bottom: var(--repo-spacing-3);
|
||
}
|
||
|
||
/* 公告区域 */
|
||
.announcement-content {
|
||
line-height: 1.7;
|
||
}
|
||
|
||
.announcement-content h1,
|
||
.announcement-content h2,
|
||
.announcement-content h3 {
|
||
margin-top: var(--repo-spacing-5);
|
||
margin-bottom: var(--repo-spacing-3);
|
||
}
|
||
|
||
.announcement-content h1 { font-size: var(--repo-font-size-xl); border-bottom: 1px solid var(--repo-color-border); padding-bottom: var(--repo-spacing-2); }
|
||
.announcement-content h2 { font-size: var(--repo-font-size-lg); border-bottom: 1px solid var(--repo-color-border); padding-bottom: var(--repo-spacing-2); }
|
||
.announcement-content h3 { font-size: var(--repo-font-size-base); }
|
||
.announcement-content p { margin-bottom: var(--repo-spacing-4); }
|
||
.announcement-content ul, .announcement-content ol { padding-left: var(--repo-spacing-6); margin-bottom: var(--repo-spacing-4); }
|
||
.announcement-content code {
|
||
background: var(--repo-color-bg-tertiary);
|
||
padding: 0.2em 0.4em;
|
||
border-radius: var(--repo-radius-sm);
|
||
font-size: 0.9em;
|
||
}
|
||
.announcement-content pre {
|
||
background: #0f172a;
|
||
padding: var(--repo-spacing-4);
|
||
border-radius: var(--repo-radius-md);
|
||
overflow-x: auto;
|
||
margin: var(--repo-spacing-4) 0;
|
||
}
|
||
.announcement-content pre code {
|
||
background: none;
|
||
padding: 0;
|
||
color: #f8fafc;
|
||
}
|
||
.announcement-content blockquote {
|
||
border-left: 4px solid var(--repo-color-border);
|
||
padding-left: var(--repo-spacing-4);
|
||
margin: var(--repo-spacing-4) 0;
|
||
color: var(--repo-color-text-secondary);
|
||
}
|
||
|
||
/* 响应式 */
|
||
@media (max-width: 768px) {
|
||
.hero-title {
|
||
font-size: 2rem;
|
||
}
|
||
.content-card {
|
||
padding: var(--repo-spacing-5);
|
||
}
|
||
.feature-grid {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
}
|
||
</style>
|
||
{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="home-container">
|
||
<!-- Hero 区域 -->
|
||
<div class="hero-section">
|
||
<h1 class="hero-title" id="hero-title">ap_ds: 轻量级 Python 音频革命</h1>
|
||
<p class="hero-subtitle" id="hero-subtitle">2.5MB 终结 160MB 臃肿时代</p>
|
||
<div class="version-badges" id="version-badges">
|
||
<span class="repo-tag repo-tag--primary">v3.0.0 LTS</span>
|
||
<span class="repo-tag repo-tag--success">仅 2.5MB</span>
|
||
<span class="repo-tag repo-tag--warning">跨平台 W/M/L</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 目录 -->
|
||
<div class="toc-section">
|
||
<h3 class="repo-text-lg repo-font-semibold repo-mb-4"><i class="fa fa-list-ul" style="margin-right: 8px; color: var(--repo-color-primary);"></i>目录</h3>
|
||
<div class="toc-grid">
|
||
<a href="#introduction" class="toc-link">1. 项目介绍</a>
|
||
<a href="#features" class="toc-link">2. 核心特性</a>
|
||
<a href="#comparison" class="toc-link">3. 技术对比</a>
|
||
<a href="#installation" class="toc-link">4. 安装与使用</a>
|
||
<a href="#license" class="toc-link">5. 开源许可证</a>
|
||
<a href="#faq" class="toc-link">6. 常见问题</a>
|
||
<a href="#contact" class="toc-link">7. 联系与支持</a>
|
||
<a href="#announcement" class="toc-link">8. 最新公告</a>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 1. 项目介绍 -->
|
||
<div class="content-card" id="introduction">
|
||
<h2>1. 项目介绍</h2>
|
||
<div class="note-box">
|
||
<p><strong>📋 官方信息</strong></p>
|
||
<p>项目名称:ap_ds</p>
|
||
<p>官方网站:<a href="https://apds.top" style="color: var(--repo-color-primary);">https://apds.top</a></p>
|
||
<p>PyPI:<a href="https://pypi.org/project/ap_ds/" style="color: var(--repo-color-primary);">https://pypi.org/project/ap_ds/</a></p>
|
||
<p>开发者:Dvs (DvsXT)</p>
|
||
</div>
|
||
<p>ap_ds 是一个极轻量级(2.5MB)的 Python 音频库,用于播放和精确解析 MP3、FLAC、OGG 和 WAV 文件。它没有外部 Python 依赖,仅使用 Python 标准库,为非阻塞播放提供平滑的 GUI 应用程序体验。</p>
|
||
<div class="success-box">
|
||
<p><strong>🎉 v3.0.0 LTS 长期支持版本</strong></p>
|
||
<p>首个长期支持版本,提供 <strong>永久免费技术支持</strong>,哈希验证下载,确定性资源清理。</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 2. 核心特性 -->
|
||
<div class="content-card" id="features">
|
||
<h2>2. 核心特性</h2>
|
||
<div class="feature-grid">
|
||
<div class="feature-card">
|
||
<div class="feature-icon">⚡</div>
|
||
<div class="feature-title">极致轻量</div>
|
||
<div class="feature-desc">Windows 2.5MB · macOS 3.36MB · Linux 就绪</div>
|
||
</div>
|
||
<div class="feature-card">
|
||
<div class="feature-icon">🎵</div>
|
||
<div class="feature-title">四种格式</div>
|
||
<div class="feature-desc">MP3 / FLAC / OGG / WAV</div>
|
||
</div>
|
||
<div class="feature-card">
|
||
<div class="feature-icon">📊</div>
|
||
<div class="feature-title">精确元数据</div>
|
||
<div class="feature-desc">WAV/FLAC 100% 准确</div>
|
||
</div>
|
||
<div class="feature-card">
|
||
<div class="feature-icon">▶️</div>
|
||
<div class="feature-title">非阻塞播放</div>
|
||
<div class="feature-desc">完美适配 GUI 应用</div>
|
||
</div>
|
||
</div>
|
||
<div class="grid" style="display: grid; grid-template-columns: 1fr 1fr; gap: var(--repo-spacing-8);">
|
||
<div>
|
||
<h3>📦 体积对比</h3>
|
||
<ul style="list-style: none; padding-left: 0;">
|
||
<li style="margin-bottom: var(--repo-spacing-2);">🟢 <strong>ap_ds</strong> Windows: 2.5MB</li>
|
||
<li style="margin-bottom: var(--repo-spacing-2);">🍎 macOS: 3.36MB</li>
|
||
<li style="margin-bottom: var(--repo-spacing-2);">🐧 Linux: 动态链接 ~50KB</li>
|
||
<li style="margin-bottom: var(--repo-spacing-2);">🔴 FFmpeg: ≥160MB</li>
|
||
<li>🟡 Pygame + 解析库: 臃肿且功能不全</li>
|
||
</ul>
|
||
</div>
|
||
<div>
|
||
<h3>⚙️ 为什么这么小?</h3>
|
||
<ul>
|
||
<li>专注:仅播放和解析,无编辑/转码</li>
|
||
<li>基于工业级 SDL2</li>
|
||
<li>逐字节优化</li>
|
||
<li>跨平台 W/M/L</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 3. 技术对比 -->
|
||
<div class="content-card" id="comparison">
|
||
<h2>3. 技术对比</h2>
|
||
|
||
<h3>第一章:Pygame —— 游戏引擎的"音频残疾"</h3>
|
||
<div class="code-block">
|
||
<pre class="language-python"><code># Pygame 不可靠的音频时长
|
||
my_sound = pygame.mixer.Sound('my_song.mp3')
|
||
total_length = my_sound.get_length() # 仅对 WAV 可靠!</code></pre>
|
||
<button class="copy-btn" onclick="copyCode(this)"><i class="fa fa-clipboard"></i> 复制</button>
|
||
</div>
|
||
<div class="warning-box">
|
||
⚠️ Pygame 的 <code>Sound.get_length()</code> 仅对 WAV 格式正确,MP3/OGG/FLAC 返回无效值。
|
||
</div>
|
||
|
||
<h3>第二章:FFmpeg 套件 —— 160MB 的"至少"之痛</h3>
|
||
<table class="comparison-table">
|
||
<thead><tr><th>组件</th><th>功能</th><th>大小</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>ffplay.exe</td><td>播放核心</td><td>≈80MB</td></tr>
|
||
<tr><td>ffprobe.exe</td><td>元数据探测</td><td>≈80MB</td></tr>
|
||
<tr><td>ffmpeg.exe</td><td>转换器</td><td>≈80MB</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="note-box">🔍 三个独立可执行文件,无 Python 封装,总计 ≥160MB。</div>
|
||
|
||
<h3>第三章:ap_ds 革命</h3>
|
||
<div class="success-box">
|
||
<p><strong>七大技术突破</strong></p>
|
||
<ul>
|
||
<li>✓ 2.5MB 解决 160MB 问题</li>
|
||
<li>✓ 非阻塞消除 GUI 卡顿</li>
|
||
<li>✓ 精确进度查询</li>
|
||
<li>✓ 零依赖部署</li>
|
||
<li>✓ AID 多音频管理</li>
|
||
<li>✓ SDL2 性能</li>
|
||
<li>✓ 智能 C 依赖跨平台</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 4. 安装与使用 -->
|
||
<div class="content-card" id="installation">
|
||
<h2>4. 安装与使用</h2>
|
||
|
||
<div class="code-block">
|
||
<pre class="language-bash"><code>pip install ap_ds</code></pre>
|
||
<button class="copy-btn" onclick="copyCode(this)"><i class="fa fa-clipboard"></i> 复制</button>
|
||
</div>
|
||
|
||
<h3>基础示例</h3>
|
||
<div class="code-block">
|
||
<pre class="language-python"><code>from ap_ds import AudioLibrary
|
||
|
||
lib = AudioLibrary()
|
||
aid = lib.play_from_file("music.mp3")
|
||
lib.pause_audio(aid)
|
||
lib.seek_audio(aid, 30.5)
|
||
duration = lib.stop_audio(aid)</code></pre>
|
||
<button class="copy-btn" onclick="copyCode(this)"><i class="fa fa-clipboard"></i> 复制</button>
|
||
</div>
|
||
|
||
<h3>DAP 播放列表 (v2.3.0+)</h3>
|
||
<div class="code-block">
|
||
<pre class="language-python"><code>aid1 = lib.play_from_file("song1.mp3")
|
||
recordings = lib.get_dap_recordings()
|
||
lib.save_dap_to_json("my_playlist.ap-ds-dap")</code></pre>
|
||
<button class="copy-btn" onclick="copyCode(this)"><i class="fa fa-clipboard"></i> 复制</button>
|
||
</div>
|
||
|
||
<h3>淡入淡出效果 (v2.4.0+)</h3>
|
||
<div class="code-block">
|
||
<pre class="language-python"><code># 2秒淡入
|
||
lib.fadein_music(aid, loops=-1, ms=2000)
|
||
|
||
# 3秒淡出
|
||
lib.fadeout_music(ms=3000)
|
||
|
||
# 检查播放状态
|
||
if lib.is_music_playing():
|
||
print("音乐播放中")</code></pre>
|
||
<button class="copy-btn" onclick="copyCode(this)"><i class="fa fa-clipboard"></i> 复制</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 5. 开源许可证 -->
|
||
<div class="content-card" id="license">
|
||
<h2>5. 开源许可证</h2>
|
||
<div class="license-grid">
|
||
<div class="license-card">
|
||
<h4>✅ 您可以</h4>
|
||
<ul>
|
||
<li>商业使用</li>
|
||
<li>修改代码</li>
|
||
<li>闭源集成</li>
|
||
<li>销售解决方案</li>
|
||
<li>云服务部署</li>
|
||
</ul>
|
||
</div>
|
||
<div class="license-card">
|
||
<h4>❌ 您不可以</h4>
|
||
<ul>
|
||
<li>使用原始品牌名称</li>
|
||
<li>删除版权声明</li>
|
||
<li>用于非法用途</li>
|
||
<li>专利侵权诉讼</li>
|
||
</ul>
|
||
</div>
|
||
<div class="license-card">
|
||
<h4>👍 您应该</h4>
|
||
<ul>
|
||
<li>保留版权声明</li>
|
||
<li>标注来源归属</li>
|
||
<li>报告安全问题</li>
|
||
<li>修改版本用独立品牌</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<p class="repo-text-secondary repo-text-sm repo-mt-4">详细许可证请查看 <code>AP_DS_LICENSE.MD</code> 文件。</p>
|
||
</div>
|
||
|
||
<!-- 6. 常见问题 -->
|
||
<div class="content-card" id="faq">
|
||
<h2>6. 常见问题</h2>
|
||
|
||
<div><p class="repo-font-semibold">问:公司可以将其集成到商业产品中吗?</p><div class="success-box">✅ 完全可以,无需付费、无需通知、无需授权。</div></div>
|
||
|
||
<div><p class="repo-font-semibold repo-mt-4">问:我可以修改并重新分发吗?</p><div class="success-box">✅ 可以,但必须使用独立品牌、保留版权、标注来源、提供维护者声明。</div></div>
|
||
|
||
<div><p class="repo-font-semibold repo-mt-4">问:我必须开源我的修改吗?</p><div class="warning-box">❌ 不需要,您可以闭源分发。</div></div>
|
||
|
||
<div><p class="repo-font-semibold repo-mt-4">问:在云服务中使用需要付费吗?</p><div class="warning-box">❌ 不需要,但欢迎贡献代码。</div></div>
|
||
|
||
<div><p class="repo-font-semibold repo-mt-4">问:技术支持收费吗?</p><div class="success-box">✅ 永久免费技术支持,通过 GitCode Issues 或邮件联系。</div></div>
|
||
</div>
|
||
|
||
<!-- 7. 联系与支持 -->
|
||
<div class="content-card" id="contact">
|
||
<h2>7. 联系与支持</h2>
|
||
<div class="grid" style="display: grid; grid-template-columns: 1fr 1fr; gap: var(--repo-spacing-6);">
|
||
<div style="background: var(--repo-color-bg-secondary); padding: var(--repo-spacing-5); border-radius: var(--repo-radius-lg);">
|
||
<h4>📧 授权咨询</h4>
|
||
<p>me@dvsyun.top 或 dvs6666@163.com</p>
|
||
<p class="repo-text-sm repo-text-tertiary">7个工作日内回复</p>
|
||
</div>
|
||
<div style="background: var(--repo-color-bg-secondary); padding: var(--repo-spacing-5); border-radius: var(--repo-radius-lg);">
|
||
<h4>🛠️ 技术支持</h4>
|
||
<p>GitCode Issues · 官方文档 · 邮件支持</p>
|
||
<p class="repo-text-sm repo-text-success">✅ 永久免费</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="repo-mt-6" style="background: var(--repo-color-bg-secondary); border-radius: var(--repo-radius-lg); padding: var(--repo-spacing-5);">
|
||
<h3>🔗 官方仓库</h3>
|
||
<div class="grid" style="display: grid; grid-template-columns: 1fr 1fr; gap: var(--repo-spacing-4); margin-top: var(--repo-spacing-3);">
|
||
<div>
|
||
<p>✅ <strong>主仓库:</strong><a href="https://gitcode.com/dvsxt/ap_ds" class="repo-text-link">GitCode</a></p>
|
||
<p>✅ <strong>国内镜像:</strong><a href="https://gitee.com/dssxt/ap_ds" class="repo-text-link">Gitee</a></p>
|
||
</div>
|
||
<div>
|
||
<p>❌ <strong>已废弃:</strong><a href="https://github.com/dvs-web/ap_ds" class="repo-text-danger">GitHub</a></p>
|
||
<p>🔗 <strong>项目主页:</strong><a href="https://apds.top" class="repo-text-link">apds.top</a></p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 8. 最新公告 -->
|
||
<div class="content-card" id="announcement">
|
||
<h2>8. 最新公告</h2>
|
||
<div id="announcement-content" class="announcement-content">加载中...</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// 复制代码函数
|
||
window.copyCode = function(btn) {
|
||
const pre = btn.parentElement.querySelector('pre');
|
||
const code = pre.innerText;
|
||
navigator.clipboard.writeText(code).then(() => {
|
||
btn.classList.add('copied');
|
||
btn.innerHTML = '<i class="fa fa-check"></i> 已复制';
|
||
setTimeout(() => {
|
||
btn.classList.remove('copied');
|
||
btn.innerHTML = '<i class="fa fa-clipboard"></i> 复制';
|
||
}, 2000);
|
||
});
|
||
};
|
||
|
||
// 从后端获取版本信息
|
||
fetch('/api/version-info')
|
||
.then(res => res.json())
|
||
.then(data => {
|
||
if (data.title) document.getElementById('hero-title').innerHTML = data.title;
|
||
if (data.subtitle) document.getElementById('hero-subtitle').innerHTML = data.subtitle;
|
||
const badgesDiv = document.getElementById('version-badges');
|
||
if (data.version || data.size) {
|
||
badgesDiv.innerHTML = `
|
||
<span class="repo-tag repo-tag--primary">${data.version || 'v3.0.0 LTS'}</span>
|
||
<span class="repo-tag repo-tag--success">仅 ${data.size || '2.5MB'}</span>
|
||
<span class="repo-tag repo-tag--warning">跨平台 W/M/L</span>
|
||
`;
|
||
}
|
||
})
|
||
.catch(() => {});
|
||
|
||
// 加载最新公告
|
||
fetch('/api/latest-announcement')
|
||
.then(res => res.json())
|
||
.then(data => {
|
||
const container = document.getElementById('announcement-content');
|
||
if (data.html) {
|
||
container.innerHTML = data.html;
|
||
// 高亮代码块
|
||
if (typeof Prism !== 'undefined') {
|
||
Prism.highlightAllUnder(container);
|
||
}
|
||
// 为代码块添加复制按钮
|
||
container.querySelectorAll('pre').forEach(pre => {
|
||
if (!pre.parentElement.classList.contains('code-block')) {
|
||
const wrapper = document.createElement('div');
|
||
wrapper.className = 'code-block';
|
||
pre.parentNode.insertBefore(wrapper, pre);
|
||
wrapper.appendChild(pre);
|
||
const btn = document.createElement('button');
|
||
btn.className = 'copy-btn';
|
||
btn.innerHTML = '<i class="fa fa-clipboard"></i> 复制';
|
||
btn.onclick = function() { window.copyCode(btn); };
|
||
wrapper.appendChild(btn);
|
||
}
|
||
});
|
||
} else {
|
||
container.innerHTML = '<p class="repo-text-tertiary">暂无公告</p>';
|
||
}
|
||
})
|
||
.catch(() => {
|
||
document.getElementById('announcement-content').innerHTML = '<p class="repo-text-tertiary">无法加载公告</p>';
|
||
});
|
||
</script>
|
||
{% endblock %} |