音频时长计费系统设计.md 12 KB

音频时长计费系统设计

更新时间: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%

四、实时成本预估

📊 生成前预估

// 前端显示预估成本
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

五、余额扣费逻辑

🔧 实现方案

// 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

// 用户音频余额
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
  • 更新个人中心配额显示
  • 添加音频包购买功能
  • 测试验证完整流程