根目录由AndroidgetFilesDir()/workbench获得。常见路径可示意为/data/user/0/<applicationId>/files/workbench,实际应以系统API返回为准,不能在APK写死某个用户或设备路径。
workbench/
├── templates/index.html
├── static/mobile.js、mobile.css
├── assets/fonts/NotoSansCJKsc-Bold.otf
├── assets/previews/<voice>.mp3 # 26段
├── licenses/
├── draft.json # 写入中draft.pending
├── trial-usage.json # 仅试用版;写入中trial-usage.pending
├── jobs/<规范UUID>/
│ ├── job.json # 写入中job.pending
│ ├── part-0000.mp3 ... # 写入中part-0000.partial
│ ├── audio.mp3 # 写入中audio.pending.mp3
│ ├── image-<version>.png
│ ├── image-<version>-<index>.png # 多图
│ ├── cover.png、cover-1.png ...
│ ├── image_sequence.ffconcat
│ ├── encode-progress.txt、video-log.txt
│ ├── <正文前30字符清理后>.mp4
│ └── video.pending.mp4
└── records/
├── events.jsonl
└── tingwen-records.json # 导出时生成
job核心字段字典
| 字段组 | 字段 | 说明 |
|---|---|---|
| 标识/时间 | id、created、updated | 规范UUID、创建/更新时间戳 |
| 原始创作快照 | title、title_secondary、title_style、text、voice | 创建任务后固定,编辑草稿不回写 |
| 当前配图要求 | prompt | 创建时保存;regenerate/change-source可更新任务配图要求,单纯编辑草稿不回写 |
| 来源配置 | provider、model、image_mode | manual为手机图/网址;AI当前Seedream;历史可保留兼容配置 |
| 输出名 | video_filename | 正文命名,历史可回退video.mp4 |
| 图片版本 | image_version、confirmed_version、confirmed_digest | 当前图与确认闸门 |
| 图库 | image_gallery、image_metadata | 多图entry含filename/metadata/source_id;单图gallery可为空 |
| 状态 | audio_state、image_state、video_state | 分别维护 |
| 消息/进度 | 各阶段_message、各阶段_progress | 进度含stage、percent或completed/total |
| 控制/收费状态 | paused、cancelled、submitting、remote_id | remote_id为兼容字段,不实现SeedreamID恢复轮询 |
| 媒体时长 | audio_duration、video_duration、image_durations | 成功后写,时间轴依据audio_duration |
job_view响应额外附gallery(index、metadata、preview_url)、output_folder、audio_path、video_path、video_url;这些是视图便利字段,不必一概理解为job落盘schema。video_path来自独立实际文件检查,所以状态重置后仍可访问上次成片。
原子写入与局限
| 文件 | 写入机制 | 一致性边界 |
|---|---|---|
| job.json | RLock内写job.pending,replace正式文件 | 原子替换,未见job写入fsync;不构成数据库事务 |
| draft.json | pending、flush、fsync文件、replace | 字段白名单;与试用账本不是跨文件事务 |
| 试用ledger | pending、flush、fsync、replace、fsync目录 | 进程内RLock串行;非跨进程文件锁 |
| 图像/最终音频/视频 | 先临时后replace | 只有达到对应验证条件才发布为完成 |
| events.jsonl | 锁内追加安全字段 | 日志坏行可跳过,写失败标warning而不阻断媒体任务 |
原子rename和fsync改善持久化,不代表所有断电、介质损坏或空间耗尽都绝不会丢数据。任务文件未加密,必要正文与提示词保存在应用私有JSON;allowBackup=false关闭自动Android备份。没有用户级项目打包恢复、容量轮转或自动清理机制。
日志schema
白名单为event/job_id/import_id/call_id/part/status/provider/model/duration_ms/count,再加time/version。model字段进行安全格式检查;不接受任意error文本,避免把密钥、网址或完整内容当日志写入。读取逐行忽略坏行、时间倒序、默认分页100条。一次调用started/completed是生命周期两条记录,不代表两次云端收费,应用日志也不替代云端账单。
依据:app.py:63–129,427–498,626–659、records.py:75–113、试用trial_limits.py:61–197。