free-short-video 7.0.0 → 7.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +8 -4
- package/README.md +7 -40
- package/core/api/agnes_video.py +13 -23
- package/core/config.py +60 -3
- package/core/i18n_backend.py +643 -0
- package/core/pipelines/anchor_video.py +16 -13
- package/core/pipelines/creative/steps_audio.py +9 -7
- package/core/pipelines/creative/steps_frames.py +16 -4
- package/core/pipelines/creative/steps_script.py +44 -21
- package/core/pipelines/creative/steps_video.py +14 -14
- package/core/pipelines/manuscript_video.py +30 -13
- package/core/pipelines/multi_scene.py +17 -11
- package/core/pipelines/poetry_video.py +9 -5
- package/core/pipelines/simple_video.py +7 -7
- package/core/screenwriter/__init__.py +16 -4
- package/models/task.py +2 -2
- package/package.json +1 -1
- package/static/assets/ar-CRbirOE3.js +1 -0
- package/static/assets/bn-DGXpxXqo.js +1 -0
- package/static/assets/de-CW_QJIGx.js +1 -0
- package/static/assets/es-DG3zPtKB.js +1 -0
- package/static/assets/fa-KkBv8EdH.js +1 -0
- package/static/assets/fr-zdohXdVm.js +1 -0
- package/static/assets/hi-g1ky89XQ.js +1 -0
- package/static/assets/id-C21bK9DP.js +1 -0
- package/static/assets/index-D9sLMHUd.css +1 -0
- package/static/assets/index-DNreiP_P.js +45 -0
- package/static/assets/it-C5Xbey_b.js +1 -0
- package/static/assets/ja-NciKY87B.js +1 -0
- package/static/assets/ko-DJ8XhzBo.js +1 -0
- package/static/assets/ms-DcwfkMJG.js +1 -0
- package/static/assets/nl-CnpYVEZB.js +1 -0
- package/static/assets/pt-DAP0auKP.js +1 -0
- package/static/assets/ru-CzKYIeBy.js +1 -0
- package/static/assets/th-Q_FQzUg5.js +1 -0
- package/static/assets/tl-DXi6nq4V.js +1 -0
- package/static/assets/tr-BOCBaAw1.js +1 -0
- package/static/assets/ur-K0JNi0pO.js +1 -0
- package/static/assets/vi-DR30o5T0.js +1 -0
- package/static/index.html +2 -2
- package/web/helpers.py +39 -9
- package/web/routes/config_routes.py +37 -26
- package/web/routes/gallery_routes.py +4 -3
- package/web/routes/image_routes.py +6 -3
- package/web/routes/preset_routes.py +4 -3
- package/web/routes/preview_routes.py +38 -11
- package/web/routes/task_creation_routes.py +91 -24
- package/web/routes/utility_routes.py +8 -7
- package/web/routes/video_routes.py +4 -4
- package/web/routes/voice_routes.py +3 -2
- package/web/routes/workspace_routes.py +7 -6
- package/static/assets/ar-DVEg_H6f.js +0 -1
- package/static/assets/bn-BiFSnXzB.js +0 -1
- package/static/assets/de-uhexDoxx.js +0 -1
- package/static/assets/es-DUPqgRup.js +0 -1
- package/static/assets/fa-CNvLTccz.js +0 -1
- package/static/assets/fr-BagKMN93.js +0 -1
- package/static/assets/hi-DeWOhJ1q.js +0 -1
- package/static/assets/id-nGPSnGvK.js +0 -1
- package/static/assets/index-CJDvYGjk.css +0 -1
- package/static/assets/index-CfGG_wN-.js +0 -45
- package/static/assets/it-BJGGcHvC.js +0 -1
- package/static/assets/ja-cR8f9YPd.js +0 -1
- package/static/assets/ko-C0xGw09S.js +0 -1
- package/static/assets/ms-Cgs1dWE8.js +0 -1
- package/static/assets/nl-Cwg9KBwg.js +0 -1
- package/static/assets/pt-B9Hhu0CQ.js +0 -1
- package/static/assets/ru-CafubBrt.js +0 -1
- package/static/assets/th-2Muse1NU.js +0 -1
- package/static/assets/tl-DGVTGEV4.js +0 -1
- package/static/assets/tr-BPcMq5fF.js +0 -1
- package/static/assets/ur-BTthCgqj.js +0 -1
- package/static/assets/vi-Bi-nuXdz.js +0 -1
package/.env.example
CHANGED
|
@@ -36,11 +36,15 @@ HOST=0.0.0.0
|
|
|
36
36
|
PORT=8765
|
|
37
37
|
|
|
38
38
|
# 注:Agnes API 走哪个站点(国际站 / 国内站)**不通过环境变量配置**
|
|
39
|
-
# (AGNES_BASE_URL 已废弃,代码中不再读取)。请在 Web 设置页的 API Key
|
|
40
|
-
#
|
|
39
|
+
# (AGNES_BASE_URL 已废弃,代码中不再读取)。请在 Web 设置页的 API Key 面板选择全局默认域名。
|
|
40
|
+
# ⚠️ 重要:通过本文件 / 环境变量写入的 Key 属于 env 来源,**无法逐个绑定域名,也不参与
|
|
41
|
+
# Web 页的「自动探测域名」**——它们一律使用你在 Web 页设定的「全局默认域名」。因此:
|
|
42
|
+
# - 单站点 Key:把全局默认域名设成与该 Key 站点一致即可;
|
|
43
|
+
# - 混用不同站点的 Key:请改到 Web 配置页逐个添加(config 来源),再逐 Key 绑定域名
|
|
44
|
+
# 或点「自动探测域名」,才能各走各的站点(env Key 做不到这点)。
|
|
45
|
+
# 跨站使用 Key(如国际站 Key 打到国内站专属域名)会得到 HTTP 401 / 无效的令牌。
|
|
41
46
|
# 可选域名:com = apihub.agnes-ai.com(国际站)、cn = api.agnes-ai.cn(国内站,
|
|
42
|
-
# 需国内站专属 Key)、cn_bak = apihub.agnes-ai.cn
|
|
43
|
-
# 跨站使用 Key 会得到 HTTP 401 / 无效的令牌。
|
|
47
|
+
# 需国内站专属 Key)、cn_bak = apihub.agnes-ai.cn(备用,国内与国际 Key 均可用)。
|
|
44
48
|
|
|
45
49
|
|
|
46
50
|
# ── 4. 限速(可选)─────────────────────────────────────────────────
|
package/README.md
CHANGED
|
@@ -1,56 +1,23 @@
|
|
|
1
1
|
---
|
|
2
2
|
|
|
3
|
-
# What's New in v7.0.
|
|
3
|
+
# What's New in v7.0.2
|
|
4
4
|
|
|
5
5
|
## What's New
|
|
6
6
|
|
|
7
7
|
### Features & Improvements
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
breakdown, scene planning, poetry segmentation, image-prompt rewriting — is routed to your
|
|
13
|
-
provider automatically. The built-in Agnes provider is always available, cannot be deleted,
|
|
14
|
-
and keeps the previous behaviour when no custom provider is selected.
|
|
15
|
-
- **Provider management panel.** A dedicated settings section lists all text providers, lets
|
|
16
|
-
you add, edit and delete them, and keeps the Agnes key/domain editing inside the provider
|
|
17
|
-
modal. Keys are masked in the UI, and the provider's model list is a single editable list:
|
|
18
|
-
fetch it from the endpoint or type model ids by hand. Model selection is a two-level
|
|
19
|
-
provider → model picker that merges the models of all providers.
|
|
20
|
-
- **Interface-language aware backend messages.** Task progress messages, failure panels, HTTP
|
|
21
|
-
error details and the diagnostics report are now localized according to the UI language
|
|
22
|
-
instead of being hard-coded Chinese. The UI language travels with every request
|
|
23
|
-
(`X-Agnes-UI-Lang`, falling back to `Accept-Language`), is snapshotted into each task at
|
|
24
|
-
creation time, and therefore does not drift if the user switches language later. Chinese and
|
|
25
|
-
English are covered; the remaining languages fall back to the existing behaviour.
|
|
26
|
-
- **Clearer network failure diagnosis.** TLS handshake resets (`connection reset`) are now
|
|
27
|
-
attributed to local-connection problems, and the diagnostics report shows the interface
|
|
28
|
-
language of the reporting user, making failure reports easier to triage.
|
|
29
|
-
|
|
30
|
-
### Refactoring & Optimizations
|
|
31
|
-
|
|
32
|
-
- **Decoupled text-generation layer.** A new protocol-client layer
|
|
33
|
-
(`core/api/providers/` → base / OpenAI / Anthropic) plus a provider factory replaces the two
|
|
34
|
-
hard-coded Agnes chat client constructions, so pipelines and the screenwriter are untouched
|
|
35
|
-
while the underlying model source becomes pluggable. Custom providers reuse the existing
|
|
36
|
-
shared rate limiter and exponential-backoff retry policy, and failures are recorded in the
|
|
37
|
-
same error log as before.
|
|
38
|
-
- **Backend i18n runtime.** A new translation runtime plus request-scoped language middleware
|
|
39
|
-
gives the FastAPI side the same localization guarantees the frontend already had, with a
|
|
40
|
-
safe fallback chain that never turns a missing translation into a request failure.
|
|
9
|
+
* **Clearer key/domain setup to prevent `401`.** The API Key panel now states, per source, that keys added in the web UI can be bound to their own domain (and are covered by *Auto-detect domains*), while `.env` / environment-variable keys always follow the single **global default domain** and cannot be bound individually. Each `.env` key now shows a neutral "follows global domain" badge with the resolved endpoint. A new **multi-key** note explains that a single mismatched or expired key makes tasks intermittently fail with `401` whenever that key is picked. Getting Started and the FAQ gained a "match the key to the right site" section, and `.env.example` now spells out the `.env`-key behavior — so single-site users set the domain and mixed-site users move keys into the web config page.
|
|
10
|
+
* **True 16:9 landscape.** Landscape (16:9) video now renders at the correct aspect ratio, and the portrait / large-landscape resolution option labels were fixed so the listed size matches what is actually generated.
|
|
11
|
+
* **Refreshed language switcher.** The native browser language dropdown was replaced with a site-styled language switcher, consistent with the rest of the UI across all 22 locales.
|
|
41
12
|
|
|
42
13
|
### Bug Fixes
|
|
43
14
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
- The built-in Agnes provider no longer appears twice in the provider picker and is now
|
|
47
|
-
labelled as text-only.
|
|
48
|
-
- Non-Chinese interfaces no longer receive hard-coded Chinese network-diagnosis and task
|
|
49
|
-
messages (issue #64).
|
|
15
|
+
* Fixed the config page recommending "bind a matching domain for each key" on `.env`-sourced keys, which have no domain dropdown and cannot be bound — the misleading hint that repeatedly sent users down the wrong path when chasing `401` errors. The *Auto-detect domains* tooltip now correctly states it only probes web-UI keys.
|
|
16
|
+
* Corrected the Docker/compose image reference to the real flat GHCR namespace, so documented pull commands actually resolve.
|
|
50
17
|
|
|
51
18
|
---
|
|
52
19
|
|
|
53
|
-
No action is required after upgrading.
|
|
20
|
+
No action is required after upgrading. If you were hitting `401`, re-check your key against its site in the API Key panel or run *Auto-detect domains*.
|
|
54
21
|
|
|
55
22
|
---
|
|
56
23
|
|
package/core/api/agnes_video.py
CHANGED
|
@@ -15,10 +15,10 @@ from core.api.error_collector import collect_error, collect_error_from_exception
|
|
|
15
15
|
from core.api.key_manager import get_key_ring
|
|
16
16
|
from core.api.rate_limiter import get_rate_limiter, get_video_submit_limiter
|
|
17
17
|
from core.config import (
|
|
18
|
-
VIDEO_ASPECT_RATIOS,
|
|
19
18
|
get_agnes_api_root,
|
|
20
19
|
get_base_url_for_key,
|
|
21
20
|
is_v25_video_model,
|
|
21
|
+
width_height_to_aspect_ratio,
|
|
22
22
|
)
|
|
23
23
|
from utils.image_normalizer import normalize_reference_path
|
|
24
24
|
from utils.video import download_video
|
|
@@ -271,7 +271,7 @@ class AgnesVideoAPI:
|
|
|
271
271
|
return 961 # 480p tier
|
|
272
272
|
|
|
273
273
|
def _get_frame_config(self, duration: Optional[int] = None,
|
|
274
|
-
width: int =
|
|
274
|
+
width: int = 1280, height: int = 720) -> tuple:
|
|
275
275
|
d = duration or self.default_duration
|
|
276
276
|
max_nf = self._get_max_frames(width, height)
|
|
277
277
|
if d in DURATION_PRESETS:
|
|
@@ -563,8 +563,8 @@ class AgnesVideoAPI:
|
|
|
563
563
|
prompt: str,
|
|
564
564
|
reference_image_paths: List[str] = [],
|
|
565
565
|
duration: Optional[int] = None,
|
|
566
|
-
width: int =
|
|
567
|
-
height: int =
|
|
566
|
+
width: int = 1280,
|
|
567
|
+
height: int = 720,
|
|
568
568
|
seed: Optional[int] = None,
|
|
569
569
|
negative_prompt: Optional[str] = None,
|
|
570
570
|
progress_callback=None,
|
|
@@ -587,8 +587,8 @@ class AgnesVideoAPI:
|
|
|
587
587
|
prompt: str,
|
|
588
588
|
reference_image_paths: List[str] = [],
|
|
589
589
|
duration: Optional[int] = None,
|
|
590
|
-
width: int =
|
|
591
|
-
height: int =
|
|
590
|
+
width: int = 1280,
|
|
591
|
+
height: int = 720,
|
|
592
592
|
seed: Optional[int] = None,
|
|
593
593
|
negative_prompt: Optional[str] = None,
|
|
594
594
|
**kwargs,
|
|
@@ -649,31 +649,21 @@ class AgnesVideoAPI:
|
|
|
649
649
|
|
|
650
650
|
@staticmethod
|
|
651
651
|
def _width_height_to_aspect_ratio(width: int, height: int) -> str:
|
|
652
|
-
"""
|
|
652
|
+
"""将像素宽高映射到 2.5 系列 aspect_ratio 枚举(委托 ``core.config``)。
|
|
653
653
|
|
|
654
|
-
|
|
654
|
+
映射规则已上提到 ``core.config.width_height_to_aspect_ratio``,供回归
|
|
655
|
+
校验脚本共用(保证「提交」与「校验」同一套规则);此方法保留为类内
|
|
656
|
+
调用入口,行为与上提前完全一致。
|
|
655
657
|
"""
|
|
656
|
-
|
|
657
|
-
return "16:9"
|
|
658
|
-
ratio = width / height
|
|
659
|
-
best = "16:9"
|
|
660
|
-
best_dist = float("inf")
|
|
661
|
-
for ar in VIDEO_ASPECT_RATIOS:
|
|
662
|
-
w, h = ar.split(":")
|
|
663
|
-
target = int(w) / int(h)
|
|
664
|
-
dist = abs(ratio - target)
|
|
665
|
-
if dist < best_dist:
|
|
666
|
-
best_dist = dist
|
|
667
|
-
best = ar
|
|
668
|
-
return best
|
|
658
|
+
return width_height_to_aspect_ratio(width, height)
|
|
669
659
|
|
|
670
660
|
async def _submit_video_v25(
|
|
671
661
|
self,
|
|
672
662
|
prompt: str,
|
|
673
663
|
reference_image_paths: List[str],
|
|
674
664
|
duration: Optional[int] = None,
|
|
675
|
-
width: int =
|
|
676
|
-
height: int =
|
|
665
|
+
width: int = 1280,
|
|
666
|
+
height: int = 720,
|
|
677
667
|
seed: Optional[int] = None,
|
|
678
668
|
**kwargs,
|
|
679
669
|
) -> str:
|
package/core/config.py
CHANGED
|
@@ -18,7 +18,7 @@ CONFIG_FILE = os.path.join(CONFIG_DIR, "config.json")
|
|
|
18
18
|
# ═══════════════════════════════════════════════════
|
|
19
19
|
# 应用版本号(v6.1 新增:发版时同步更新,见 docs/dev/release_process.md)
|
|
20
20
|
# ═══════════════════════════════════════════════════
|
|
21
|
-
APP_VERSION = "7.0.
|
|
21
|
+
APP_VERSION = "7.0.2"
|
|
22
22
|
|
|
23
23
|
# 未配置 API Key 时的统一报错文案(含免费获取与在线体验兜底,全站路由共用)
|
|
24
24
|
#
|
|
@@ -903,7 +903,7 @@ def set_watermark_config(enabled: bool = None, language: str = None):
|
|
|
903
903
|
|
|
904
904
|
VIDEO_RESOLUTION_PRESETS = {
|
|
905
905
|
"portrait": {"width": 768, "height": 1152, "label": "竖屏 9:16"},
|
|
906
|
-
"landscape": {"width":
|
|
906
|
+
"landscape": {"width": 1280, "height": 720, "label": "横屏 16:9"},
|
|
907
907
|
"square": {"width": 1024, "height": 1024, "label": "方形 1:1"},
|
|
908
908
|
}
|
|
909
909
|
|
|
@@ -1085,6 +1085,63 @@ def is_v25_video_model(model: str) -> bool:
|
|
|
1085
1085
|
# 支持的画幅比例(2.5 系列 aspect_ratio 枚举)
|
|
1086
1086
|
VIDEO_ASPECT_RATIOS = ["21:9", "16:9", "4:3", "1:1", "3:4", "9:16"]
|
|
1087
1087
|
|
|
1088
|
+
# ── 项目标准像素档 → aspect_ratio 显式映射(语义优先于数值最近邻)──
|
|
1089
|
+
# 背景:2.5 系列只接受上面 6 档比例枚举,而非标准比例走「数值最近邻」会归错档:
|
|
1090
|
+
# · 1152x768(3:2, 1.500)距 4:3(1.333) 0.167 < 距 16:9(1.778) 0.278 → 误判 4:3
|
|
1091
|
+
# · 768x1152(2:3, 0.667)距 3:4(0.750) 0.083 < 距 9:16(0.563) 0.104 → 误判 3:4
|
|
1092
|
+
# 改度量方式(比值 / 对数距离)救不了这两个值——2:3 在几何上确实更贴近 3:4。
|
|
1093
|
+
# 但它们在前端就是「竖屏 9:16」「横屏 16:9」两个语义明确的惯例像素档,故显式查表,
|
|
1094
|
+
# 不让数值距离决定。表内其余档位与最近邻结果一致,仅作显式化,不改变既有行为。
|
|
1095
|
+
STANDARD_PIXEL_TO_RATIO = {
|
|
1096
|
+
# 竖屏
|
|
1097
|
+
(768, 1152): "9:16",
|
|
1098
|
+
(720, 1280): "9:16",
|
|
1099
|
+
(768, 1344): "9:16",
|
|
1100
|
+
(1024, 1792): "9:16",
|
|
1101
|
+
# 横屏
|
|
1102
|
+
(1152, 768): "16:9",
|
|
1103
|
+
(1280, 720): "16:9",
|
|
1104
|
+
(1344, 768): "16:9",
|
|
1105
|
+
(1792, 1024): "16:9",
|
|
1106
|
+
# 方形与超宽
|
|
1107
|
+
(1024, 1024): "1:1",
|
|
1108
|
+
(960, 720): "4:3",
|
|
1109
|
+
(720, 960): "3:4",
|
|
1110
|
+
(1680, 720): "21:9",
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
def width_height_to_aspect_ratio(width: int, height: int) -> str:
|
|
1115
|
+
"""将像素宽高映射到 2.5 系列 aspect_ratio 枚举。
|
|
1116
|
+
|
|
1117
|
+
映射顺序:
|
|
1118
|
+
|
|
1119
|
+
1. 项目标准像素档显式查表(``STANDARD_PIXEL_TO_RATIO``)——语义优先,避免
|
|
1120
|
+
``768x1152``(竖屏 9:16)/ ``1152x768``(横屏 16:9)这类项目惯例档被
|
|
1121
|
+
数值最近邻误判成 ``3:4`` / ``4:3``;
|
|
1122
|
+
2. 未命中时取误差最小的档位(默认 ``16:9``)。
|
|
1123
|
+
|
|
1124
|
+
供 API 客户端(提交时推导 aspect_ratio)与回归校验脚本(校验时推导期望
|
|
1125
|
+
比例)共用,保证「提交」与「校验」使用同一套映射规则。
|
|
1126
|
+
"""
|
|
1127
|
+
if not width or not height:
|
|
1128
|
+
return "16:9"
|
|
1129
|
+
exact = STANDARD_PIXEL_TO_RATIO.get((width, height))
|
|
1130
|
+
if exact:
|
|
1131
|
+
return exact
|
|
1132
|
+
ratio = width / height
|
|
1133
|
+
best = "16:9"
|
|
1134
|
+
best_dist = float("inf")
|
|
1135
|
+
for ar in VIDEO_ASPECT_RATIOS:
|
|
1136
|
+
w, h = ar.split(":")
|
|
1137
|
+
target = int(w) / int(h)
|
|
1138
|
+
dist = abs(ratio - target)
|
|
1139
|
+
if dist < best_dist:
|
|
1140
|
+
best_dist = dist
|
|
1141
|
+
best = ar
|
|
1142
|
+
return best
|
|
1143
|
+
|
|
1144
|
+
|
|
1088
1145
|
# 2.5 系列时长档位(seconds 字符串 "4"–"12")
|
|
1089
1146
|
VIDEO_25_DURATIONS = [4, 5, 6, 8, 10, 12]
|
|
1090
1147
|
|
|
@@ -1104,7 +1161,7 @@ VIDEO_MODEL_CAPABILITIES = {
|
|
|
1104
1161
|
"type": "pixels",
|
|
1105
1162
|
"options": [
|
|
1106
1163
|
{"value": "768x1152", "label": {"zh": "竖屏 768x1152", "en": "Portrait 768x1152"}},
|
|
1107
|
-
{"value": "
|
|
1164
|
+
{"value": "1280x720", "label": {"zh": "横屏 1280x720", "en": "Landscape 1280x720"}},
|
|
1108
1165
|
{"value": "1024x1024", "label": {"zh": "方形 1024x1024", "en": "Square 1024x1024"}},
|
|
1109
1166
|
],
|
|
1110
1167
|
},
|