https://github.com/comerc/try-go-secrets
https://github.com/comerc/try-go-secrets
Last synced: 7 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/comerc/try-go-secrets
- Owner: comerc
- Created: 2026-03-03T09:57:44.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-05-28T18:06:46.000Z (15 days ago)
- Last Synced: 2026-05-28T18:23:03.218Z (15 days ago)
- Language: Go
- Size: 5.89 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Go Secrets Pipeline
Автоматизированный пайплайн генерации YouTube Shorts (<60 сек) из 286 markdown-файлов с секретами Go.
**Стек:** Go · Gemini TTS · Codex CLI / Claude Code CLI / z.ai · Puppeteer · FFmpeg
---
## Режимы запуска
В `.env` используются ключевые параметры запуска:
| Переменная | Значение | Эффект |
|---|---|---|
| `LLM_BACKEND` | `codex-cli` (по умолчанию) | инференс через локальный Codex CLI |
| `LLM_BACKEND` | `claude-cli` | инференс через локальный Claude Code CLI |
| `LLM_BACKEND` | `zai-api` | инференс через z.ai API |
| `LLM_MODEL` | например `gpt-5.5` | модель для Codex, Claude и z.ai |
| `LLM_EFFORT` | `medium` по умолчанию | уровень reasoning/thinking для LLM-бэкенда |
| `PUPPETEER_URL` | выбирается автоматически, если не задан | адрес локально запущенного Puppeteer-сервиса |
Поддерживаемые уровни `LLM_EFFORT` зависят от бэкенда:
- `claude-cli`: `low`, `medium`, `high`, `xhigh`, `max`
- `codex-cli`: `low`, `medium`, `high`, `xhigh`
- `zai-api`: `low`, `medium`, `high`
Для `zai-api` значение `LLM_EFFORT` маппится так:
- `low` -> `thinking.disabled`
- `medium` -> `thinking.enabled`
- `high` -> `thinking.enabled` + `clear_thinking=false`
---
## Быстрый старт (локальный режим)
```bash
# 1. Скопировать и заполнить ключи API
cp .env.example .env
# 2. Убедиться что Codex CLI залогинен
codex login
# 3. Конкретный файл по номеру
./scripts/run.sh 43
# → output/ru/videos/YYYY-MM-DD__NNN.mp4
# Другой язык на один запуск
VIDEO_LANG=es ./scripts/run.sh 43
# 4. Случайный необработанный файл
./scripts/run.sh
# 5. Бесконечный цикл (все файлы подряд)
./scripts/loop.sh
```
`run.sh` запускает pipeline локально (`go run ./cmd/main.go`). Если Puppeteer ещё не установлен, скрипт сам сделает `npm install` в `puppeteer/`, поднимет сервис на свободном порту и дождётся `/health`.
Результаты:
- `output//` — видео, аудио, сценарии
- `state/tts_usage.json` — общий учёт TTS
- `state//` — `processed.json`, `youtube_schedule.json`
---
## YouTube автопубликация
Финальный шаг пайплайна может автоматически загрузить готовый ролик в YouTube, поставить публикацию в расписание и добавить видео в плейлист.
Включается через `.env`:
```bash
YOUTUBE_ENABLED=true
YOUTUBE_CLIENT_ID=...
YOUTUBE_CLIENT_SECRET=...
YOUTUBE_REFRESH_TOKEN=...
YOUTUBE_PLAYLIST_ID_RU=...
TERMINAL_TITLE_RU=300 секретов Golang
YOUTUBE_SCHEDULE_LOCATION_RU=Europe/Moscow
YOUTUBE_SCHEDULE_TIME_RU=12:00
```
Поведение:
- `Script.Title` отправляется как title ролика.
- `Script.NarrationText` отправляется в description.
- `TERMINAL_TITLE_` отображается в заголовке терминала внутри видео.
- Видео загружается как `private` с `publishAt`, то есть YouTube сам опубликует его в заданное время.
- Публикация планируется по одному ролику в день. Занятые даты хранятся в `state//youtube_schedule.json`.
- Ролик добавляется в плейлист `YOUTUBE_PLAYLIST_ID_`.
Опубликовать уже готовый ролик без перегенерации:
```bash
./scripts/pub.sh 43
```
Скрипт найдёт последние `output//scripts/*__043.json` и `output//videos/*__043.mp4`, выберет первую свободную дату и загрузит ролик в YouTube.
`state//youtube_schedule.json` хранит только номер ролика и дату:
```json
{
"043": "2026-05-03"
}
```
Для OAuth refresh token нужен доступ к YouTube Data API v3 со scope `https://www.googleapis.com/auth/youtube`.
---
## Исправление готового ролика (fix)
Если нужно поправить озвучку/субтитры без перегенерации сценария через LLM:
**1. Найти сценарий**
```
output/ru/scripts/YYYY-MM-DD__NNN.json
```
**2. Отредактировать поля**
| Поле | Что менять |
|---|---|
| `NarrationTags` | Gemini TTS markup tags для озвучки, например `[short pause]`, `[whispering]`; официальный список: https://docs.cloud.google.com/text-to-speech/docs/gemini-tts#markup_tag_guide |
| `NarrationText` | Чистый текст субтитров (без Audio-Tags) |
| `Segments[].Text` | Текст отдельного сегмента субтитров |
**3. Запустить перегенерацию**
```bash
./scripts/fix.sh 43
```
Скрипт пропускает LLM, берёт отредактированный `NarrationTags` и заново синтезирует аудио + рендерит видео (Puppeteer + FFmpeg).
---
## Разработка
```bash
# Unit-тесты (парсер + выбор контента), без внешних зависимостей
go test ./tests/...
# Тест TTS изолированно
go run ./cmd/main.go -test-tts "Привет мир"
# → output/ru/audio/test-tts.wav
# Puppeteer поднимается автоматически через `./scripts/run.sh` и `./scripts/fix.sh`
```
---
## Переменные окружения
| Переменная | Описание |
|---|---|
| `LLM_BACKEND` | `codex-cli` — Codex CLI, `claude-cli` — Claude Code CLI, `zai-api` — z.ai API |
| `LLM_MODEL` | модель для Codex, Claude и z.ai (`glm-5.1` по умолчанию для z.ai) |
| `LLM_EFFORT` | уровень effort/thinking для LLM-бэкенда |
| `ZAI_API_KEY` | ключ z.ai API |
| `GEMINI_API_KEY` | ключ Gemini API для TTS |
| `GEMINI_TTS_MODEL` | модель Gemini TTS, по умолчанию `gemini-3.1-flash-tts-preview` |
| `GEMINI_TTS_VOICE` | голос Gemini TTS; если пусто, выбирается случайно из `x-voices.md` |
| `PUPPETEER_URL` | URL локального puppeteer-сервиса, подбирается автоматически |
| `RAW_DIR` | папка с markdown-файлами, по умолчанию `./raw` |
| `OUTPUT_DIR` | базовая папка с результатами, по умолчанию `./output`; язык добавляется автоматически |
| `STATE_DIR` | базовая папка с состоянием, по умолчанию `./state`; язык добавляется автоматически |
| `VIDEO_LANG` | язык нарратива и подпапок: `ru` (по умолчанию), `en-us`, `es` |
| `VIDEO_WIDTH` | ширина видео в пикселях, по умолчанию `1080` |
| `VIDEO_HEIGHT` | высота видео в пикселях, по умолчанию `1920` |
| `VIDEO_FPS` | частота кадров, по умолчанию `30` |
| `TERMINAL_TITLE_` | текст в заголовке терминала внутри видео, например `TERMINAL_TITLE_EN_US` |
| `YOUTUBE_ENABLED` | включает финальную загрузку и планирование YouTube |
| `YOUTUBE_CLIENT_ID` | OAuth client id Google Cloud |
| `YOUTUBE_CLIENT_SECRET` | OAuth client secret Google Cloud |
| `YOUTUBE_REFRESH_TOKEN` | refresh token для YouTube Data API |
| `YOUTUBE_PLAYLIST_ID_` | ID плейлиста для языка, например `YOUTUBE_PLAYLIST_ID_RU` |
| `YOUTUBE_SCHEDULE_LOCATION_` | IANA-таймзона расписания, например `YOUTUBE_SCHEDULE_LOCATION_RU=Europe/Moscow` |
| `YOUTUBE_SCHEDULE_TIME_` | время публикации по выбранной таймзоне в формате `HH:MM`, например `YOUTUBE_SCHEDULE_TIME_RU=13:30` |
---
YOUTUBE_ENABLED=true ./scripts/runs.sh