Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 93 additions & 51 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,96 +1,138 @@
# NiuMa Studio 环境变量示例
# 使用方法:复制本文件为 .env,然后填写自己的密钥
# 注意:.env 已被 .gitignore 忽略,不要把真实 API Key 提交到 Git。
# NiuMa Studio / 牛马片场环境变量示例
# 使用方法:复制本文件为 .env,然后只在 .env 里填写真实密钥
# 注意:不要把真实 API Key、Token、Cookie、账号密码提交到 Git。

# ========================
# 基础配置
# 1. 本地服务与数据目录
# ========================

# 本地管理员令牌(用于调用管理接口时鉴权)
# 生产环境请换成随机长字符串,不要使用默认值
# 本地管理接口令牌。建议改成随机长字符串。
LOCAL_ADMIN_TOKEN=change-me-to-a-random-string

# 数据库文件路径(本地默认存在 data/ 目录;Docker 内固定为 /app/data/workflow.sqlite3
# 数据库文件。留空时使用 app/core/config.py 中的默认值:data/workflow.sqlite3
DATABASE_PATH=

# 数据目录(任务记录、AI 分析结果等;留空则默认使用项目 data/ 目录)
# 数据目录。留空时使用项目根目录下的 data/
DATA_DIR=

# FFmpeg 超时(秒),超过此时间未完成的视频处理会被取消
FFMPEG_TIMEOUT=600

# Docker / 本地存储路径
# 本地直接运行时默认沿用历史存储目录 E:\直播间切片工作流存储,避免影响已有任务和视频。
# Docker Compose 会自动把这个 E 盘目录挂载到容器内的 /workspace/tasks。
# 如果以后要换存储盘,可以同步修改 docker-compose.yml 里的 volumes 和这里的路径。
# 任务产物目录。
# 历史默认值是 E:\直播间切片工作流存储,用来兼容已有任务。
# 如果你的电脑没有 E 盘,请改成真实存在的 Windows 目录,例如:
# STORAGE_ROOT=C:\NiuMaStudio\tasks
# TASKS_DIR=C:\NiuMaStudio\tasks
STORAGE_ROOT=E:\直播间切片工作流存储
TASKS_DIR=E:\直播间切片工作流存储

# 允许从哪些本地目录选择已有视频,多个路径用英文逗号分隔。
# 留空时只允许项目任务目录和存储目录内的文件。
ALLOWED_MEDIA_ROOTS=

# 上传限制。
MAX_UPLOAD_SIZE_BYTES=4294967296
ALLOWED_UPLOAD_EXTENSIONS=.mp4,.mov,.mkv,.avi,.flv,.webm,.m4v,.ts,.wav,.mp3,.aac,.flac,.ogg,.wma

# ========================
# 2. FFmpeg / FFprobe
# ========================

# 所有这些命令都要求 Windows 能直接执行 ffmpeg / ffprobe。
FFMPEG_TIMEOUT=600
FFMPEG_AUDIO_EXTRACT_TIMEOUT=600
FFMPEG_CUT_TIMEOUT=600
FFMPEG_SUBTITLE_TIMEOUT=300
FFMPEG_COVER_TIMEOUT=120
FFMPEG_CHUNK_TIMEOUT=120
FFPROBE_TIMEOUT=60

# ========================
# 3. 转写配置
# ========================

# 可选值:volcengine 或 local。
# volcengine = 火山引擎远程转写。
# local = 本地 faster-whisper。
# 远程失败时当前不会自动切到本地,页面会提示手动改用本地模型。
TRANSCRIPTION_PROVIDER=volcengine
TRANSCRIPTION_FALLBACK_PROVIDER=

# 火山引擎 ASR。真实密钥只写在 .env,不要写进代码或文档。
VOLCENGINE_ASR_API_URL=https://openspeech.bytedance.com/api/v3/auc/bigmodel/recognize/flash
VOLCENGINE_ASR_API_KEY=
VOLCENGINE_ASR_APP_KEY=
VOLCENGINE_ASR_ACCESS_KEY=
VOLCENGINE_ASR_RESOURCE_ID=volc.bigasr.auc_turbo
VOLCENGINE_ASR_TIMEOUT_SECONDS=300
VOLCENGINE_ASR_AUDIO_FORMAT=mp3

# 本地 faster-whisper。
TRANSCRIPTION_MODEL=medium
TRANSCRIPTION_LANGUAGE=zh
TRANSCRIPTION_DEVICE=cpu
TRANSCRIPTION_COMPUTE_TYPE=int8
TRANSCRIPTION_CPU_FALLBACK_MODEL=medium
TRANSCRIPTION_CHUNK_SECONDS=120
TRANSCRIPTION_CHUNK_OVERLAP_SECONDS=5

# ========================
# 4. AI 分析与发送中心文案
# ========================

# 可选值:remote 或 local。
AI_DEFAULT_PROVIDER=remote
AI_PROVIDER=remote
AI_REQUEST_TIMEOUT_SECONDS=120

# 2. 分析文字稿,生成候选切片:远程 OpenAI-compatible API
# AI 分析候选片段:远程 OpenAI-compatible / DeepSeek。
AI_ANALYSIS_REMOTE_BASE_URL=https://api.deepseek.com
AI_ANALYSIS_REMOTE_API_KEY=请在这里填写你的文字稿分析 API Key
AI_ANALYSIS_REMOTE_API_KEY=
AI_ANALYSIS_REMOTE_MODEL=deepseek-v4-flash
AI_ANALYSIS_REMOTE_PROTOCOL=chat_completions
AI_ANALYSIS_REMOTE_REASONING_EFFORT=
AI_ANALYSIS_REMOTE_RESPONSES_PATH=/v1/responses
AI_ANALYSIS_REMOTE_DISABLE_RESPONSE_STORAGE=true
AI_ANALYSIS_REQUEST_TIMEOUT_SECONDS=120

# 3. 发送中心生成发布文案:远程 OpenAI-compatible API
# 发送中心生成标题、简介、话题:远程 OpenAI-compatible / DeepSeek。
AI_PUBLISH_REMOTE_BASE_URL=https://api.deepseek.com
AI_PUBLISH_REMOTE_API_KEY=请在这里填写你的发布文案 API Key
AI_PUBLISH_REMOTE_API_KEY=
AI_PUBLISH_REMOTE_MODEL=deepseek-v4-flash
AI_PUBLISH_REMOTE_PROTOCOL=chat_completions
AI_PUBLISH_REMOTE_REASONING_EFFORT=
AI_PUBLISH_REMOTE_RESPONSES_PATH=/v1/responses
AI_PUBLISH_REMOTE_DISABLE_RESPONSE_STORAGE=true
AI_PUBLISH_REQUEST_TIMEOUT_SECONDS=120

# 本地 Ollama API
# 兼容旧脚本的 AI_REMOTE_* 配置。新功能优先使用上面的 AI_ANALYSIS_* 和 AI_PUBLISH_*。
AI_REMOTE_BASE_URL=https://api.deepseek.com
AI_REMOTE_API_KEY=
AI_REMOTE_MODEL=deepseek-v4-flash
AI_REMOTE_REVIEW_MODEL=deepseek-v4-flash
AI_REMOTE_PUBLISH_MODEL=deepseek-v4-flash
AI_REMOTE_PROTOCOL=chat_completions
AI_REMOTE_REASONING_EFFORT=
AI_REMOTE_RESPONSES_PATH=/v1/responses
AI_REMOTE_DISABLE_RESPONSE_STORAGE=true

# 本地 Ollama。
AI_LOCAL_BASE_URL=http://127.0.0.1:11434/v1
AI_LOCAL_API_KEY=ollama
AI_LOCAL_MODEL=qwen3:8b
AI_LOCAL_PROTOCOL=chat_completions
AI_LOCAL_FALLBACK_PROTOCOL=
AI_LOCAL_HEALTH_TIMEOUT_SECONDS=30

# 发送中心 opencli
# Docker 主页面固定使用 8001;Windows opencli 辅助服务由 scripts/start_docker_opencli.ps1 启动。
OPENCLI_LOCAL_BASE_URL=http://127.0.0.1:8001
OPENCLI_HOST_BRIDGE_URL=http://host.docker.internal:8765

# 额外 AI 运行默认值
# 长文本处理参数。一般不用改。
AI_NETWORK_ACCESS=enabled
AI_WINDOWS_WSL_SETUP_ACKNOWLEDGED=true
AI_MODEL_CONTEXT_WINDOW=1000000
AI_MODEL_AUTO_COMPACT_TOKEN_LIMIT=900000

# 1. 音频转写
# 默认优先使用国内可直连的火山引擎远程转写;失败后会暂停并提示原因,不会自动退回本地 faster-whisper。
TRANSCRIPTION_PROVIDER=volcengine
TRANSCRIPTION_FALLBACK_PROVIDER=
VOLCENGINE_ASR_API_URL=https://openspeech.bytedance.com/api/v3/auc/bigmodel/recognize/flash
VOLCENGINE_ASR_API_KEY=请在这里填写你的火山引擎 App Key
VOLCENGINE_ASR_APP_KEY=
VOLCENGINE_ASR_ACCESS_KEY=
VOLCENGINE_ASR_RESOURCE_ID=volc.bigasr.auc_turbo
VOLCENGINE_ASR_TIMEOUT_SECONDS=300
VOLCENGINE_ASR_AUDIO_FORMAT=mp3
# ========================
# 5. opencli / 发送中心
# ========================

# 本地 faster-whisper 配置
# 只有在页面确认“改用本地模型转写”后才会使用,不作为默认自动兜底。
# MVP 默认使用 CPU 稳定跑通,确认成功后再单独切换 CUDA 加速。
# 如果要测试 RTX 显卡,可改为:
# TRANSCRIPTION_MODEL=large-v3
# TRANSCRIPTION_DEVICE=cuda
# TRANSCRIPTION_COMPUTE_TYPE=float16
TRANSCRIPTION_MODEL=medium
TRANSCRIPTION_LANGUAGE=zh
TRANSCRIPTION_DEVICE=cpu
TRANSCRIPTION_COMPUTE_TYPE=int8
TRANSCRIPTION_CPU_FALLBACK_MODEL=medium
TRANSCRIPTION_CHUNK_SECONDS=120
TRANSCRIPTION_CHUNK_OVERLAP_SECONDS=5
# 本地直接运行时页面地址。
OPENCLI_LOCAL_BASE_URL=http://127.0.0.1:8001

# Docker 内调用 Windows 宿主机 opencli 桥接服务时使用。
OPENCLI_HOST_BRIDGE_URL=http://host.docker.internal:8765
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
.venv/
__pycache__/
*.pyc
.pytest_cache/
.ruff_cache/

# 本地真实配置与密钥:不要提交 API Key
.env
.env.*
!.env.example

# 本地数据库、日志、截图、浏览器缓存、测试素材都不提交
data/*
!data/.gitkeep

Expand All @@ -25,6 +28,7 @@ tasks/*
*.webm
*.mp3
*.wav
*.bak_*

.DS_Store
Thumbs.db
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Changelog

## 2026-06-17

### 修复

- 修复 AI 分析和恢复历史分析时候选片段可能被误清空的问题。
- 给字幕烧录 FFmpeg 调用补充超时配置,避免 Windows 本地进程长期卡住。
- 给任务详情视频探测 FFprobe 调用补充超时保护,超时后降级显示未知时长。
- 移除重复的 `LOCAL_ADMIN_TOKEN` 配置字段。
- 将 Pydantic 校验器迁移到 v2 `field_validator` 写法,消除弃用 warning。

### 文档

- 重写 `README.md`,明确当前已实现能力、边界和 Windows 快速启动。
- 新增 `docs/WINDOWS_SETUP.md`,提供新手 Windows 部署教程。
- 重写架构、任务流、数据库、部署、AI 分析、切片、候选审核、字幕发送文档。
- 同步 `docs/UI_REFERENCE.md`、`docs/PROJECT_GUIDE.md`、`DEVELOPMENT_LOG.md`、`NEXT_STEPS.md`。
- 明确 `scheduled_at` 当前只是字段预留,没有真正定时调度器。
- 明确发送中心是人工确认 + opencli 辅助投稿,不是无人值守发布。

### 配置与清理

- 更新 `.env.example`,补齐 Windows 路径、FFmpeg、AI、转写、opencli 配置说明。
- 更新 `.gitignore`,补充 pytest/ruff 缓存和本地备份文件规则。
- 给 `docker-compose.yml` 的 E 盘任务目录挂载补充说明。
- 清理明确可再生成的本地日志、缓存和 `__pycache__` 产物。
10 changes: 10 additions & 0 deletions DEVELOPMENT_LOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Development Log

## 2026-06-17 Windows 代码体检、文档重写与冗余清理
- 在 `refactor/windows-codebase-audit-docs-cleanup` 分支执行本轮整理,开始前确认 `master` 工作区无未提交的跟踪文件修改。
- 修复 AI 分析候选片段替换顺序:重新跑 AI 分析或恢复历史分析时,会用新结果替换当前候选,不再插入后立刻清空。
- 为字幕 FFmpeg 烧录和任务详情 FFprobe 探测补充超时保护,降低 Windows 本地进程卡死风险。
- 移除重复的 `LOCAL_ADMIN_TOKEN` 配置字段,并将 Pydantic 校验器迁移到 `field_validator`。
- 新增 AI 候选片段替换和历史恢复回归测试,已先单独验证 `tests/test_versioning_rollback.py::TestAIAnalysisActive` 通过。
- 重写或同步 `README.md`、`docs/WINDOWS_SETUP.md`、`docs/ARCHITECTURE.md`、`docs/TASK_FLOW.md`、`docs/DATABASE_SCHEMA.md`、`docs/DEPLOYMENT.md`、`docs/AI_ANALYSIS.md`、`docs/VIDEO_CUTTING.md`、`docs/CLIP_REVIEW.md`、`docs/SUBTITLE_AND_PUBLISH_PLAN.md`、`docs/UI_REFERENCE.md`、`.env.example` 和 `CHANGELOG.md`。
- 文档统一说明:`05_clips` 是当前切片目录,`06_subtitled` 是字幕成片目录,`07_covers` 是封面帧目录;`scheduled_at` 只是字段预留,发送中心仍需人工确认。
- 本轮不删除真实数据库、`.env`、任务目录、浏览器截图缓存或疑似含密钥备份文件;这些只列为后续需人工确认清理项。

## 2026-06-15 v1.3 分支整理与集成发布
- 新建并验证 `codex/branch-integration-20260611` 集成分支,按顺序整合 `fix/p0-security-and-stability`、`fix/p1-1-db-performance`、`fix/p1-2-query-refactor`、`feature/p1-3-job-queue`、`feature/p1-4-split-task-service`、`feature/p1-5-versioned-products-rollback`、`feature/p2-1-engineering` 和 `feature/p2-2-architecture-docs`。
- 已处理分支之间的冲突:数据库初始化同时保留 `oauth_states`、`workflow_jobs`、`cut_runs` 等结构;`task_service.py` 保留兼容出口,页面查询实际迁移到 `task_query_service.py`;任务队列、服务拆分、产物版本化和工程化配置已统一集成。
Expand Down
20 changes: 20 additions & 0 deletions NEXT_STEPS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# Next Steps

## 2026-06-17 本轮整理后怎么检查
1. 在项目根目录运行:`.\.venv\Scripts\python.exe -m ruff check app tests`。
2. 再运行:`.\.venv\Scripts\python.exe -m pytest -q`。
3. 启动本地后台:`.\.venv\Scripts\python.exe -m uvicorn app.main:app --host 127.0.0.1 --port 8001`。
4. 打开 `http://127.0.0.1:8001/health`,确认返回健康状态。
5. 打开首页、任务列表、任务详情、片段审核、字幕工作台、发送中心,确认页面能正常加载。
6. 用一条短视频按顺序冒烟测试:上传视频、提取音频、转写、AI 分析、片段审核、生成切片、生成字幕、刷新发送队列。

## 2026-06-17 仍需人工确认的清理项
1. `.env.backup_*` 可能含真实密钥,确认不需要后再删除。
2. `data/screenshots/` 可能含浏览器缓存或登录痕迹,确认不需要后再删除。
3. `data/workflow.sqlite3.bak_*` 是数据库备份,确认已有其他备份后再删除。
4. `tasks/` 下的真实任务产物目录不要自动删除,确认不再需要后再清理。
5. 根目录 `ChatGPT Image 2026年5月16日 11_54_05.png` 需要先确认是否是重复设计图,再决定是否删除或移动到 `docs/design/`。

## 2026-06-17 下一步建议
1. 先完成本轮 PR 审核和合并,不急着继续大改业务流程。
2. 下一轮优先做小范围体验增强:字幕批量处理、字幕文本编辑、发送失败重试入口、任务文件入口。
3. 如果要继续清理冗余文件,建议单独开一个清理分支,只处理人工确认过的本地数据和历史设计素材。

## 2026-06-15 v1.3 合并后怎么检查
1. 打开项目后先确认左侧显示 `v1.3 分支整合版`。
2. 启动 Docker 主页面:`docker compose up --build`。
Expand Down
Loading
Loading