mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-24 21:51:02 +03:00
chore(repo): нормализация EOL к LF + .gitattributes
Приводим авторский контент (.ps1/.psm1/.py/.mjs/.md/.json, пин .bsl) к единому LF и закрепляем политикой в .gitattributes. Инструмент правки всегда пишет LF, поэтому единый LF убирает EOL-шум в диффах, ложные срабатывания blame и налог на ручную синхронизацию CRLF-файлов. BOM на .ps1 сохранён (git с eol=lf меняет только CR<->LF, BOM не трогает). Данные 1С (*.xml) и бинарники под нормализацию не берём. Гейт: PS-порт 459/459, Python-порт 459/459, web-test E2E 22/22 (с пересборкой стенда). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
9eb9571e95
commit
26888a07d5
+386
-386
@@ -1,386 +1,386 @@
|
||||
# Запись видеоинструкций
|
||||
|
||||
Навык `/web-test` умеет записывать видеоинструкции по работе в 1С: автоматические действия в браузере записываются в MP4 с субтитрами, подсветкой элементов и голосовой озвучкой. Результат — готовое обучающее видео.
|
||||
|
||||
```
|
||||
сценарий → запись экрана → субтитры → подсветка → озвучка голосом → MP4
|
||||
```
|
||||
|
||||
## Предусловия
|
||||
|
||||
Все пути и настройки хранятся в `.v8-project.json` — см. [справочник формата](v8-project-guide.md).
|
||||
|
||||
### ffmpeg (обязательно)
|
||||
|
||||
Выберите один из вариантов:
|
||||
|
||||
1. **В проект** (рекомендуется) — скачать essentials build с https://www.gyan.dev/ffmpeg/builds/, распаковать в `tools/ffmpeg/`. Код найдёт `tools/ffmpeg/bin/ffmpeg.exe` автоматически
|
||||
|
||||
2. **Глобально** — скачать, распаковать в любой каталог, добавить `bin/` в системный PATH
|
||||
|
||||
3. **Через конфиг** — указать путь в `.v8-project.json`:
|
||||
```json
|
||||
{ "ffmpegPath": "C:\\tools\\ffmpeg\\bin\\ffmpeg.exe" }
|
||||
```
|
||||
|
||||
### node-edge-tts (для озвучки)
|
||||
|
||||
```bash
|
||||
npm install --prefix tools/tts node-edge-tts
|
||||
```
|
||||
|
||||
Бесплатный, без API-ключа. Если не установлен — запись видео работает, только озвучка недоступна.
|
||||
|
||||
### Конфигурация голоса в `.v8-project.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"ffmpegPath": "tools/ffmpeg/bin/ffmpeg.exe",
|
||||
"tts": {
|
||||
"provider": "edge",
|
||||
"voice": "ru-RU-DmitryNeural"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
Минимальный сценарий — запись 3 шагов с озвучкой:
|
||||
|
||||
```js
|
||||
// Начинаем запись
|
||||
await startRecording('recordings/demo.mp4');
|
||||
|
||||
// Субтитры + действия
|
||||
await showCaption('Переходим в раздел «Продажи»');
|
||||
await wait(1.5);
|
||||
await navigateSection('Продажи');
|
||||
|
||||
await showCaption('Открываем заказы клиентов');
|
||||
await wait(1.5);
|
||||
await openCommand('Заказы клиентов');
|
||||
|
||||
await showCaption('Создаём новый заказ');
|
||||
await wait(1.5);
|
||||
await clickElement('Создать');
|
||||
await wait(2);
|
||||
|
||||
// Завершаем запись
|
||||
await hideCaption();
|
||||
const video = await stopRecording();
|
||||
console.log(`Записано: ${video.duration.toFixed(1)}s`);
|
||||
|
||||
// Озвучка
|
||||
const narrated = await addNarration(video.file, {
|
||||
ffmpegPath: 'tools/ffmpeg/bin/ffmpeg.exe',
|
||||
voice: 'ru-RU-DmitryNeural',
|
||||
});
|
||||
console.log(`Озвучено: ${narrated.file}`);
|
||||
```
|
||||
|
||||
Результат: `recordings/demo-narrated.mp4` — видео с голосовым сопровождением.
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Запись без озвучки
|
||||
|
||||
Простейший вариант — субтитры на экране, без голоса:
|
||||
|
||||
```
|
||||
> Запиши видеоинструкцию: открой раздел Продажи, создай заказ клиента,
|
||||
> заполни организацию и контрагента. Без озвучки
|
||||
```
|
||||
|
||||
Claude запишет видео с субтитрами и подсветкой элементов.
|
||||
|
||||
### Запись с озвучкой
|
||||
|
||||
Полный pipeline — голос озвучивает каждый шаг:
|
||||
|
||||
```
|
||||
> Запиши озвученную видеоинструкцию по созданию заказа клиента.
|
||||
> Голос — Светлана
|
||||
```
|
||||
|
||||
Claude запишет видео, затем наложит голосовую дорожку. Субтитры показываются на экране, параллельно звучит голос.
|
||||
|
||||
### Переозвучка другим голосом
|
||||
|
||||
Видео уже записано — хотите другой голос? Не нужно перезаписывать:
|
||||
|
||||
```
|
||||
> Переозвучь recordings/demo.mp4 голосом Светланы
|
||||
```
|
||||
|
||||
Claude вызовет `addNarration` с другим голосом. Тексты берутся из файла `.captions.json`, который сохраняется рядом с видео при записи.
|
||||
|
||||
### Редактирование субтитров
|
||||
|
||||
После записи рядом с видео появляется файл `video.captions.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"videoTimestamps": true,
|
||||
"captions": [
|
||||
{ "text": "Переходим в раздел «Продажи»", "speech": "Переходим в раздел Продажи", "time": 3160 },
|
||||
{ "text": "Открываем заказы клиентов", "speech": "Открываем заказы клиентов", "time": 7040, "voice": "bqbHGIIO5oETYIqhWmfk" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Можно отредактировать `speech` (текст озвучки) или добавить `voice` (голос для конкретной реплики) и переозвучить:
|
||||
|
||||
```
|
||||
> Отредактируй субтитры в recordings/demo.captions.json — замени "Продажи" на
|
||||
> "раздел Продажи", потом переозвучь
|
||||
```
|
||||
|
||||
## Приёмы
|
||||
|
||||
### Титульный слайд
|
||||
|
||||
Полноэкранная заставка в начале видео. Поддерживает озвучку через `speech`:
|
||||
|
||||
```js
|
||||
await startRecording('recordings/demo.mp4');
|
||||
await showTitleSlide('Создание заказа клиента', {
|
||||
subtitle: '1С:Бухгалтерия в примерах',
|
||||
speech: 'Создание заказа клиента. Бухгалтерия в примерах.'
|
||||
});
|
||||
await wait(1);
|
||||
await hideTitleSlide();
|
||||
// ... далее контент
|
||||
```
|
||||
|
||||
### Слайды из презентации
|
||||
|
||||
Показать изображение (скриншот слайда, схему и т.д.) как полноэкранный оверлей с озвучкой:
|
||||
|
||||
```js
|
||||
await showImage('slides/overview.png', {
|
||||
speech: 'На этом слайде показана общая схема процесса'
|
||||
});
|
||||
await wait(1);
|
||||
await hideImage();
|
||||
```
|
||||
|
||||
Стили оформления (`style`):
|
||||
- `'blur'` (по умолчанию) — размытый фон из картинки + тень. Лучший для презентаций
|
||||
- `'dark'` — тёмный фон + тень
|
||||
- `'light'` — белый фон + тень
|
||||
- `'full'` — на весь экран без отступов
|
||||
|
||||
```js
|
||||
await showImage('slides/diagram.png', { style: 'dark', speech: 'Диаграмма процесса' });
|
||||
```
|
||||
|
||||
### Подсветка элементов
|
||||
|
||||
Полупрозрачная рамка на элементе, который сейчас используется. Два режима:
|
||||
|
||||
- **Авторежим** — `setHighlight(true)` перед началом действий. Каждая функция (`navigateSection`, `clickElement`, `fillFields` и т.д.) автоматически подсвечивает элемент перед действием
|
||||
- **Ручная** — `highlight('Провести')` для произвольной подсветки конкретного элемента
|
||||
|
||||
```js
|
||||
setHighlight(true); // включить авто
|
||||
// ... все действия подсвечиваются автоматически
|
||||
setHighlight(false); // выключить перед stopRecording
|
||||
```
|
||||
|
||||
### Паузы и ритм
|
||||
|
||||
Ритм «субтитр → пауза → действие» даёт зрителю время прочитать, что произойдёт:
|
||||
|
||||
```js
|
||||
await showCaption('Проводим документ'); // зритель читает
|
||||
await wait(1.5); // пауза 1.5 сек
|
||||
await clickElement('Провести'); // действие
|
||||
```
|
||||
|
||||
Пауза после действия нужна только когда загружается следующая форма:
|
||||
|
||||
```js
|
||||
await clickElement('Создать');
|
||||
await wait(2); // форма загружается
|
||||
```
|
||||
|
||||
### Два голоса (подкаст / диалог)
|
||||
|
||||
Параметр `voice` в `showCaption` задаёт голос для конкретной реплики. `addNarration` автоматически использует его вместо глобального:
|
||||
|
||||
```js
|
||||
const MALE = 'bqbHGIIO5oETYIqhWmfk'; // Alexander
|
||||
const FEMALE = '0ArNnoIAWKlT4WweaVMY'; // Elena Gromova
|
||||
|
||||
// speechRate: 85 — ElevenLabs медленнее Edge TTS, нужен запас
|
||||
await startRecording('podcast.mp4', { speechRate: 85 });
|
||||
|
||||
await showImage('slides/slide-01.png', { style: 'full', speech: false });
|
||||
await showCaption('', { speech: 'Привет! Сегодня поговорим...', voice: MALE });
|
||||
await wait(0.8);
|
||||
await showCaption('', { speech: 'А я буду задавать вопросы...', voice: FEMALE });
|
||||
await wait(0.8);
|
||||
|
||||
const video = await stopRecording();
|
||||
const result = await addNarration(video.file, {
|
||||
provider: 'elevenlabs',
|
||||
apiKey: 'sk_...',
|
||||
// глобальный voice не нужен — каждый caption несёт свой
|
||||
});
|
||||
```
|
||||
|
||||
Приёмы:
|
||||
- `showCaption('', { speech, voice })` — пустой текст (без субтитра на экране), но speech записывается для озвучки
|
||||
- `showImage` со `speech: false` — слайд без озвучки, реплики идут через `showCaption`
|
||||
- `speechRate: 85` — для ElevenLabs увеличиваем множитель (по умолчанию 70мс/символ), чтобы фразы не наезжали друг на друга
|
||||
|
||||
### Разделение текста и озвучки
|
||||
|
||||
Параметр `speech` в `showCaption` позволяет показывать одно, а озвучивать другое:
|
||||
|
||||
```js
|
||||
// Субтитр технический, озвучка человечная
|
||||
await showCaption('Дт 60.02 — Кт 51', {
|
||||
speech: 'Дебет шестьдесят ноль два — кредит пятьдесят один'
|
||||
});
|
||||
|
||||
// Показать субтитр, но НЕ озвучивать
|
||||
await showCaption('Технические детали', { speech: false });
|
||||
```
|
||||
|
||||
Это полезно для:
|
||||
- **Бухгалтерских проводок** — на экране формула, голосом — словами
|
||||
- **Технических данных** — показать, но не зачитывать
|
||||
- **Информационных плашек** — немой субтитр на несколько секунд
|
||||
|
||||
## Доступные голоса и провайдеры
|
||||
|
||||
### Какой провайдер выбрать?
|
||||
|
||||
| Провайдер | Тембр | Произношение русского | Цена |
|
||||
|-----------|-------|----------------------|------|
|
||||
| **Edge TTS** | Синтетичнее | Корректные ударения, правильная артикуляция | Бесплатно |
|
||||
| **ElevenLabs** | Живее, естественнее | Возможны ошибки в ударениях и артикуляции (напр. «докумЭнт», «крЕдит» вместо «кредИт») | Платно (starter+) |
|
||||
| **OpenAI** | Зависит от голоса | Зависит от сервиса | Платно |
|
||||
|
||||
**Для русскоязычных видеоинструкций рекомендуется Edge TTS** — он бесплатный и даёт надёжное качество русской речи. Голоса DmitryNeural и SvetlanaNeural специально обучены для русского языка: правильно расставляют ударения, корректно артикулируют и делают паузы в нужных местах.
|
||||
|
||||
**ElevenLabs** даёт более живой, «человечный» тембр — голос звучит менее синтетически. Однако мультиязычная модель иногда ошибается в произношении русских слов (особенно профессиональная терминология). Если выбираете ElevenLabs для русского контента — берите **professional-голоса** с образовательным или деловым профилем (например, Olga Orlova, Artem), они дают лучший результат, чем англоязычные premade-голоса через мультиязычную модель. Управлять ударениями через API нельзя — фонемные теги (SSML) поддерживаются только для английских моделей.
|
||||
|
||||
### Edge TTS (бесплатный) — рекомендуется для русского
|
||||
|
||||
| Голос | Описание |
|
||||
|-------|----------|
|
||||
| `ru-RU-DmitryNeural` | Мужской, русский — спокойный, деловой |
|
||||
| `ru-RU-SvetlanaNeural` | Женский, русский — чёткий, уверенный |
|
||||
|
||||
Полный список: `en-US-AriaNeural`, `en-US-GuyNeural`, `de-DE-ConradNeural` и другие. Edge TTS поддерживает десятки языков.
|
||||
|
||||
Конфигурация не нужна — Edge TTS используется по умолчанию. Для смены голоса:
|
||||
|
||||
```json
|
||||
{
|
||||
"tts": {
|
||||
"voice": "ru-RU-SvetlanaNeural"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### ElevenLabs (платный) — живой тембр
|
||||
|
||||
Модель `eleven_multilingual_v2` поддерживает русский. Тембр заметно живее, чем у Edge TTS, но возможны артикуляционные ошибки на русской терминологии.
|
||||
|
||||
Для русского контента выбирайте **professional-голоса** с образовательным/деловым профилем из Voice Library:
|
||||
|
||||
| Голос | ID | Профиль |
|
||||
|-------|----|---------|
|
||||
| Olga Orlova | `d60rsXo2p0OwikDR5bS7` | Clear and Engaging |
|
||||
| Artem | `WTn2eCRCpoFAC50VD351` | Friendly & Professional |
|
||||
| Denis | `0BcDz9UPwL3MpsnTeUlO` | Pleasant, Engaging and Friendly |
|
||||
| Alexander | `bqbHGIIO5oETYIqhWmfk` | Pleasant, Warm and Natural |
|
||||
| Elena Gromova | `0ArNnoIAWKlT4WweaVMY` | Podcasts & Conversation |
|
||||
| Victor | `9fjVd0EYNNXHllJquVdT` | Moscow accent |
|
||||
|
||||
```json
|
||||
{
|
||||
"tts": {
|
||||
"provider": "elevenlabs",
|
||||
"apiKey": "sk_...",
|
||||
"voice": "d60rsXo2p0OwikDR5bS7"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`voice` — ID голоса (не имя). Professional-голоса добавляются в аккаунт через Voice Library в личном кабинете. Требуется платный тариф (starter и выше).
|
||||
|
||||
Особенности: лимит на параллельные запросы (2–3 одновременно), система автоматически ограничивает размер пакета.
|
||||
|
||||
### OpenAI-compatible (платный)
|
||||
|
||||
```json
|
||||
{
|
||||
"tts": {
|
||||
"provider": "openai",
|
||||
"apiKey": "sk-...",
|
||||
"voice": "alloy"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Голоса: `alloy`, `echo`, `fable`, `onyx`, `nova`, `shimmer`.
|
||||
|
||||
Поле `apiUrl` позволяет подключить любой OpenAI-совместимый сервис (например, локальный TTS-прокси).
|
||||
|
||||
## Полный пример
|
||||
|
||||
Типовая структура озвученного сценария:
|
||||
|
||||
```js
|
||||
await startRecording('output.mp4');
|
||||
|
||||
// Титульный слайд с озвучкой
|
||||
await showTitleSlide('Заголовок', {
|
||||
subtitle: 'Подзаголовок',
|
||||
speech: 'Заголовок. Подзаголовок.'
|
||||
});
|
||||
await wait(1);
|
||||
await hideTitleSlide();
|
||||
|
||||
// Слайд из презентации (опционально)
|
||||
await showImage('slides/overview.png', {
|
||||
speech: 'Описание слайда для озвучки'
|
||||
});
|
||||
await wait(1);
|
||||
await hideImage();
|
||||
|
||||
setHighlight(true);
|
||||
|
||||
// ... шаги с showCaption + действия ...
|
||||
|
||||
await hideCaption();
|
||||
setHighlight(false);
|
||||
const video = await stopRecording();
|
||||
|
||||
const narrated = await addNarration(video.file, {
|
||||
ffmpegPath: 'tools/ffmpeg/bin/ffmpeg.exe',
|
||||
voice: 'ru-RU-SvetlanaNeural',
|
||||
});
|
||||
```
|
||||
|
||||
## Типичные проблемы
|
||||
|
||||
| Проблема | Решение |
|
||||
|----------|---------|
|
||||
| `ffmpeg not found` | Установите ffmpeg (см. Предусловия) |
|
||||
| Файл записи 0 байт | Проверьте права на запись в выходной каталог |
|
||||
| Видео дёргается | Добавьте `wait()` между шагами |
|
||||
| `Already recording` | Вызовите `stopRecording()` перед новой записью |
|
||||
| `No captions available` | Используйте `showCaption()` во время записи |
|
||||
| TTS timeout | Проверьте интернет-соединение (Edge TTS требует сеть) |
|
||||
| Озвучка обрезается | Увеличьте паузы `wait()` между субтитрами |
|
||||
| Фразы наезжают друг на друга | Увеличьте `speechRate` в `startRecording` (85 для ElevenLabs) |
|
||||
|
||||
## Связанные навыки
|
||||
|
||||
- [Тестирование через веб-клиент](web-test-guide.md) — навигация, формы, таблицы, отчёты
|
||||
- [Веб-публикация](web-guide.md) — `/web-publish`, `/web-info`, `/web-stop`
|
||||
# Запись видеоинструкций
|
||||
|
||||
Навык `/web-test` умеет записывать видеоинструкции по работе в 1С: автоматические действия в браузере записываются в MP4 с субтитрами, подсветкой элементов и голосовой озвучкой. Результат — готовое обучающее видео.
|
||||
|
||||
```
|
||||
сценарий → запись экрана → субтитры → подсветка → озвучка голосом → MP4
|
||||
```
|
||||
|
||||
## Предусловия
|
||||
|
||||
Все пути и настройки хранятся в `.v8-project.json` — см. [справочник формата](v8-project-guide.md).
|
||||
|
||||
### ffmpeg (обязательно)
|
||||
|
||||
Выберите один из вариантов:
|
||||
|
||||
1. **В проект** (рекомендуется) — скачать essentials build с https://www.gyan.dev/ffmpeg/builds/, распаковать в `tools/ffmpeg/`. Код найдёт `tools/ffmpeg/bin/ffmpeg.exe` автоматически
|
||||
|
||||
2. **Глобально** — скачать, распаковать в любой каталог, добавить `bin/` в системный PATH
|
||||
|
||||
3. **Через конфиг** — указать путь в `.v8-project.json`:
|
||||
```json
|
||||
{ "ffmpegPath": "C:\\tools\\ffmpeg\\bin\\ffmpeg.exe" }
|
||||
```
|
||||
|
||||
### node-edge-tts (для озвучки)
|
||||
|
||||
```bash
|
||||
npm install --prefix tools/tts node-edge-tts
|
||||
```
|
||||
|
||||
Бесплатный, без API-ключа. Если не установлен — запись видео работает, только озвучка недоступна.
|
||||
|
||||
### Конфигурация голоса в `.v8-project.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"ffmpegPath": "tools/ffmpeg/bin/ffmpeg.exe",
|
||||
"tts": {
|
||||
"provider": "edge",
|
||||
"voice": "ru-RU-DmitryNeural"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
Минимальный сценарий — запись 3 шагов с озвучкой:
|
||||
|
||||
```js
|
||||
// Начинаем запись
|
||||
await startRecording('recordings/demo.mp4');
|
||||
|
||||
// Субтитры + действия
|
||||
await showCaption('Переходим в раздел «Продажи»');
|
||||
await wait(1.5);
|
||||
await navigateSection('Продажи');
|
||||
|
||||
await showCaption('Открываем заказы клиентов');
|
||||
await wait(1.5);
|
||||
await openCommand('Заказы клиентов');
|
||||
|
||||
await showCaption('Создаём новый заказ');
|
||||
await wait(1.5);
|
||||
await clickElement('Создать');
|
||||
await wait(2);
|
||||
|
||||
// Завершаем запись
|
||||
await hideCaption();
|
||||
const video = await stopRecording();
|
||||
console.log(`Записано: ${video.duration.toFixed(1)}s`);
|
||||
|
||||
// Озвучка
|
||||
const narrated = await addNarration(video.file, {
|
||||
ffmpegPath: 'tools/ffmpeg/bin/ffmpeg.exe',
|
||||
voice: 'ru-RU-DmitryNeural',
|
||||
});
|
||||
console.log(`Озвучено: ${narrated.file}`);
|
||||
```
|
||||
|
||||
Результат: `recordings/demo-narrated.mp4` — видео с голосовым сопровождением.
|
||||
|
||||
## Сценарии использования
|
||||
|
||||
### Запись без озвучки
|
||||
|
||||
Простейший вариант — субтитры на экране, без голоса:
|
||||
|
||||
```
|
||||
> Запиши видеоинструкцию: открой раздел Продажи, создай заказ клиента,
|
||||
> заполни организацию и контрагента. Без озвучки
|
||||
```
|
||||
|
||||
Claude запишет видео с субтитрами и подсветкой элементов.
|
||||
|
||||
### Запись с озвучкой
|
||||
|
||||
Полный pipeline — голос озвучивает каждый шаг:
|
||||
|
||||
```
|
||||
> Запиши озвученную видеоинструкцию по созданию заказа клиента.
|
||||
> Голос — Светлана
|
||||
```
|
||||
|
||||
Claude запишет видео, затем наложит голосовую дорожку. Субтитры показываются на экране, параллельно звучит голос.
|
||||
|
||||
### Переозвучка другим голосом
|
||||
|
||||
Видео уже записано — хотите другой голос? Не нужно перезаписывать:
|
||||
|
||||
```
|
||||
> Переозвучь recordings/demo.mp4 голосом Светланы
|
||||
```
|
||||
|
||||
Claude вызовет `addNarration` с другим голосом. Тексты берутся из файла `.captions.json`, который сохраняется рядом с видео при записи.
|
||||
|
||||
### Редактирование субтитров
|
||||
|
||||
После записи рядом с видео появляется файл `video.captions.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"videoTimestamps": true,
|
||||
"captions": [
|
||||
{ "text": "Переходим в раздел «Продажи»", "speech": "Переходим в раздел Продажи", "time": 3160 },
|
||||
{ "text": "Открываем заказы клиентов", "speech": "Открываем заказы клиентов", "time": 7040, "voice": "bqbHGIIO5oETYIqhWmfk" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Можно отредактировать `speech` (текст озвучки) или добавить `voice` (голос для конкретной реплики) и переозвучить:
|
||||
|
||||
```
|
||||
> Отредактируй субтитры в recordings/demo.captions.json — замени "Продажи" на
|
||||
> "раздел Продажи", потом переозвучь
|
||||
```
|
||||
|
||||
## Приёмы
|
||||
|
||||
### Титульный слайд
|
||||
|
||||
Полноэкранная заставка в начале видео. Поддерживает озвучку через `speech`:
|
||||
|
||||
```js
|
||||
await startRecording('recordings/demo.mp4');
|
||||
await showTitleSlide('Создание заказа клиента', {
|
||||
subtitle: '1С:Бухгалтерия в примерах',
|
||||
speech: 'Создание заказа клиента. Бухгалтерия в примерах.'
|
||||
});
|
||||
await wait(1);
|
||||
await hideTitleSlide();
|
||||
// ... далее контент
|
||||
```
|
||||
|
||||
### Слайды из презентации
|
||||
|
||||
Показать изображение (скриншот слайда, схему и т.д.) как полноэкранный оверлей с озвучкой:
|
||||
|
||||
```js
|
||||
await showImage('slides/overview.png', {
|
||||
speech: 'На этом слайде показана общая схема процесса'
|
||||
});
|
||||
await wait(1);
|
||||
await hideImage();
|
||||
```
|
||||
|
||||
Стили оформления (`style`):
|
||||
- `'blur'` (по умолчанию) — размытый фон из картинки + тень. Лучший для презентаций
|
||||
- `'dark'` — тёмный фон + тень
|
||||
- `'light'` — белый фон + тень
|
||||
- `'full'` — на весь экран без отступов
|
||||
|
||||
```js
|
||||
await showImage('slides/diagram.png', { style: 'dark', speech: 'Диаграмма процесса' });
|
||||
```
|
||||
|
||||
### Подсветка элементов
|
||||
|
||||
Полупрозрачная рамка на элементе, который сейчас используется. Два режима:
|
||||
|
||||
- **Авторежим** — `setHighlight(true)` перед началом действий. Каждая функция (`navigateSection`, `clickElement`, `fillFields` и т.д.) автоматически подсвечивает элемент перед действием
|
||||
- **Ручная** — `highlight('Провести')` для произвольной подсветки конкретного элемента
|
||||
|
||||
```js
|
||||
setHighlight(true); // включить авто
|
||||
// ... все действия подсвечиваются автоматически
|
||||
setHighlight(false); // выключить перед stopRecording
|
||||
```
|
||||
|
||||
### Паузы и ритм
|
||||
|
||||
Ритм «субтитр → пауза → действие» даёт зрителю время прочитать, что произойдёт:
|
||||
|
||||
```js
|
||||
await showCaption('Проводим документ'); // зритель читает
|
||||
await wait(1.5); // пауза 1.5 сек
|
||||
await clickElement('Провести'); // действие
|
||||
```
|
||||
|
||||
Пауза после действия нужна только когда загружается следующая форма:
|
||||
|
||||
```js
|
||||
await clickElement('Создать');
|
||||
await wait(2); // форма загружается
|
||||
```
|
||||
|
||||
### Два голоса (подкаст / диалог)
|
||||
|
||||
Параметр `voice` в `showCaption` задаёт голос для конкретной реплики. `addNarration` автоматически использует его вместо глобального:
|
||||
|
||||
```js
|
||||
const MALE = 'bqbHGIIO5oETYIqhWmfk'; // Alexander
|
||||
const FEMALE = '0ArNnoIAWKlT4WweaVMY'; // Elena Gromova
|
||||
|
||||
// speechRate: 85 — ElevenLabs медленнее Edge TTS, нужен запас
|
||||
await startRecording('podcast.mp4', { speechRate: 85 });
|
||||
|
||||
await showImage('slides/slide-01.png', { style: 'full', speech: false });
|
||||
await showCaption('', { speech: 'Привет! Сегодня поговорим...', voice: MALE });
|
||||
await wait(0.8);
|
||||
await showCaption('', { speech: 'А я буду задавать вопросы...', voice: FEMALE });
|
||||
await wait(0.8);
|
||||
|
||||
const video = await stopRecording();
|
||||
const result = await addNarration(video.file, {
|
||||
provider: 'elevenlabs',
|
||||
apiKey: 'sk_...',
|
||||
// глобальный voice не нужен — каждый caption несёт свой
|
||||
});
|
||||
```
|
||||
|
||||
Приёмы:
|
||||
- `showCaption('', { speech, voice })` — пустой текст (без субтитра на экране), но speech записывается для озвучки
|
||||
- `showImage` со `speech: false` — слайд без озвучки, реплики идут через `showCaption`
|
||||
- `speechRate: 85` — для ElevenLabs увеличиваем множитель (по умолчанию 70мс/символ), чтобы фразы не наезжали друг на друга
|
||||
|
||||
### Разделение текста и озвучки
|
||||
|
||||
Параметр `speech` в `showCaption` позволяет показывать одно, а озвучивать другое:
|
||||
|
||||
```js
|
||||
// Субтитр технический, озвучка человечная
|
||||
await showCaption('Дт 60.02 — Кт 51', {
|
||||
speech: 'Дебет шестьдесят ноль два — кредит пятьдесят один'
|
||||
});
|
||||
|
||||
// Показать субтитр, но НЕ озвучивать
|
||||
await showCaption('Технические детали', { speech: false });
|
||||
```
|
||||
|
||||
Это полезно для:
|
||||
- **Бухгалтерских проводок** — на экране формула, голосом — словами
|
||||
- **Технических данных** — показать, но не зачитывать
|
||||
- **Информационных плашек** — немой субтитр на несколько секунд
|
||||
|
||||
## Доступные голоса и провайдеры
|
||||
|
||||
### Какой провайдер выбрать?
|
||||
|
||||
| Провайдер | Тембр | Произношение русского | Цена |
|
||||
|-----------|-------|----------------------|------|
|
||||
| **Edge TTS** | Синтетичнее | Корректные ударения, правильная артикуляция | Бесплатно |
|
||||
| **ElevenLabs** | Живее, естественнее | Возможны ошибки в ударениях и артикуляции (напр. «докумЭнт», «крЕдит» вместо «кредИт») | Платно (starter+) |
|
||||
| **OpenAI** | Зависит от голоса | Зависит от сервиса | Платно |
|
||||
|
||||
**Для русскоязычных видеоинструкций рекомендуется Edge TTS** — он бесплатный и даёт надёжное качество русской речи. Голоса DmitryNeural и SvetlanaNeural специально обучены для русского языка: правильно расставляют ударения, корректно артикулируют и делают паузы в нужных местах.
|
||||
|
||||
**ElevenLabs** даёт более живой, «человечный» тембр — голос звучит менее синтетически. Однако мультиязычная модель иногда ошибается в произношении русских слов (особенно профессиональная терминология). Если выбираете ElevenLabs для русского контента — берите **professional-голоса** с образовательным или деловым профилем (например, Olga Orlova, Artem), они дают лучший результат, чем англоязычные premade-голоса через мультиязычную модель. Управлять ударениями через API нельзя — фонемные теги (SSML) поддерживаются только для английских моделей.
|
||||
|
||||
### Edge TTS (бесплатный) — рекомендуется для русского
|
||||
|
||||
| Голос | Описание |
|
||||
|-------|----------|
|
||||
| `ru-RU-DmitryNeural` | Мужской, русский — спокойный, деловой |
|
||||
| `ru-RU-SvetlanaNeural` | Женский, русский — чёткий, уверенный |
|
||||
|
||||
Полный список: `en-US-AriaNeural`, `en-US-GuyNeural`, `de-DE-ConradNeural` и другие. Edge TTS поддерживает десятки языков.
|
||||
|
||||
Конфигурация не нужна — Edge TTS используется по умолчанию. Для смены голоса:
|
||||
|
||||
```json
|
||||
{
|
||||
"tts": {
|
||||
"voice": "ru-RU-SvetlanaNeural"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### ElevenLabs (платный) — живой тембр
|
||||
|
||||
Модель `eleven_multilingual_v2` поддерживает русский. Тембр заметно живее, чем у Edge TTS, но возможны артикуляционные ошибки на русской терминологии.
|
||||
|
||||
Для русского контента выбирайте **professional-голоса** с образовательным/деловым профилем из Voice Library:
|
||||
|
||||
| Голос | ID | Профиль |
|
||||
|-------|----|---------|
|
||||
| Olga Orlova | `d60rsXo2p0OwikDR5bS7` | Clear and Engaging |
|
||||
| Artem | `WTn2eCRCpoFAC50VD351` | Friendly & Professional |
|
||||
| Denis | `0BcDz9UPwL3MpsnTeUlO` | Pleasant, Engaging and Friendly |
|
||||
| Alexander | `bqbHGIIO5oETYIqhWmfk` | Pleasant, Warm and Natural |
|
||||
| Elena Gromova | `0ArNnoIAWKlT4WweaVMY` | Podcasts & Conversation |
|
||||
| Victor | `9fjVd0EYNNXHllJquVdT` | Moscow accent |
|
||||
|
||||
```json
|
||||
{
|
||||
"tts": {
|
||||
"provider": "elevenlabs",
|
||||
"apiKey": "sk_...",
|
||||
"voice": "d60rsXo2p0OwikDR5bS7"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`voice` — ID голоса (не имя). Professional-голоса добавляются в аккаунт через Voice Library в личном кабинете. Требуется платный тариф (starter и выше).
|
||||
|
||||
Особенности: лимит на параллельные запросы (2–3 одновременно), система автоматически ограничивает размер пакета.
|
||||
|
||||
### OpenAI-compatible (платный)
|
||||
|
||||
```json
|
||||
{
|
||||
"tts": {
|
||||
"provider": "openai",
|
||||
"apiKey": "sk-...",
|
||||
"voice": "alloy"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Голоса: `alloy`, `echo`, `fable`, `onyx`, `nova`, `shimmer`.
|
||||
|
||||
Поле `apiUrl` позволяет подключить любой OpenAI-совместимый сервис (например, локальный TTS-прокси).
|
||||
|
||||
## Полный пример
|
||||
|
||||
Типовая структура озвученного сценария:
|
||||
|
||||
```js
|
||||
await startRecording('output.mp4');
|
||||
|
||||
// Титульный слайд с озвучкой
|
||||
await showTitleSlide('Заголовок', {
|
||||
subtitle: 'Подзаголовок',
|
||||
speech: 'Заголовок. Подзаголовок.'
|
||||
});
|
||||
await wait(1);
|
||||
await hideTitleSlide();
|
||||
|
||||
// Слайд из презентации (опционально)
|
||||
await showImage('slides/overview.png', {
|
||||
speech: 'Описание слайда для озвучки'
|
||||
});
|
||||
await wait(1);
|
||||
await hideImage();
|
||||
|
||||
setHighlight(true);
|
||||
|
||||
// ... шаги с showCaption + действия ...
|
||||
|
||||
await hideCaption();
|
||||
setHighlight(false);
|
||||
const video = await stopRecording();
|
||||
|
||||
const narrated = await addNarration(video.file, {
|
||||
ffmpegPath: 'tools/ffmpeg/bin/ffmpeg.exe',
|
||||
voice: 'ru-RU-SvetlanaNeural',
|
||||
});
|
||||
```
|
||||
|
||||
## Типичные проблемы
|
||||
|
||||
| Проблема | Решение |
|
||||
|----------|---------|
|
||||
| `ffmpeg not found` | Установите ffmpeg (см. Предусловия) |
|
||||
| Файл записи 0 байт | Проверьте права на запись в выходной каталог |
|
||||
| Видео дёргается | Добавьте `wait()` между шагами |
|
||||
| `Already recording` | Вызовите `stopRecording()` перед новой записью |
|
||||
| `No captions available` | Используйте `showCaption()` во время записи |
|
||||
| TTS timeout | Проверьте интернет-соединение (Edge TTS требует сеть) |
|
||||
| Озвучка обрезается | Увеличьте паузы `wait()` между субтитрами |
|
||||
| Фразы наезжают друг на друга | Увеличьте `speechRate` в `startRecording` (85 для ElevenLabs) |
|
||||
|
||||
## Связанные навыки
|
||||
|
||||
- [Тестирование через веб-клиент](web-test-guide.md) — навигация, формы, таблицы, отчёты
|
||||
- [Веб-публикация](web-guide.md) — `/web-publish`, `/web-info`, `/web-stop`
|
||||
|
||||
Reference in New Issue
Block a user