npm package: @iwhalecloud-lab/metamee-digital-picture2d-render
Description: MetaMee digital picture2d render - 支持图片、视频+Canvas等多种渲染模式的数字人口型同步库
Author: adam24
Latest version: 4.0.0

# @iwhalecloud-lab/metamee-digital-picture2d-render

数字人口型同步渲染库，支持多种渲染模式和智能口型匹配算法，特别适用于卡通数字人和 3D 虚拟角色场景。


## 1. 功能特点

- 支持自定义数字人形象视频
- 支持TTS文字转语音
- 支持队列播放
- 支持中断播放
- 支持自定义样式
- 支持自定义嘴型映射和音频分析精度
- 支持debug模式

---

## 2. 安装

```bash
npm install @iwhalecloud-lab/metamee-digital-picture2d-render
```

---

## 3. 使用方法

### 3.1 初始化（init）


调用 `init()` 完成数字人初始化，适用于卡通/3D 数字人场景，支持视频循环播放、动态口型叠加和绿幕抠图。

```javascript
import { init } from '@iwhalecloud-lab/metamee-digital-picture2d-render';

await init({
  id: 'avatar-container', // 挂载的DOM元素ID
  avatarImagePath: '/images/mouth/', // 口型图片目录，末尾带 /
  avatarImageFileName: 'man.gif', // 必填项
  avatarMouthStartFileName: 'a.png', // 初始口型
  avatarVideoPath: '/videos/', // 视频文件路径
  avatarVideoFileName: 'character-no-mouth.mp4',   // 说话视频（无嘴巴）
  avatarIdleVideoFileName: 'character-idle.mp4',   // 待机视频，即静默视频
  render: 'video-canvas', // 渲染模式
  width: 400, // 宽度
  height: 400, // 高度
  videoFps: 25, // 必传项 - 视频帧
  fftSize: 2048, // 音频分析精度, 默认值为 2048
  angleDataUrl: '/data/angle.json', // 口型角度数据文件所在目录
  angleData: [
    {
      frame: 0,
      dst_center_x: 0.49722222222222223,
      dst_center_y: 0.5907407407407408,
      angle: 0.0,
      scale: 1.0,
    }
  ], // 口型角度数据 - 此处是示例
  mouthTypeOrder: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], // 按开口程度从小到大排列的口型类型列表, 对应口型图片例：a.png
  chromaKey: true, // 是否启用绿幕抠图  
  debug: false, // 开启后控制台会打印相关日志信息
  // 自定义口型映射
  mouthTypeMappings: [
    { threshold: 240, type: 'f' },
    { threshold: 180, type: 'd' },
    { threshold: 140, type: 'h' },
    { threshold: 100, type: 'e' },
    { threshold: 60, type: 'c' },
    { threshold: 40, type: 'g' },
    { threshold: 20, type: 'b' },
    { threshold: -Infinity, type: 'a' } // 默认情况
  ],
  onLoadProgress: (progress, total, message) => {
    console.log(`[${progress}/${total}] ${message}`);
  },
  options: {
    onSuccess: () => console.log('初始化成功'),
    onError: (err) => console.error('初始化失败:', err)
  }
});
```

#### angle.json 数据格式

`angle.json` 记录每一帧口型图片的位置、旋转和缩放信息，推荐使用归一化坐标（0~1）以适配不同 Canvas 尺寸：

```json
[
  {
    "frame": 0,
    "dst_center_x": 0.49722222222222223,
    "dst_center_y": 0.5907407407407408,
    "angle": 0.0,
    "scale": 1.0,
  }
]
```

| 字段 | 类型 | 说明 | 必填 |
|------|------|------|------|
| frame | number | 视频帧序号 | 是 |
| dst_center_x | number | 归一化 X 坐标（0~1） | 是 |
| dst_center_y | number | 归一化 Y 坐标（0~1） | 是 |
| angle | number | 旋转角度（度） | 是 |
| scale | number | 缩放比例 | 否（默认 1） |

---

### 3.2 发送 TTS 请求（sendToTTS）

调用 `sendToTTS()` 发送文本转语音请求，支持多条文本排队顺序播放。

```javascript
import { sendToTTS } from '@iwhalecloud-lab/metamee-digital-picture2d-render';

sendToTTS({
  url: 'https://api.example.com/tts', // // TTS服务地址
  text: '你好，我是数字人助手', // // 要转换的文本内容
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_TOKEN'
  },
  data: {}, // 额外参数（可选）
  options: {
    onSuccess: () => console.log('TTS 转换成功'),
    onPlay: (msg) => console.log('开始播放:', msg.text, '时长:', msg.duration, '秒'),
    onEnd: (msg) => console.log('播放结束:', msg.text),
    onError: (err) => console.error('TTS 失败:', err)
  }
});

// 多条文本将按调用顺序依次播放
sendToTTS({ url: '...', text: '第二句话', options: { ... } });
```

---

### 3.3 中断播放（abort）

调用 `abort()` 立即中断当前播放，清空队列，并将画面切回静默视频（如已配置）。

```javascript
import { abort } from '@iwhalecloud-lab/metamee-digital-picture2d-render';

// 中断当前播放、清空队列、重置所有状态
abort();
```

---

## 4. API 文档

### 4.1 InitConfig 配置项

`init()` 函数的完整配置项：

| 字段 | 类型 | 说明 | 是否必填 | 默认值 |
|------|------|------|----------|--------|
| id | `string` | 挂载的 DOM 元素 ID | 是 | - |
| avatarImagePath | `string` | 资源路径（口型图片/形象图片） | 是 | - |
| avatarImageFileName | `string` | 静态形象图片 | 是 | - |
| avatarMouthStartFileName | `string` | 初始口型图片 | 是 | - |
| height | `string \| number` | 渲染高度 | 否 | - |
| width | `string \| number` | 渲染宽度 | 否 | - |
| render | `'video-canvas'` | 渲染模式 | 是 | - |
| debug | `boolean` | 是否开启调试模式 | 否 | `false` |
| mouthTypeMappings | `Array<MouthTypeMapping>` | 音量阈值与嘴型映射表 | 是 | - |
| mouthTypeOrder | `string[]` | 按开口程度从小到大排列的口型类型列表 | 是 | - |
| fftSize | `number` | 音频分析 FFT 精度（32~32768，须为 2 的幂） | 否 | `2048` |
| avatarVideoFileName | `string` | 说话视频文件名（无嘴巴） | 是 | - |
| avatarIdleVideoFileName | `string` | 静默/待机视频文件名 | 否 | - |
| avatarVideoPath | `string` | 视频文件路径（独立于 avatarImagePath） | 否 | - |
| angleDataUrl | `string` | angle.json 数据 URL | 是 | - |
| angleData | `Array<AngleData>` | 直接传入的角度数据 | 是 | - |
| videoFps | `number` | 视频帧率 | 否 | 默认 `25` |
| chromaKey | `boolean` | 是否启用绿幕抠图 | 否 | `false` |
| onLoadProgress | `(progress, total, message) => void` | 资源加载进度回调 | 否 | - |
| options | `Options` | 初始化回调函数配置 | 否 | - |

**默认 mouthTypeMappings 值：**

```javascript
[
  { threshold: 240, type: 'f' },   // 最大开口
  { threshold: 180, type: 'd' },
  { threshold: 140, type: 'h' },
  { threshold: 100, type: 'e' },
  { threshold: 60,  type: 'c' },
  { threshold: 20,  type: 'b' },
  { threshold: -Infinity, type: 'a' }  // 闭口（默认）
]
```

---

### 4.2 Options 回调配置

`init()` 中 `options` 字段的回调函数定义：

| 字段 | 类型 | 说明 |
|------|------|------|
| onSuccess | `() => void` | 初始化成功回调 |
| onError | `(errMsg: any) => void` | 初始化失败回调 |

**TTSOptions — sendToTTS 播放回调：**

| 字段 | 类型 | 说明 |
|------|------|------|
| onSuccess | `() => void` | TTS 转换成功回调 |
| onPlay | `(msg: any) => void` | 开始播放回调，msg 包含 `text` 和 `duration`（秒） |
| onEnd | `(msg: any) => void` | 播放结束回调 |
| onError | `(errMsg: any) => void` | 失败回调 |

---

### 4.3 ttsConfig 配置项

`sendToTTS()` 函数的完整配置项：

| 字段 | 类型 | 说明 | 是否必填 |
|------|------|------|----------|
| url | `string` | TTS 服务请求地址 | 是 |
| text | `string` | 要转换的文本内容 | 是 |
| headers | `HeadersInit` | 自定义请求头 | 否 |
| data | `any` | 额外传递的请求参数 | 否 |
| options | `TTSOptions` | 播放回调函数配置 | 否 |

---

## 5. 注意事项

1. 确保提供的图片/视频资源路径正确，口型图片命名需与配置的口型类型一一对应（如 `a.png`、`b.png` 等）。
2. **说话视频**（`avatarVideoFileName`）应为无嘴巴的视频文件，运行时会动态叠加口型图片；**静默视频**（`avatarIdleVideoFileName`）应为包含完整嘴巴的待机动画，播放时不会叠加口型。
3. `angle.json` 中的帧数需与视频帧率严格对应，推荐使用归一化坐标（`dst_center_x`、`dst_center_y`），以适配不同尺寸的 Canvas。
4. 视频格式建议使用 MP4（H.264 编码），推荐分辨率 1080p，帧率 25~30fps；说话视频与静默视频建议保持相同分辨率和帧率，以确保切换流畅。
5. 需确保浏览器支持 Web Audio API；在部分浏览器中，音频上下文可能需要用户首次交互后才能激活（autoplay policy），库内已内置交互监听器自动处理此场景。

---

## 6. 浏览器支持

本库依赖以下浏览器 API：

| 功能 | Chrome | Firefox | Safari | Edge |
|------|--------|---------|--------|------|
| Web Audio API | ✅ 49+ | ✅ 25+ | ✅ 14.1+ | ✅ 14+ |
| Canvas 2D | ✅ | ✅ | ✅ | ✅ |
| HTMLVideoElement | ✅ | ✅ | ✅ | ✅ |
| WebGL（绿幕抠图） | ✅ | ✅ | ✅ 15+ | ✅ |
| Blob / createObjectURL | ✅ | ✅ | ✅ | ✅ |

> **注意**：iOS Safari 对 autoplay 有严格限制，音频播放需在用户交互事件（`click` / `touchstart`）的回调中触发，库内已内置处理逻辑。

---