@siliconoid/xssml-editor
v1.0.12
Published
A professional X-SSML editor built with React and ProseMirror.
Readme
@siliconoid/xssml-editor
基于 ProseMirror 的 XSSML 富文本编辑器 SDK,支持语音合成标记语言 (XSSML) 的可视化编辑。
✨ 特性
- 🎯 XSSML 标准对齐 - 基本遵循 W3C XSSML 1.1 规范
- 🔌 可扩展架构 - Registry 模式支持自定义扩展
- 📦 模块化设计 - Command/Node/Mark/Plugin 分离
- 🛡️ 类型安全 - 完整的 TypeScript 类型定义
- 🔍 内容提取 - 内置分句与段落提取引擎 (TextExtractor)
📦 安装
npm install @siliconoid/xssml-editor🚀 快速开始
import { MarkEditor, SayAsCommands, SayAsInterpretType } from '@siliconoid/xssml-editor';
import '@siliconoid/xssml-editor/dist/index.css';
// 创建编辑器
const editor = new MarkEditor({
parent: document.getElementById('editor')!,
content: '',
});
// 设置数字读法
editor.execute(SayAsCommands.setSayAs, {
interpretAs: SayAsInterpretType.cardinal,
});
// 获取内容
const content = editor.getContent();📖 核心 API (Core API)
MarkEditor
编辑器核心实例,管理文档状态与命令执行。
初始化
import { MarkEditor } from '@siliconoid/xssml-editor';
import '@siliconoid/xssml-editor/dist/index.css';
const editor = new MarkEditor({
parent: document.getElementById('editor-root')!, // 挂载容器
content: '', // 初始内容 (JSON 或空字符串)
maxWordCount: 1000, // 最大字数限制
editable: true, // 是否可编辑
// 自定义悬浮菜单渲染
floatingMenu: {
onRender: (mountPoint, state) => {
// 在 mountPoint 中渲染您的自定义菜单
// state.isActive: 是否显示
// state.selection: 当前选区信息
},
},
// 自定义右键菜单渲染
contextMenu: {
onRender: (mountPoint, state) => {
// 在 mountPoint 中渲染您的自定义菜单
},
},
});常用属性
| 属性 | 类型 | 说明 |
| :--------- | :-------- | :---------------------------------- |
| editable | boolean | 获取或设置编辑器的读写状态 |
| count | number | [只读] 获取当前文档的有效字符数 |
常用方法
| 方法 | 说明 | 示例 |
| :------------------------- | :---------------------------------- | :---------------------------------------------------------- |
| setContent(json) | 设置编辑器内容 (JSON格式) | editor.setContent(docJSON) |
| setContentFromSSML(ssml) | 解析并导入 XSSML 字符串 | editor.setContentFromSSML('<speak>Hello</speak>') |
| setContentFromHTML(html) | 解析并导入 HTML (自动兼容旧版标记) | editor.setContentFromHTML('<p>Text</p>') |
| execute(cmd, args) | 执行编辑器命令 | editor.execute(BreakCommands.insertBreak, { value: 500 }) |
| toJSON() | 导出标准的 JSON 文档结构 | const doc = editor.toJSON() |
| getPlainText(mode?) | 获取纯文本 (支持全文/选区/光标后) | editor.getPlainText({ contentMode: 'selection' }) |
| getDetermination() | 获取提取后的播放片段列表 | editor.getPlaybackSegments() |
| getSelection() | 获取当前选区信息 (start, end, text) | const { text } = editor.getSelection() |
| destroy() | 销毁编辑器实例 | editor.destroy() |
事件监听
// 监听字数变化
editor.on('wordCount', ({ count, exceeded }) => {
console.log(`当前字数: ${count}`, exceeded ? '已超限' : '');
});
// 监听命令状态变化 (用于更新 UI 按钮状态)
editor.on('stateChange', ({ commands }) => {
const isUndoable = commands['undo'].available;
});
// 监听富媒体点击 (如图片被点击)
editor.on('plugin.textmedia_click', (data) => {
console.log('Clicked:', data);
});🛠️ 命令系统 (Commands)
所有命令均通过 editor.execute(Command, payload) 调用。
1. 语音标注 (TTS)
控制语音合成的核心参数。
import {
BreakCommands,
SayAsCommands,
SayAsInterpretType,
SpeechRateCommands,
} from '@siliconoid/xssml-editor';
// 插入 500ms 停顿
editor.execute(BreakCommands.insertBreak, { value: 500 }); // value: ms
// 插入换气
editor.execute(BreathCommands.insertBreath);
// 设置选中文本的读法 (如:数值)
editor.execute(SayAsCommands.setSayAs, {
interpretAs: SayAsInterpretType.cardinal, // 'digits' | 'cardinal' | ...
});
// 调整选中文本的语速
editor.execute(SpeechRateCommands.setSpeechRate, { value: 1.5 }); // value:倍率
// 开启/关闭多音字建议模式
editor.execute(PhonemeCommands.switchPhonemeMode, { active: true });2. 交互与数字人 (Interaction & Avatar)
用于控制数字人动作或互动逻辑。
import { ActionCommands, WaitCommands, CmdCommands } from '@siliconoid/xssml-editor';
// 插入动作 (动作ID, 动作名称)
editor.execute(ActionCommands.insertAction, { value: 'wave_hand', label: '招手' });
// 插入等待指令 (等待类型, 参数)
editor.execute(WaitCommands.insertWait, {
waitType: 'video_ended', // 'sleep' | 'video_ended' | 'audio_ended'
label: '等待视频结束',
});
// 插入自定义指令
editor.execute(CmdCommands.insertCmd, { value: 'custom_cmd', label: '自定义指令' });3. 特效与资源 (Effect & Media)
import { SoundEventCommands, TextMediaCommands } from '@siliconoid/xssml-editor';
// 插入音效
editor.execute(SoundEventCommands.insertSoundEvent, {
value: 'applause.mp3',
label: '欢呼声',
volume: 80,
});
// 插入或更新图片/视频 (TextMedia)
editor.execute(TextMediaCommands.setTextMedia, {
src: 'https://example.com/image.png',
mediaType: 'image',
extra: 'some_metadata',
});4. 基础编辑 (Basis)
import { HistoryCommands, TextInputCommands, HighlightCommands } from '@siliconoid/xssml-editor';
// 撤销 / 重做
editor.execute(HistoryCommands.undo);
editor.execute(HistoryCommands.redo);
// 替换指定范围文本 (常用于 AI 润色)
editor.execute(TextInputCommands.replaceRange, {
from: 0,
to: 5,
content: 'New Text',
});
// 高亮范围 / 清除高亮
editor.execute(HighlightCommands.highlight, { from: 0, to: 10 });
editor.execute(HighlightCommands.clearHighlight);🧩 文本提取引擎 (TextExtractor)
TextExtractor 是一个独立的无头工具,用于将结构化的编辑器 JSON 数据转换为扁平化的播放列表或合成请求序列。
import { TextExtractor } from '@siliconoid/xssml-editor';
const extractor = new TextExtractor();
const docJSON = editor.toJSON();
// 1. 提取所有句子 (自动处理标点分句)
const sentences = extractor.extractSentences(docJSON);
sentences.forEach((s) => {
console.log(`[${s.start}-${s.end}] ${s.text}`);
// s.events 包含该句子内的动作、音效等指令
});
// 2. 按段落提取 (保留段落结构和段落级指令)
const paragraphResult = extractor.paragraphize(docJSON);
console.log(paragraphResult.paragraphs);📁 目录结构
dist/
├── index.js # CJS (Legacy)
├── index.esm.js # ESM (Recommended)
├── index.umd.js # UMD (Browser Global: XSSMLEditor)
├── index.css # Core Styles
└── index.d.ts # Typings📄 许可证
MIT
