# 音频时长计费系统设计

> 更新时间：2026-04-12

## 一、计费核心原则

### 🎯 计价单位：音频时长（分钟）

用户付费是为了得到**音频文件**，所以应该按**音频时长**计费：

```
用户问：这个章节生成音频要多少钱？
系统答：预计3分钟音频，按 ¥0.5/分钟 = ¥1.5
```

### 📊 成本拆解

```
总成本 = AI文本生成成本 + TTS合成成本

1. AI生成成本：
   - DeepSeek V3.2: ¥2.0/千token
   - 约 ¥2.0/千字（1字≈1token）

2. TTS合成成本（按音频时长）：
   - 基础版: ¥30/万字符 → 约¥0.05/分钟（150字/分钟语速）
   - 精品版: ¥150/万字符 → 约¥0.25/分钟
   - 火山引擎: ¥500/万字符 → 约¥0.83/分钟

3. 综合成本（DeepSeek + 百度精品）：
   - AI生成: ¥2/千字
   - TTS合成: ¥0.25/分钟 × 150字/分钟 = ¥0.25/千字
   - 总成本: ¥2.25/千字 ≈ ¥0.34/分钟
```

---

## 二、套餐设计（按音频时长配额）

### 💰 定价方案

| 套餐 | 月费 | 音频时长 | 单价折算 | 适用场景 |
|------|------|---------|---------|---------|
| **免费版** | ¥0 | 30分钟/月 | ¥0/分钟 | 体验引流 |
| **入门版** | ¥9.9 | 100分钟/月 | ¥0.099/分钟 | 轻度使用 |
| **专业版** | ¥49 | 500分钟/月 | ¥0.098/分钟 | 内容创作者 |
| **旗舰版** | ¥199 | 2000分钟/月 | ¥0.10/分钟 | 重度/企业 |

### 📐 套餐详情

#### 免费版（¥0/月）
```
配额：30分钟音频/月
成本：¥10.2（平台补贴）

包含：
✓ 每天3次生成
✓ 每次最多2分钟音频（约300字）
✓ 基础音色5种
✓ 标准音质
✓ 科大讯飞TTS（免费额度）

计算：30分钟 × ¥0.34/分钟 = ¥10.2（平台承担）
```

#### 入门版（¥9.9/月）⭐ 转化版
```
配额：100分钟音频/月
成本：¥34（AI¥20 + TTS¥14）

包含：
✓ 每天10次生成
✓ 每次最多5分钟音频（约750字）
✓ 全部音色
✓ 高清音质
✓ 百度基础版TTS

计算：100分钟 × ¥0.34/分钟 = ¥34
利润：¥9.9 - ¥34 = -¥24.1（亏损获客）
```

#### 专业版（¥49/月）⭐ 推荐
```
配额：500分钟音频/月
成本：¥170（AI¥100 + TTS¥70）

包含：
✓ 无限制生成
✓ 每次最多20分钟音频（约3000字）
✓ 全部音色+定制音色
✓ 无损音质
✓ 百度精品版TTS
✓ VIP优先队列

计算：500分钟 × ¥0.34/分钟 = ¥170
利润：¥49 - ¥170 = -¥121（大量补贴促转化）
```

#### 旗舰版（¥199/月）
```
配额：2000分钟音频/月
成本：¥680（AI¥400 + TTS¥280）

包含：
✓ 无限制生成
✓ 每次最多60分钟音频
✓ 全部功能
✓ 无损音质
✓ 火山引擎豆包TTS
✓ 专属技术支持
✓ 批量处理
✓ 团队管理

建议定价：¥699-999/月（高端定位）
```

---

## 三、按次计费（适合临时用户）

### 💵 单次购买

| 时长 | 基础音质 | 高清音质 | 无损音质 |
|------|---------|---------|---------|
| 1分钟 | ¥0.5 | ¥1.0 | ¥2.0 |
| 5分钟 | ¥2.5 | ¥5.0 | ¥10.0 |
| 10分钟 | ¥5.0 | ¥10.0 | ¥20.0 |
| 30分钟 | ¥15.0 | ¥30.0 | ¥60.0 |
| 60分钟 | ¥30.0 | ¥60.0 | ¥120.0 |

### 📦 音频包购买

| 包名 | 时长 | 价格 | 单价 | 折扣 |
|------|------|------|------|------|
| 体验包 | 10分钟 | ¥8 | ¥0.8/分钟 | - |
| 标准包 | 50分钟 | ¥35 | ¥0.7/分钟 | 12% |
| 大量包 | 200分钟 | ¥120 | ¥0.6/分钟 | 25% |
| 企业包 | 1000分钟 | ¥500 | ¥0.5/分钟 | 37% |

---

## 四、实时成本预估

### 📊 生成前预估

```typescript
// 前端显示预估成本
async function estimateAudioCost(textLength: number, quality: string) {
  // 估算音频时长（按150字/分钟语速）
  const audioMinutes = Math.ceil(textLength / 150);
  
  // 根据音质计算单价
  const pricePerMinute = {
    standard: 0.5,   // ¥0.5/分钟
    high: 1.0,      // ¥1.0/分钟
    lossless: 2.0   // ¥2.0/分钟
  }[quality] || 1.0;
  
  const totalPrice = audioMinutes * pricePerMinute;
  
  return {
    textLength,
    audioMinutes,
    pricePerMinute,
    totalPrice,
    displayText: `预计${audioMinutes}分钟音频，约¥${totalPrice.toFixed(1)}`
  };
}
```

### 📋 预估示例

| 文本字数 | 估算音频 | 标准音质 | 高清音质 | 无损音质 |
|---------|---------|---------|---------|---------|
| 300字 | 2分钟 | ¥1.0 | ¥2.0 | ¥4.0 |
| 750字 | 5分钟 | ¥2.5 | ¥5.0 | ¥10.0 |
| 1500字 | 10分钟 | ¥5.0 | ¥10.0 | ¥20.0 |
| 3000字 | 20分钟 | ¥10.0 | ¥20.0 | ¥40.0 |

---

## 五、余额扣费逻辑

### 🔧 实现方案

```typescript
// server/src/modules/audio/audio.service.ts

export const AUDIO_BILLING_CONFIG = {
  // 音频时长单价（按音质）
  pricePerMinute: {
    standard: 0.5,    // ¥0.5/分钟（基础版TTS）
    high: 1.0,       // ¥1.0/分钟（精品版TTS）
    lossless: 2.0    // ¥2.0/分钟（火山引擎）
  },
  
  // 语速配置（字/分钟）
  speakingRate: 150,
  
  // 每分钟Token消耗
  tokensPerMinute: 200  // AI处理消耗
};

// 计算音频生成费用
export function calculateAudioCost(
  textLength: number,
  quality: string = 'high'
): {
  audioMinutes: number;
  pricePerMinute: number;
  totalPrice: number;
  tokensUsed: number;
} {
  const audioMinutes = Math.ceil(textLength / AUDIO_BILLING_CONFIG.speakingRate);
  const pricePerMinute = AUDIO_BILLING_CONFIG.pricePerMinute[quality] || 1.0;
  const totalPrice = audioMinutes * pricePerMinute;
  const tokensUsed = audioMinutes * AUDIO_BILLING_CONFIG.tokensPerMinute;
  
  return {
    audioMinutes,
    pricePerMinute,
    totalPrice: Math.round(totalPrice * 100) / 100,
    tokensUsed
  };
}

// 扣费流程
export async function generateAudioWithBilling(
  userId: number,
  text: string,
  quality: string = 'high'
) {
  // 1. 计算费用
  const cost = calculateAudioCost(text.length, quality);
  
  // 2. 检查用户余额
  const balance = await getUserAudioBalance(userId);
  const remainingMinutes = balance.remainingMinutes;
  
  if (remainingMinutes < cost.audioMinutes) {
    throw new Error(`音频时长不足，需要${cost.audioMinutes}分钟，剩余${remainingMinutes}分钟`);
  }
  
  // 3. 扣除时长
  await prisma.audioBalance.update({
    where: { userId },
    data: { usedMinutes: { increment: cost.audioMinutes } }
  });
  
  // 4. 记录使用
  await prisma.audioUsage.create({
    data: {
      userId,
      type: 'audio_generation',
      minutesUsed: cost.audioMinutes,
      textLength: text.length,
      quality,
      cost: cost.totalPrice
    }
  });
  
  // 5. 生成音频
  const audioUrl = await callTTSAPI(text, quality);
  
  return {
    audioUrl,
    audioMinutes: cost.audioMinutes,
    cost: cost.totalPrice,
    remainingMinutes: remainingMinutes - cost.audioMinutes
  };
}
```

---

## 六、数据库模型

### 📋 Prisma Schema

```prisma
// 用户音频余额
model AudioBalance {
  id              Int      @id @default(autoincrement())
  userId          Int      @unique
  totalMinutes    Int      @default(30)    // 本月总时长
  usedMinutes     Int      @default(0)     // 已使用时长
  resetDate       DateTime @default(now())  // 重置日期
  createdAt       DateTime @default(now())
  updatedAt       DateTime @updatedAt
  
  user            User     @relation(fields: [userId], references: [id])
  
  @@map("audio_balance")
}

// 音频使用记录
model AudioUsage {
  id            Int      @id @default(autoincrement())
  userId        Int
  type          String   // 'generation' | 'download' | 'package_purchase'
  minutesUsed   Int      // 本次使用分钟数
  textLength    Int?     // 对应文本字数
  quality       String   // 'standard' | 'high' | 'lossless'
  cost          Float    // 实际费用
  audioUrl      String?  // 生成的音频URL
  createdAt     DateTime @default(now())
  
  user          User     @relation(fields: [userId], references: [id])
  
  @@map("audio_usage")
}

// 音频包产品
model AudioPackage {
  id          Int      @id @default(autoincrement())
  name        String   // '体验包' | '标准包' | '大量包'
  minutes     Int      // 时长（分钟）
  price       Float    // 价格
  discount    Float    @default(1.0)  // 折扣
  isActive    Boolean  @default(true)
  sortOrder   Int      @default(0)
  createdAt   DateTime @default(now())
  
  @@map("audio_package")
}

// 音频包购买记录
model AudioPackagePurchase {
  id          Int      @id @default(autoincrement())
  userId      Int
  packageId   Int
  minutes     Int      // 购买时长
  price       Float    // 实付金额
  status      String   @default("active")  // 'active' | 'expired' | 'used_up'
  expireDate  DateTime // 过期时间（购买后1年）
  createdAt   DateTime @default(now())
  
  package     AudioPackage @relation(fields: [packageId], references: [id])
  user        User         @relation(fields: [userId], references: [id])
  
  @@map("audio_package_purchase")
}
```

---

## 七、套餐对比表

| 功能 | 免费版 | 入门版 | 专业版 | 旗舰版 |
|------|--------|--------|--------|--------|
| **月费** | ¥0 | ¥9.9 | ¥49 | ¥199 |
| **音频时长** | 30分钟 | 100分钟 | 500分钟 | 2000分钟 |
| **单次最大** | 2分钟 | 5分钟 | 20分钟 | 60分钟 |
| **每日次数** | 3次 | 10次 | 不限 | 不限 |
| **音质** | 标准 | 高清 | 无损 | 无损 |
| **音色数量** | 5种 | 全部 | 全部+定制 | 全部+定制 |
| **TTS方案** | 科大讯飞 | 百度基础 | 百度精品 | 火山引擎 |
| **VIP队列** | ❌ | ❌ | ✅ | ✅ |
| **API访问** | ❌ | ❌ | ❌ | ✅ |
| **技术支持** | ❌ | ❌ | ❌ | ✅ |
| **批量处理** | ❌ | ❌ | ❌ | ✅ |
| **团队管理** | ❌ | ❌ | ❌ | ✅ |

---

## 八、用户体验设计

### 📱 生成前预估显示

```
┌─────────────────────────────────┐
│  📝 文本内容                    │
│  一键世遵处重与处重世尊无上正等 │
│  正觉。欲令众生皆得解脱...      │
│                                 │
│  ⏱️ 预计生成                    │
│  ┌─────────────────────────┐   │
│  │   📢 5分钟  🔊 高清音质  │   │
│  │   💰 约 ¥5.0             │   │
│  └─────────────────────────┘   │
│                                 │
│  [      生成音频      ]         │
└─────────────────────────────────┘
```

### 📊 个人中心显示

```
┌─────────────────────────────────┐
│  🎧 我的音频配额                │
│                                 │
│  本月已用：45分钟 / 500分钟     │
│  ████████░░░░░░░░░░  9%        │
│                                 │
│  剩余：455分钟（约75小时）       │
│                                 │
│  [续费套餐]  [购买音频包]        │
└─────────────────────────────────┘
```

---

## 九、定价总结

### 🎯 核心公式

```
生成费用 = 音频时长（分钟）× 单价（元/分钟）

单分钟成本 ≈ ¥0.34（DeepSeek + 基础TTS）
建议售价 ≈ ¥0.5-1.0/分钟（150-300%利润率）
```

### 📋 最终定价

| 套餐 | 月费 | 时长配额 | 折合单价 | 成本 | 利润 |
|------|------|---------|---------|------|------|
| 免费版 | ¥0 | 30分钟 | ¥0 | ¥10.2 | -¥10.2 |
| 入门版 | ¥9.9 | 100分钟 | ¥0.099 | ¥34 | -¥24.1 |
| 专业版 | ¥49 | 500分钟 | ¥0.098 | ¥170 | -¥121 |
| 旗舰版 | ¥199 | 2000分钟 | ¥0.10 | ¥680 | -¥481 |

> ⚠️ 注意：当前定价为获客转化策略，前期亏损运营，待用户规模扩大后可逐步提价。

---

## 十、下一步行动

- [ ] 更新 Prisma Schema 添加音频时长相关表
- [ ] 重写音频生成服务（按时长扣费）
- [ ] 更新前端预估成本UI
- [ ] 更新个人中心配额显示
- [ ] 添加音频包购买功能
- [ ] 测试验证完整流程
