free-short-video 6.4.4 → 6.4.6
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 +17 -5
- package/README.md +6 -10
- package/core/api/agnes_chat.py +2 -1
- package/core/api/agnes_models.py +3 -3
- package/core/compositor/concatenator/audio_overlay.py +66 -8
- package/core/config.py +2 -2
- package/core/pipelines/anchor_video.py +2 -1
- package/core/pipelines/creative/pipeline.py +2 -1
- package/core/pipelines/manuscript_video.py +2 -1
- package/core/pipelines/poetry_video.py +2 -1
- package/core/pipelines/simple_video.py +2 -1
- package/core/screenwriter/__init__.py +2 -2
- package/package.json +1 -1
package/.env.example
CHANGED
|
@@ -16,22 +16,32 @@
|
|
|
16
16
|
|
|
17
17
|
# ── 1. API Key(必填)──────────────────────────────────────────────
|
|
18
18
|
# 从 https://platform.agnes-ai.com 获取免费 Key
|
|
19
|
+
# ⚠️ 主 Key 的变量名不带序号(就是 AGNES_API_KEY,没有 AGNES_API_KEY_1 这个槽位)
|
|
19
20
|
AGNES_API_KEY=your-api-key-here
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
# ── 2. 多 Key 轮询(可选,推荐)────────────────────────────────────
|
|
23
24
|
# 每个 Key 的配额独立,总量 ≈ 20 × Key 数 / 分钟。
|
|
24
|
-
#
|
|
25
|
-
#
|
|
25
|
+
# 命名规则:主 Key 用 AGNES_API_KEY,额外 Key 从 AGNES_API_KEY_2 起序号依次递增
|
|
26
|
+
# (_2、_3、_4 ...),中间不可断号(断号之后的 Key 不会被加载)。
|
|
26
27
|
# 遇到 429 会自动轮换到下一个 Key;限速配额与并发上限随 Key 数线性放大。
|
|
27
28
|
# AGNES_API_KEY_2=your-second-api-key
|
|
28
29
|
# AGNES_API_KEY_3=your-third-api-key
|
|
30
|
+
# AGNES_API_KEY_4=your-fourth-api-key
|
|
31
|
+
# AGNES_API_KEY_5=your-fifth-api-key
|
|
29
32
|
|
|
30
33
|
|
|
31
|
-
# ── 3.
|
|
34
|
+
# ── 3. 本地服务监听地址(非 Agnes API 地址)─────────────────────────
|
|
32
35
|
HOST=0.0.0.0
|
|
33
36
|
PORT=8765
|
|
34
37
|
|
|
38
|
+
# 注:Agnes API 走哪个站点(国际站 / 国内站)**不通过环境变量配置**
|
|
39
|
+
# (AGNES_BASE_URL 已废弃,代码中不再读取)。请在 Web 设置页的 API Key 面板
|
|
40
|
+
# 选择域名,或用「自动探测域名」逐 Key 补全匹配域名(每个 Key 可绑定各自域名)。
|
|
41
|
+
# 可选域名:com = apihub.agnes-ai.com(国际站)、cn = api.agnes-ai.cn(国内站,
|
|
42
|
+
# 需国内站专属 Key)、cn_bak = apihub.agnes-ai.cn(备用,国际站 Key 亦可用)。
|
|
43
|
+
# 跨站使用 Key 会得到 HTTP 401 / 无效的令牌。
|
|
44
|
+
|
|
35
45
|
|
|
36
46
|
# ── 4. 限速(可选)─────────────────────────────────────────────────
|
|
37
47
|
# 共享桶:Chat / 图片生成 / 图片上传 / 结果轮询 共用
|
|
@@ -54,8 +64,10 @@ PORT=8765
|
|
|
54
64
|
|
|
55
65
|
|
|
56
66
|
# ── 5. 图生图模型(可选)───────────────────────────────────────────
|
|
57
|
-
# i2i 默认与 t2i
|
|
58
|
-
# AGNES_IMAGE_I2I_MODEL=agnes-image-2.
|
|
67
|
+
# i2i 默认与 t2i 同模型(当前默认 agnes-image-2.5-flash);如需为 i2i 固定旧版:
|
|
68
|
+
# AGNES_IMAGE_I2I_MODEL=agnes-image-2.1-flash
|
|
69
|
+
# (真实模型 ID 形如 agnes-image-2.5-flash / agnes-image-2.1-flash /
|
|
70
|
+
# agnes-image-2.0-flash,不带 -flash 后缀的写法无效)
|
|
59
71
|
#
|
|
60
72
|
# 注:视频 / 图片主模型请通过 Web UI 或 POST /api/config 选择,
|
|
61
73
|
# 不再通过环境变量配置(AGNES_VIDEO_MODEL、AGNES_IMAGE_MODEL、
|
package/README.md
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
|
|
3
|
-
# What's New in v6.4.
|
|
3
|
+
# What's New in v6.4.6
|
|
4
4
|
|
|
5
5
|
## What's New
|
|
6
6
|
|
|
7
|
-
###
|
|
7
|
+
### Bug Fixes
|
|
8
8
|
|
|
9
|
-
* **
|
|
10
|
-
|
|
11
|
-
* **Agnes Image 2.5 Flash added and set as default** — the latest generation image model `agnes-image-2.5-flash` is now the default for both text-to-image and image-to-image workflows; the older `agnes-image-2.1-flash` and `agnes-image-2.0-flash` remain available as selectable options.
|
|
12
|
-
|
|
13
|
-
* **LLM upgraded to Agnes 2.5 Flash** — the deprecated `agnes-2.0-flash` text model is removed from the selector and replaced by `agnes-2.5-flash` for story, script, and narration generation, following the official model deprecation notice.
|
|
9
|
+
* **Digital human (anchor) videos no longer fail at the stitch/composite step in Docker** — anchor tasks crashed while looping the presenter clip and compositing it with narration audio and subtitles, and retrying did not help because the underlying cause was permanent. The container ships only the bundled `ffmpeg` binary (no `ffprobe`), and the clip-duration probe did not handle a missing `ffprobe`. Media duration is now probed through `ffmpeg` whenever `ffprobe` is unavailable, with a safe default as a final fallback, so digital-human video composition completes normally in Docker and other minimal environments.
|
|
14
10
|
|
|
15
11
|
---
|
|
16
12
|
|
|
17
|
-
|
|
13
|
+
No action is required after upgrading.
|
|
18
14
|
|
|
19
15
|
---
|
|
20
16
|
|
|
@@ -37,7 +33,7 @@ free-short-video
|
|
|
37
33
|
|
|
38
34
|
[](/README_ZH.md)
|
|
39
35
|
[](https://github.com/lcy362/agnes-video-generator)
|
|
40
|
-
[](https://github.com/lcy362/agnes-video-generator/blob/
|
|
36
|
+
[](https://github.com/lcy362/agnes-video-generator/blob/HEAD/LICENSE)
|
|
41
37
|
[](https://www.python.org/)
|
|
42
38
|
[](https://video.lichuanyang.top)
|
|
43
39
|
[](https://hub.docker.com/r/lcy362/free-short-video)
|
|
@@ -194,7 +190,7 @@ Full walkthrough: [Getting Started → Configure API Key](docs/public/getting-st
|
|
|
194
190
|
- **[Getting Started](docs/public/getting-started.md)** — Install and deploy in 4 ways: Manual (`start.sh`), Docker, npm (`npx free-short-video`), or AI-Agent assisted.
|
|
195
191
|
- **[Usage Guide](docs/public/usage.md)** — Configure your API key, pick a video mode, resume from checkpoints, the three chaining modes, and logs & output layout.
|
|
196
192
|
- **[Architecture](docs/public/architecture.md)** — Project structure and tech stack.
|
|
197
|
-
- **[API Reference](docs/public/api.md)** — Full REST
|
|
193
|
+
- **[API Reference](docs/public/api.md)** — Full REST endpoint list (progress via polling, no WebSocket).
|
|
198
194
|
- **[FAQ](docs/public/faq.md)** — Frequently asked questions.
|
|
199
195
|
- **[About & License](docs/public/about.md)** — Acknowledgments and the MIT license.
|
|
200
196
|
|
package/core/api/agnes_chat.py
CHANGED
|
@@ -16,6 +16,7 @@ import requests
|
|
|
16
16
|
|
|
17
17
|
from core.api.error_collector import collect_error, collect_error_from_exception
|
|
18
18
|
from core.api.rate_limiter import get_rate_limiter, request_with_key_rotation
|
|
19
|
+
from core.config import DEFAULT_TEXT_MODEL
|
|
19
20
|
|
|
20
21
|
logger = logging.getLogger(__name__)
|
|
21
22
|
|
|
@@ -58,7 +59,7 @@ def strip_code_fence(text: str) -> str:
|
|
|
58
59
|
class AgnesChatAPI:
|
|
59
60
|
"""Agnes LLM Chat API 封装(text + multimodal)。"""
|
|
60
61
|
|
|
61
|
-
def __init__(self, api_key: str, model: str =
|
|
62
|
+
def __init__(self, api_key: str, model: str = DEFAULT_TEXT_MODEL):
|
|
62
63
|
self.api_key = api_key
|
|
63
64
|
self.model = model
|
|
64
65
|
# 基础 headers(不含 Authorization):每次请求前经 _auth_headers() 注入当前 Key
|
package/core/api/agnes_models.py
CHANGED
|
@@ -21,12 +21,12 @@ REQUEST_TIMEOUT = 20
|
|
|
21
21
|
|
|
22
22
|
# 分组失败时的兜底列表
|
|
23
23
|
_FALLBACK = {
|
|
24
|
-
"text": [DEFAULT_TEXT_MODEL],
|
|
24
|
+
"text": [DEFAULT_TEXT_MODEL, "agnes-2.5-flash"],
|
|
25
25
|
"image": [DEFAULT_IMAGE_MODEL, "agnes-image-2.1-flash", "agnes-image-2.0-flash"],
|
|
26
26
|
"video": [DEFAULT_VIDEO_MODEL],
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
# 已废弃、应从可选列表中剔除的模型 ID(如 agnes-2.0-flash
|
|
29
|
+
# 已废弃、应从可选列表中剔除的模型 ID(如 agnes-2.0-flash,官方已迁移至新版本)
|
|
30
30
|
_DEPRECATED_MODELS = {"agnes-2.0-flash"}
|
|
31
31
|
|
|
32
32
|
|
|
@@ -35,7 +35,7 @@ def _classify(model_id: str) -> str:
|
|
|
35
35
|
|
|
36
36
|
- ``agnes-image*`` → image
|
|
37
37
|
- ``agnes-video*`` → video
|
|
38
|
-
- 其余(如 ``agnes-
|
|
38
|
+
- 其余(如 ``agnes-3.0-flash``)→ text
|
|
39
39
|
"""
|
|
40
40
|
if model_id.startswith("agnes-image"):
|
|
41
41
|
return "image"
|
|
@@ -7,6 +7,7 @@ import itertools
|
|
|
7
7
|
import json
|
|
8
8
|
import logging
|
|
9
9
|
import os
|
|
10
|
+
import re
|
|
10
11
|
import subprocess
|
|
11
12
|
from typing import List, Optional, Tuple
|
|
12
13
|
|
|
@@ -771,6 +772,69 @@ class AudioOverlayMixin:
|
|
|
771
772
|
logger.warning(f"[Compositor] merge scene srts failed: {e}")
|
|
772
773
|
return False
|
|
773
774
|
|
|
775
|
+
@staticmethod
|
|
776
|
+
def _probe_clip_duration(path: str, default: float = 5.0) -> float:
|
|
777
|
+
"""探测媒体文件时长(秒),三级兜底。
|
|
778
|
+
|
|
779
|
+
修复 Issue #54:Docker 镜像仅暴露 imageio-ffmpeg 自带的 ``ffmpeg``,
|
|
780
|
+
不含 ``ffprobe``,``resolve_binary("ffprobe")`` 返回 ``None``;若直接传入
|
|
781
|
+
``subprocess.run([None, ...])`` 会在 ``os.path.dirname(None)`` 处抛
|
|
782
|
+
``TypeError``。此处按可用性依次尝试:
|
|
783
|
+
|
|
784
|
+
1. ``ffprobe``(解析到真实路径时才用);
|
|
785
|
+
2. ``ffmpeg -i`` 的 stderr ``Duration:`` 行(ffmpeg 为硬依赖,镜像必有);
|
|
786
|
+
3. 调用方给定的 ``default``。
|
|
787
|
+
|
|
788
|
+
Args:
|
|
789
|
+
path: 媒体文件路径。
|
|
790
|
+
default: 全部探测失败时返回的兜底时长(秒)。
|
|
791
|
+
|
|
792
|
+
Returns:
|
|
793
|
+
时长(秒);无法探测时返回 ``default``。
|
|
794
|
+
"""
|
|
795
|
+
# 1) ffprobe(可能为 None,必须先判空)
|
|
796
|
+
ffprobe = resolve_binary("ffprobe")
|
|
797
|
+
if ffprobe:
|
|
798
|
+
try:
|
|
799
|
+
r = subprocess.run(
|
|
800
|
+
[ffprobe, "-v", "error", "-show_entries", "format=duration",
|
|
801
|
+
"-of", "csv=p=0", path],
|
|
802
|
+
stdin=subprocess.DEVNULL, capture_output=True, text=True, timeout=15,
|
|
803
|
+
)
|
|
804
|
+
val = float((r.stdout or "").strip() or 0)
|
|
805
|
+
if val > 0:
|
|
806
|
+
return val
|
|
807
|
+
except Exception as e:
|
|
808
|
+
logger.warning(f"[Compositor] ffprobe duration failed: {e}")
|
|
809
|
+
|
|
810
|
+
# 2) ffmpeg stderr 解析(ffmpeg 是硬依赖,Docker 镜像必有)
|
|
811
|
+
ffmpeg = resolve_binary("ffmpeg")
|
|
812
|
+
if ffmpeg:
|
|
813
|
+
try:
|
|
814
|
+
r = subprocess.run(
|
|
815
|
+
[ffmpeg, "-hide_banner", "-i", path],
|
|
816
|
+
stdin=subprocess.DEVNULL, capture_output=True, text=True, timeout=15,
|
|
817
|
+
)
|
|
818
|
+
m = re.search(
|
|
819
|
+
r"Duration:\s*(\d+):(\d+):(\d+(?:\.\d+)?)", r.stderr or ""
|
|
820
|
+
)
|
|
821
|
+
if m:
|
|
822
|
+
h, mi, s = m.groups()
|
|
823
|
+
val = int(h) * 3600 + int(mi) * 60 + float(s)
|
|
824
|
+
if val > 0:
|
|
825
|
+
logger.info(
|
|
826
|
+
f"[Compositor] duration via ffmpeg fallback: {val:.2f}s ({path})"
|
|
827
|
+
)
|
|
828
|
+
return val
|
|
829
|
+
except Exception as e:
|
|
830
|
+
logger.warning(f"[Compositor] ffmpeg duration probe failed: {e}")
|
|
831
|
+
|
|
832
|
+
# 3) 默认兜底
|
|
833
|
+
logger.warning(
|
|
834
|
+
f"[Compositor] duration probe unavailable for {path}, using default {default}s"
|
|
835
|
+
)
|
|
836
|
+
return default
|
|
837
|
+
|
|
774
838
|
@staticmethod
|
|
775
839
|
def composite_anchor_video(
|
|
776
840
|
clip_path: str,
|
|
@@ -810,14 +874,8 @@ class AudioOverlayMixin:
|
|
|
810
874
|
)
|
|
811
875
|
os.makedirs(os.path.dirname(output_path) or ".", exist_ok=True)
|
|
812
876
|
|
|
813
|
-
# Step 1: Get clip duration
|
|
814
|
-
|
|
815
|
-
[resolve_binary("ffprobe"), "-v", "error", "-show_entries", "format=duration",
|
|
816
|
-
"-of", "csv=p=0", clip_path],
|
|
817
|
-
stdin=subprocess.DEVNULL,
|
|
818
|
-
capture_output=True, text=True, timeout=15,
|
|
819
|
-
)
|
|
820
|
-
clip_duration = float(probe.stdout.strip() or 5.0)
|
|
877
|
+
# Step 1: Get clip duration(ffprobe 不可用时回退 ffmpeg,修复 Issue #54)
|
|
878
|
+
clip_duration = AudioOverlayMixin._probe_clip_duration(clip_path, default=5.0)
|
|
821
879
|
if clip_duration <= 0:
|
|
822
880
|
clip_duration = 5.0
|
|
823
881
|
|
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 = "6.4.
|
|
21
|
+
APP_VERSION = "6.4.6"
|
|
22
22
|
|
|
23
23
|
# 未配置 API Key 时的统一报错文案(含免费获取与在线体验兜底,全站路由共用)
|
|
24
24
|
API_KEY_MISSING_MSG = (
|
|
@@ -870,7 +870,7 @@ DURATION_FRAME_MAP = {
|
|
|
870
870
|
# ═══════════════════════════════════════════════════
|
|
871
871
|
|
|
872
872
|
# 各类型 Agnes 模型默认值(与三个 API 客户端的默认 model 对齐)
|
|
873
|
-
DEFAULT_TEXT_MODEL = "agnes-
|
|
873
|
+
DEFAULT_TEXT_MODEL = "agnes-3.0-flash"
|
|
874
874
|
DEFAULT_IMAGE_MODEL = "agnes-image-2.5-flash"
|
|
875
875
|
DEFAULT_VIDEO_MODEL = "agnes-video-v2.0"
|
|
876
876
|
|
|
@@ -18,6 +18,7 @@ from typing import Callable, Optional
|
|
|
18
18
|
from core.api.agnes_image import AgnesImageAPI
|
|
19
19
|
from core.api.agnes_video import AgnesVideoAPI, VideoTaskCancelled
|
|
20
20
|
from core.compositor.concatenator import VideoConcatenator
|
|
21
|
+
from core.config import DEFAULT_TEXT_MODEL
|
|
21
22
|
from core.pipelines import MultiScenePipeline
|
|
22
23
|
from core.screenwriter import Screenwriter
|
|
23
24
|
from models.task import (
|
|
@@ -75,7 +76,7 @@ class AnchorPipeline(MultiScenePipeline):
|
|
|
75
76
|
api_key: str,
|
|
76
77
|
task_id: str,
|
|
77
78
|
dir_name: Optional[str] = None,
|
|
78
|
-
chat_model: str =
|
|
79
|
+
chat_model: str = DEFAULT_TEXT_MODEL,
|
|
79
80
|
image_model: str = "agnes-image-2.5-flash",
|
|
80
81
|
video_model: str = "agnes-video-v2.0",
|
|
81
82
|
progress_callback: Optional[Callable] = None,
|
|
@@ -8,6 +8,7 @@ from typing import Callable, Optional
|
|
|
8
8
|
|
|
9
9
|
from core.api.agnes_image import AgnesImageAPI
|
|
10
10
|
from core.api.agnes_video import AgnesVideoAPI
|
|
11
|
+
from core.config import DEFAULT_TEXT_MODEL
|
|
11
12
|
from core.pipelines import MultiScenePipeline
|
|
12
13
|
from core.screenwriter import Screenwriter
|
|
13
14
|
from models.task import CreativeVideoTask
|
|
@@ -47,7 +48,7 @@ class CreativeVideoPipeline(
|
|
|
47
48
|
api_key: str,
|
|
48
49
|
task_id: str,
|
|
49
50
|
dir_name: Optional[str] = None,
|
|
50
|
-
chat_model: str =
|
|
51
|
+
chat_model: str = DEFAULT_TEXT_MODEL,
|
|
51
52
|
image_model: str = "agnes-image-2.5-flash",
|
|
52
53
|
video_model: str = "agnes-video-v2.0",
|
|
53
54
|
progress_callback: Optional[Callable] = None,
|
|
@@ -19,6 +19,7 @@ from core.api.agnes_video import AgnesVideoAPI, VideoTaskCancelled
|
|
|
19
19
|
from core.async_io import read_text
|
|
20
20
|
from core.audio.voices import duration_len, estimate_chars_per_sec
|
|
21
21
|
from core.compositor.concatenator import VideoConcatenator
|
|
22
|
+
from core.config import DEFAULT_TEXT_MODEL
|
|
22
23
|
from core.pipelines import MultiScenePipeline
|
|
23
24
|
from core.screenwriter import Screenwriter, is_prompt_language_explicit
|
|
24
25
|
from models.task import (
|
|
@@ -144,7 +145,7 @@ class ManuscriptVideoPipeline(MultiScenePipeline):
|
|
|
144
145
|
api_key: str,
|
|
145
146
|
task_id: str,
|
|
146
147
|
dir_name: str = None,
|
|
147
|
-
chat_model: str =
|
|
148
|
+
chat_model: str = DEFAULT_TEXT_MODEL,
|
|
148
149
|
image_model: str = "agnes-image-2.5-flash",
|
|
149
150
|
video_model: str = "agnes-video-v2.0",
|
|
150
151
|
progress_callback: Optional[Callable] = None,
|
|
@@ -19,6 +19,7 @@ from core.api.agnes_video import AgnesVideoAPI
|
|
|
19
19
|
from core.audio.subtitle import SubtitleGenerator
|
|
20
20
|
from core.audio.tts import SilentTTSEngine
|
|
21
21
|
from core.compositor.concatenator import VideoConcatenator
|
|
22
|
+
from core.config import DEFAULT_TEXT_MODEL
|
|
22
23
|
from core.pipelines import MultiScenePipeline
|
|
23
24
|
from core.screenwriter import Screenwriter, clean_narration_text
|
|
24
25
|
from models.task import (
|
|
@@ -73,7 +74,7 @@ class PoetryVideoPipeline(MultiScenePipeline):
|
|
|
73
74
|
api_key: str,
|
|
74
75
|
task_id: str,
|
|
75
76
|
dir_name: Optional[str] = None,
|
|
76
|
-
chat_model: str =
|
|
77
|
+
chat_model: str = DEFAULT_TEXT_MODEL,
|
|
77
78
|
video_model: str = "agnes-video-v2.0",
|
|
78
79
|
progress_callback: Optional[callable] = None,
|
|
79
80
|
shutdown_event: Optional = None,
|
|
@@ -11,6 +11,7 @@ import traceback
|
|
|
11
11
|
from typing import Callable, Optional
|
|
12
12
|
|
|
13
13
|
from core.api.agnes_video import AgnesVideoAPI
|
|
14
|
+
from core.config import DEFAULT_TEXT_MODEL
|
|
14
15
|
from core.pipelines import BasePipeline, PipelineShutdown
|
|
15
16
|
from models.task import SimpleVideoTask, StepStatus
|
|
16
17
|
|
|
@@ -37,7 +38,7 @@ class SimpleVideoPipeline(BasePipeline):
|
|
|
37
38
|
api_key: str,
|
|
38
39
|
task_id: str,
|
|
39
40
|
dir_name: str = None,
|
|
40
|
-
chat_model: str =
|
|
41
|
+
chat_model: str = DEFAULT_TEXT_MODEL,
|
|
41
42
|
image_model: str = "agnes-image-2.5-flash",
|
|
42
43
|
video_model: str = "agnes-video-v2.0",
|
|
43
44
|
progress_callback: Optional[Callable] = None,
|
|
@@ -26,7 +26,7 @@ logger = logging.getLogger(__name__)
|
|
|
26
26
|
# "zh" — 所有 meta-prompt 使用中文(默认)
|
|
27
27
|
# "en" — 所有 meta-prompt 使用英文
|
|
28
28
|
# 示例:export PROMPT_LANGUAGE=en
|
|
29
|
-
from core.config import get_settings as _get_settings # noqa: I001 就地导入避免循环依赖
|
|
29
|
+
from core.config import DEFAULT_TEXT_MODEL, get_settings as _get_settings # noqa: I001 就地导入避免循环依赖
|
|
30
30
|
PROMPT_LANGUAGE = _get_settings().prompt_language
|
|
31
31
|
|
|
32
32
|
|
|
@@ -112,7 +112,7 @@ class Screenwriter(
|
|
|
112
112
|
对外接口与拆分前完全一致(mixin 组合,方法经 MRO 解析)。
|
|
113
113
|
"""
|
|
114
114
|
|
|
115
|
-
def __init__(self, api_key: str, model: str =
|
|
115
|
+
def __init__(self, api_key: str, model: str = DEFAULT_TEXT_MODEL, language: str = None):
|
|
116
116
|
self.api_key = api_key
|
|
117
117
|
self.model = model
|
|
118
118
|
self.language = language if language else PROMPT_LANGUAGE # "zh" 中文 / "en" 英文
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "free-short-video",
|
|
3
|
-
"version": "6.4.
|
|
3
|
+
"version": "6.4.6",
|
|
4
4
|
"description": "Free AI short-video generator — run the full free-short-video service locally with one command. Text-to-video, image generation, Edge-TTS narration, subtitles, and compositing, all free. Official site: https://video.lichuanyang.top",
|
|
5
5
|
"bin": {
|
|
6
6
|
"free-short-video": "bin/cli.js",
|