pycapcut 0.0.1__py3-none-any.whl
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.
- pyJianYingDraft/__init__.py +276 -0
- pyJianYingDraft/animation.py +140 -0
- pyJianYingDraft/assets/__init__.py +45 -0
- pyJianYingDraft/assets/draft_content_template.json +125 -0
- pyJianYingDraft/assets/draft_meta_info.json +67 -0
- pyJianYingDraft/audio_segment.py +225 -0
- pyJianYingDraft/draft_content_template.json +119 -0
- pyJianYingDraft/draft_folder.py +153 -0
- pyJianYingDraft/effect_segment.py +36 -0
- pyJianYingDraft/exceptions.py +23 -0
- pyJianYingDraft/jianying_controller.py +230 -0
- pyJianYingDraft/keyframe.py +94 -0
- pyJianYingDraft/local_materials.py +198 -0
- pyJianYingDraft/metadata/__init__.py +51 -0
- pyJianYingDraft/metadata/animation_meta.py +689 -0
- pyJianYingDraft/metadata/audio_effect_meta.py +367 -0
- pyJianYingDraft/metadata/audio_scene_effect.py +252 -0
- pyJianYingDraft/metadata/effect_meta.py +191 -0
- pyJianYingDraft/metadata/filter_meta.py +603 -0
- pyJianYingDraft/metadata/font_meta.py +341 -0
- pyJianYingDraft/metadata/mask_meta.py +15 -0
- pyJianYingDraft/metadata/speech_to_song.py +12 -0
- pyJianYingDraft/metadata/text_intro.py +152 -0
- pyJianYingDraft/metadata/text_loop.py +105 -0
- pyJianYingDraft/metadata/text_outro.py +105 -0
- pyJianYingDraft/metadata/tone_effect.py +107 -0
- pyJianYingDraft/metadata/transition_meta.py +733 -0
- pyJianYingDraft/metadata/video_character_effect.py +1913 -0
- pyJianYingDraft/metadata/video_effect_meta.py +9619 -0
- pyJianYingDraft/metadata/video_group_animation.py +131 -0
- pyJianYingDraft/metadata/video_intro.py +103 -0
- pyJianYingDraft/metadata/video_outro.py +80 -0
- pyJianYingDraft/metadata/video_scene_effect.py +7706 -0
- pyJianYingDraft/script_file.py +808 -0
- pyJianYingDraft/segment.py +256 -0
- pyJianYingDraft/template_mode.py +221 -0
- pyJianYingDraft/text_segment.py +436 -0
- pyJianYingDraft/time_util.py +99 -0
- pyJianYingDraft/track.py +138 -0
- pyJianYingDraft/util.py +58 -0
- pyJianYingDraft/video_segment.py +526 -0
- pycapcut/__init__.py +276 -0
- pycapcut/animation.py +140 -0
- pycapcut/assets/__init__.py +45 -0
- pycapcut/assets/draft_content_template.json +132 -0
- pycapcut/assets/draft_meta_info.json +73 -0
- pycapcut/audio_segment.py +225 -0
- pycapcut/draft_folder.py +153 -0
- pycapcut/effect_segment.py +36 -0
- pycapcut/exceptions.py +23 -0
- pycapcut/jianying_controller.py +230 -0
- pycapcut/keyframe.py +94 -0
- pycapcut/local_materials.py +198 -0
- pycapcut/metadata/__init__.py +51 -0
- pycapcut/metadata/audio_scene_effect.py +252 -0
- pycapcut/metadata/effect_meta.py +191 -0
- pycapcut/metadata/filter_meta.py +603 -0
- pycapcut/metadata/font_meta.py +341 -0
- pycapcut/metadata/mask_meta.py +15 -0
- pycapcut/metadata/speech_to_song.py +12 -0
- pycapcut/metadata/text_intro.py +152 -0
- pycapcut/metadata/text_loop.py +105 -0
- pycapcut/metadata/text_outro.py +105 -0
- pycapcut/metadata/tone_effect.py +107 -0
- pycapcut/metadata/transition_meta.py +733 -0
- pycapcut/metadata/video_character_effect.py +1913 -0
- pycapcut/metadata/video_group_animation.py +131 -0
- pycapcut/metadata/video_intro.py +103 -0
- pycapcut/metadata/video_outro.py +80 -0
- pycapcut/metadata/video_scene_effect.py +7706 -0
- pycapcut/script_file.py +808 -0
- pycapcut/segment.py +256 -0
- pycapcut/template_mode.py +221 -0
- pycapcut/text_segment.py +436 -0
- pycapcut/time_util.py +99 -0
- pycapcut/track.py +138 -0
- pycapcut/util.py +58 -0
- pycapcut/video_segment.py +526 -0
- pycapcut-0.0.1.dist-info/METADATA +77 -0
- pycapcut-0.0.1.dist-info/RECORD +88 -0
- pycapcut-0.0.1.dist-info/WHEEL +5 -0
- pycapcut-0.0.1.dist-info/top_level.txt +1 -0
- tools/__init__.py +17 -0
- tools/build_release.py +270 -0
- tools/code_generator.py +247 -0
- tools/extract_all.py +256 -0
- tools/extractor_base.py +132 -0
- tools/jianying_extractor.py +262 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from .local_materials import CropSettings, VideoMaterial, AudioMaterial
|
|
5
|
+
from .keyframe import KeyframeProperty
|
|
6
|
+
|
|
7
|
+
from .time_util import Timerange
|
|
8
|
+
from .audio_segment import AudioSegment
|
|
9
|
+
from .video_segment import VideoSegment, StickerSegment, ClipSettings
|
|
10
|
+
from .effect_segment import EffectSegment, FilterSegment
|
|
11
|
+
from .text_segment import TextSegment, TextStyle, TextBorder, TextBackground
|
|
12
|
+
|
|
13
|
+
from .metadata import FontType
|
|
14
|
+
from .metadata import MaskType
|
|
15
|
+
from .metadata import TransitionType, FilterType
|
|
16
|
+
from .metadata import IntroType, OutroType, GroupAnimationType
|
|
17
|
+
from .metadata import TextIntro, TextOutro, TextLoopAnim
|
|
18
|
+
from .metadata import AudioSceneEffectType
|
|
19
|
+
from .metadata import VideoSceneEffectType, VideoCharacterEffectType
|
|
20
|
+
|
|
21
|
+
from .track import TrackType
|
|
22
|
+
from .template_mode import ShrinkMode, ExtendMode
|
|
23
|
+
from .script_file import ScriptFile
|
|
24
|
+
from .draft_folder import DraftFolder
|
|
25
|
+
|
|
26
|
+
# 仅在Windows系统下导入jianying_controller
|
|
27
|
+
ISWIN = (sys.platform == 'win32')
|
|
28
|
+
if ISWIN:
|
|
29
|
+
from .jianying_controller import JianyingController, ExportResolution, ExportFramerate
|
|
30
|
+
|
|
31
|
+
from .time_util import SEC, tim, trange
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _deprecated_class_warning(old_name: str, new_name: str):
|
|
35
|
+
warnings.warn(
|
|
36
|
+
f"{old_name} is deprecated and will be removed in a future version. "
|
|
37
|
+
f"Use {new_name} instead.",
|
|
38
|
+
DeprecationWarning,
|
|
39
|
+
stacklevel=3
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# 保持向后兼容
|
|
43
|
+
class Script_file:
|
|
44
|
+
"""Deprecated: Use ScriptFile instead."""
|
|
45
|
+
def __new__(cls, *args, **kwargs):
|
|
46
|
+
_deprecated_class_warning("Script_file", "ScriptFile")
|
|
47
|
+
return ScriptFile(*args, **kwargs)
|
|
48
|
+
|
|
49
|
+
class Draft_folder:
|
|
50
|
+
"""Deprecated: Use DraftFolder instead."""
|
|
51
|
+
def __new__(cls, *args, **kwargs):
|
|
52
|
+
_deprecated_class_warning("Draft_folder", "DraftFolder")
|
|
53
|
+
return DraftFolder(*args, **kwargs)
|
|
54
|
+
|
|
55
|
+
class Shrink_mode:
|
|
56
|
+
"""Deprecated: Use ShrinkMode instead."""
|
|
57
|
+
def __new__(cls, *args, **kwargs):
|
|
58
|
+
_deprecated_class_warning("Shrink_mode", "ShrinkMode")
|
|
59
|
+
return ShrinkMode(*args, **kwargs)
|
|
60
|
+
|
|
61
|
+
class Extend_mode:
|
|
62
|
+
"""Deprecated: Use ExtendMode instead."""
|
|
63
|
+
def __new__(cls, *args, **kwargs):
|
|
64
|
+
_deprecated_class_warning("Extend_mode", "ExtendMode")
|
|
65
|
+
return ExtendMode(*args, **kwargs)
|
|
66
|
+
|
|
67
|
+
class Clip_settings:
|
|
68
|
+
"""Deprecated: Use ClipSettings instead."""
|
|
69
|
+
def __new__(cls, *args, **kwargs):
|
|
70
|
+
_deprecated_class_warning("Clip_settings", "ClipSettings")
|
|
71
|
+
return ClipSettings(*args, **kwargs)
|
|
72
|
+
|
|
73
|
+
class Text_style:
|
|
74
|
+
"""Deprecated: Use TextStyle instead."""
|
|
75
|
+
def __new__(cls, *args, **kwargs):
|
|
76
|
+
_deprecated_class_warning("Text_style", "TextStyle")
|
|
77
|
+
return TextStyle(*args, **kwargs)
|
|
78
|
+
|
|
79
|
+
class Text_border:
|
|
80
|
+
"""Deprecated: Use TextBorder instead."""
|
|
81
|
+
def __new__(cls, *args, **kwargs):
|
|
82
|
+
_deprecated_class_warning("Text_border", "TextBorder")
|
|
83
|
+
return TextBorder(*args, **kwargs)
|
|
84
|
+
|
|
85
|
+
class Text_background:
|
|
86
|
+
"""Deprecated: Use TextBackground instead."""
|
|
87
|
+
def __new__(cls, *args, **kwargs):
|
|
88
|
+
_deprecated_class_warning("Text_background", "TextBackground")
|
|
89
|
+
return TextBackground(*args, **kwargs)
|
|
90
|
+
|
|
91
|
+
class Text_segment:
|
|
92
|
+
"""Deprecated: Use TextSegment instead."""
|
|
93
|
+
def __new__(cls, *args, **kwargs):
|
|
94
|
+
_deprecated_class_warning("Text_segment", "TextSegment")
|
|
95
|
+
return TextSegment(*args, **kwargs)
|
|
96
|
+
|
|
97
|
+
class Audio_segment:
|
|
98
|
+
"""Deprecated: Use AudioSegment instead."""
|
|
99
|
+
def __new__(cls, *args, **kwargs):
|
|
100
|
+
_deprecated_class_warning("Audio_segment", "AudioSegment")
|
|
101
|
+
return AudioSegment(*args, **kwargs)
|
|
102
|
+
|
|
103
|
+
class Video_segment:
|
|
104
|
+
"""Deprecated: Use VideoSegment instead."""
|
|
105
|
+
def __new__(cls, *args, **kwargs):
|
|
106
|
+
_deprecated_class_warning("Video_segment", "VideoSegment")
|
|
107
|
+
return VideoSegment(*args, **kwargs)
|
|
108
|
+
|
|
109
|
+
class Sticker_segment:
|
|
110
|
+
"""Deprecated: Use StickerSegment instead."""
|
|
111
|
+
def __new__(cls, *args, **kwargs):
|
|
112
|
+
_deprecated_class_warning("Sticker_segment", "StickerSegment")
|
|
113
|
+
return StickerSegment(*args, **kwargs)
|
|
114
|
+
|
|
115
|
+
class Effect_segment:
|
|
116
|
+
"""Deprecated: Use EffectSegment instead."""
|
|
117
|
+
def __new__(cls, *args, **kwargs):
|
|
118
|
+
_deprecated_class_warning("Effect_segment", "EffectSegment")
|
|
119
|
+
return EffectSegment(*args, **kwargs)
|
|
120
|
+
|
|
121
|
+
class Filter_segment:
|
|
122
|
+
"""Deprecated: Use FilterSegment instead."""
|
|
123
|
+
def __new__(cls, *args, **kwargs):
|
|
124
|
+
_deprecated_class_warning("Filter_segment", "FilterSegment")
|
|
125
|
+
return FilterSegment(*args, **kwargs)
|
|
126
|
+
|
|
127
|
+
class Video_material:
|
|
128
|
+
"""Deprecated: Use VideoMaterial instead."""
|
|
129
|
+
def __new__(cls, *args, **kwargs):
|
|
130
|
+
_deprecated_class_warning("Video_material", "VideoMaterial")
|
|
131
|
+
return VideoMaterial(*args, **kwargs)
|
|
132
|
+
|
|
133
|
+
class Audio_material:
|
|
134
|
+
"""Deprecated: Use AudioMaterial instead."""
|
|
135
|
+
def __new__(cls, *args, **kwargs):
|
|
136
|
+
_deprecated_class_warning("Audio_material", "AudioMaterial")
|
|
137
|
+
return AudioMaterial(*args, **kwargs)
|
|
138
|
+
|
|
139
|
+
class Crop_settings:
|
|
140
|
+
"""Deprecated: Use CropSettings instead."""
|
|
141
|
+
def __new__(cls, *args, **kwargs):
|
|
142
|
+
_deprecated_class_warning("Crop_settings", "CropSettings")
|
|
143
|
+
return CropSettings(*args, **kwargs)
|
|
144
|
+
|
|
145
|
+
# 枚举类的向后兼容 - 使用代理类
|
|
146
|
+
class _DeprecatedEnum:
|
|
147
|
+
"""带deprecation警告的枚举代理类"""
|
|
148
|
+
def __init__(self, original_enum, old_name, new_name):
|
|
149
|
+
self._enum = original_enum
|
|
150
|
+
self._old_name = old_name
|
|
151
|
+
self._new_name = new_name
|
|
152
|
+
|
|
153
|
+
def __getattr__(self, name):
|
|
154
|
+
# 当访问枚举成员时显示警告
|
|
155
|
+
_deprecated_class_warning(self._old_name, self._new_name)
|
|
156
|
+
return getattr(self._enum, name)
|
|
157
|
+
|
|
158
|
+
def __getitem__(self, name):
|
|
159
|
+
# 当通过索引访问时显示警告
|
|
160
|
+
_deprecated_class_warning(self._old_name, self._new_name)
|
|
161
|
+
return self._enum[name]
|
|
162
|
+
|
|
163
|
+
def __repr__(self):
|
|
164
|
+
return f"<Deprecated {self._old_name} (use {self._new_name} instead)>"
|
|
165
|
+
|
|
166
|
+
Track_type = _DeprecatedEnum(TrackType, "Track_type", "TrackType")
|
|
167
|
+
Font_type = _DeprecatedEnum(FontType, "Font_type", "FontType")
|
|
168
|
+
Mask_type = _DeprecatedEnum(MaskType, "Mask_type", "MaskType")
|
|
169
|
+
Filter_type = _DeprecatedEnum(FilterType, "Filter_type", "FilterType")
|
|
170
|
+
Transition_type = _DeprecatedEnum(TransitionType, "Transition_type", "TransitionType")
|
|
171
|
+
Intro_type = _DeprecatedEnum(IntroType, "Intro_type", "IntroType")
|
|
172
|
+
Outro_type = _DeprecatedEnum(OutroType, "Outro_type", "OutroType")
|
|
173
|
+
Group_animation_type = _DeprecatedEnum(GroupAnimationType, "Group_animation_type", "GroupAnimationType")
|
|
174
|
+
Text_intro = _DeprecatedEnum(TextIntro, "Text_intro", "TextIntro")
|
|
175
|
+
Text_outro = _DeprecatedEnum(TextOutro, "Text_outro", "TextOutro")
|
|
176
|
+
Text_loop_anim = _DeprecatedEnum(TextLoopAnim, "Text_loop_anim", "TextLoopAnim")
|
|
177
|
+
Audio_scene_effect_type = _DeprecatedEnum(AudioSceneEffectType, "Audio_scene_effect_type", "AudioSceneEffectType")
|
|
178
|
+
Video_scene_effect_type = _DeprecatedEnum(VideoSceneEffectType, "Video_scene_effect_type", "VideoSceneEffectType")
|
|
179
|
+
Video_character_effect_type = _DeprecatedEnum(VideoCharacterEffectType, "Video_character_effect_type", "VideoCharacterEffectType")
|
|
180
|
+
Keyframe_property = _DeprecatedEnum(KeyframeProperty, "Keyframe_property", "KeyframeProperty")
|
|
181
|
+
|
|
182
|
+
# 仅在Windows系统下定义jianying_controller相关的向后兼容类
|
|
183
|
+
if ISWIN:
|
|
184
|
+
class Jianying_controller:
|
|
185
|
+
"""Deprecated: Use JianyingController instead."""
|
|
186
|
+
def __new__(cls, *args, **kwargs):
|
|
187
|
+
_deprecated_class_warning("Jianying_controller", "JianyingController")
|
|
188
|
+
return JianyingController(*args, **kwargs)
|
|
189
|
+
|
|
190
|
+
Export_resolution = _DeprecatedEnum(ExportResolution, "Export_resolution", "ExportResolution")
|
|
191
|
+
Export_framerate = _DeprecatedEnum(ExportFramerate, "Export_framerate", "ExportFramerate")
|
|
192
|
+
|
|
193
|
+
# 基础__all__列表(所有平台通用)
|
|
194
|
+
__all__ = [
|
|
195
|
+
"FontType",
|
|
196
|
+
"MaskType",
|
|
197
|
+
"FilterType",
|
|
198
|
+
"TransitionType",
|
|
199
|
+
"IntroType",
|
|
200
|
+
"OutroType",
|
|
201
|
+
"GroupAnimationType",
|
|
202
|
+
"TextIntro",
|
|
203
|
+
"TextOutro",
|
|
204
|
+
"TextLoopAnim",
|
|
205
|
+
"AudioSceneEffectType",
|
|
206
|
+
"VideoSceneEffectType",
|
|
207
|
+
"VideoCharacterEffectType",
|
|
208
|
+
"CropSettings",
|
|
209
|
+
"VideoMaterial",
|
|
210
|
+
"AudioMaterial",
|
|
211
|
+
"KeyframeProperty",
|
|
212
|
+
"Timerange",
|
|
213
|
+
"AudioSegment",
|
|
214
|
+
"VideoSegment",
|
|
215
|
+
"StickerSegment",
|
|
216
|
+
"ClipSettings",
|
|
217
|
+
"EffectSegment",
|
|
218
|
+
"FilterSegment",
|
|
219
|
+
"TextSegment",
|
|
220
|
+
"TextStyle",
|
|
221
|
+
"TextBorder",
|
|
222
|
+
"TextBackground",
|
|
223
|
+
"TrackType",
|
|
224
|
+
"ShrinkMode",
|
|
225
|
+
"ExtendMode",
|
|
226
|
+
"ScriptFile",
|
|
227
|
+
"DraftFolder",
|
|
228
|
+
"SEC",
|
|
229
|
+
"tim",
|
|
230
|
+
"trange",
|
|
231
|
+
|
|
232
|
+
# 向后兼容的snake_case类
|
|
233
|
+
"Script_file",
|
|
234
|
+
"Draft_folder",
|
|
235
|
+
"Shrink_mode",
|
|
236
|
+
"Extend_mode",
|
|
237
|
+
"Track_type",
|
|
238
|
+
"Font_type",
|
|
239
|
+
"Mask_type",
|
|
240
|
+
"Filter_type",
|
|
241
|
+
"Transition_type",
|
|
242
|
+
"Intro_type",
|
|
243
|
+
"Outro_type",
|
|
244
|
+
"Group_animation_type",
|
|
245
|
+
"Text_intro",
|
|
246
|
+
"Text_outro",
|
|
247
|
+
"Text_loop_anim",
|
|
248
|
+
"Audio_scene_effect_type",
|
|
249
|
+
"Video_scene_effect_type",
|
|
250
|
+
"Video_character_effect_type",
|
|
251
|
+
"Clip_settings",
|
|
252
|
+
"Text_style",
|
|
253
|
+
"Text_border",
|
|
254
|
+
"Text_background",
|
|
255
|
+
"Text_segment",
|
|
256
|
+
"Audio_segment",
|
|
257
|
+
"Video_segment",
|
|
258
|
+
"Sticker_segment",
|
|
259
|
+
"Effect_segment",
|
|
260
|
+
"Filter_segment",
|
|
261
|
+
"Video_material",
|
|
262
|
+
"Audio_material",
|
|
263
|
+
"Crop_settings",
|
|
264
|
+
"Keyframe_property",
|
|
265
|
+
]
|
|
266
|
+
|
|
267
|
+
# 仅在Windows系统下添加jianying_controller相关的导出
|
|
268
|
+
if ISWIN:
|
|
269
|
+
__all__.extend([
|
|
270
|
+
"JianyingController",
|
|
271
|
+
"ExportResolution",
|
|
272
|
+
"ExportFramerate",
|
|
273
|
+
"Jianying_controller",
|
|
274
|
+
"Export_resolution",
|
|
275
|
+
"Export_framerate",
|
|
276
|
+
])
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"""定义视频/文本动画相关类"""
|
|
2
|
+
|
|
3
|
+
import uuid
|
|
4
|
+
|
|
5
|
+
from typing import Union, Optional
|
|
6
|
+
from typing import Literal, Dict, List, Any
|
|
7
|
+
|
|
8
|
+
from .time_util import Timerange
|
|
9
|
+
|
|
10
|
+
from .metadata import AnimationMeta
|
|
11
|
+
from .metadata import IntroType, OutroType, GroupAnimationType
|
|
12
|
+
from .metadata import TextIntro, TextOutro, TextLoopAnim
|
|
13
|
+
|
|
14
|
+
class Animation:
|
|
15
|
+
"""一个视频/文本动画效果"""
|
|
16
|
+
|
|
17
|
+
name: str
|
|
18
|
+
"""动画名称, 默认取为动画效果的名称"""
|
|
19
|
+
effect_id: str
|
|
20
|
+
"""另一种动画id, 由剪映本身提供"""
|
|
21
|
+
animation_type: str
|
|
22
|
+
"""动画类型, 在子类中定义"""
|
|
23
|
+
resource_id: str
|
|
24
|
+
"""资源id, 由剪映本身提供"""
|
|
25
|
+
|
|
26
|
+
start: int
|
|
27
|
+
"""动画相对此片段开头的偏移, 单位为微秒"""
|
|
28
|
+
duration: int
|
|
29
|
+
"""动画持续时间, 单位为微秒"""
|
|
30
|
+
|
|
31
|
+
is_video_animation: bool
|
|
32
|
+
"""是否为视频动画, 在子类中定义"""
|
|
33
|
+
|
|
34
|
+
def __init__(self, animation_meta: AnimationMeta, start: int, duration: int):
|
|
35
|
+
self.name = animation_meta.title
|
|
36
|
+
self.effect_id = animation_meta.effect_id
|
|
37
|
+
self.resource_id = animation_meta.resource_id
|
|
38
|
+
|
|
39
|
+
self.start = start
|
|
40
|
+
self.duration = duration
|
|
41
|
+
|
|
42
|
+
def export_json(self) -> Dict[str, Any]:
|
|
43
|
+
return {
|
|
44
|
+
"anim_adjust_params": None,
|
|
45
|
+
"platform": "all",
|
|
46
|
+
"panel": "video" if self.is_video_animation else "",
|
|
47
|
+
"material_type": "video" if self.is_video_animation else "sticker",
|
|
48
|
+
|
|
49
|
+
"name": self.name,
|
|
50
|
+
"id": self.effect_id,
|
|
51
|
+
"type": self.animation_type,
|
|
52
|
+
"resource_id": self.resource_id,
|
|
53
|
+
|
|
54
|
+
"start": self.start,
|
|
55
|
+
"duration": self.duration,
|
|
56
|
+
# 不导出path和request_id
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
class VideoAnimation(Animation):
|
|
60
|
+
"""一个视频动画效果"""
|
|
61
|
+
|
|
62
|
+
animation_type: Literal["in", "out", "group"]
|
|
63
|
+
|
|
64
|
+
def __init__(self, animation_type: Union[IntroType, OutroType, GroupAnimationType],
|
|
65
|
+
start: int, duration: int):
|
|
66
|
+
super().__init__(animation_type.value, start, duration)
|
|
67
|
+
|
|
68
|
+
if isinstance(animation_type, IntroType):
|
|
69
|
+
self.animation_type = "in"
|
|
70
|
+
elif isinstance(animation_type, OutroType):
|
|
71
|
+
self.animation_type = "out"
|
|
72
|
+
elif isinstance(animation_type, GroupAnimationType):
|
|
73
|
+
self.animation_type = "group"
|
|
74
|
+
|
|
75
|
+
self.is_video_animation = True
|
|
76
|
+
|
|
77
|
+
class Text_animation(Animation):
|
|
78
|
+
"""一个文本动画效果"""
|
|
79
|
+
|
|
80
|
+
animation_type: Literal["in", "out", "loop"]
|
|
81
|
+
|
|
82
|
+
def __init__(self, animation_type: Union[TextIntro, TextOutro, TextLoopAnim],
|
|
83
|
+
start: int, duration: int):
|
|
84
|
+
super().__init__(animation_type.value, start, duration)
|
|
85
|
+
|
|
86
|
+
if isinstance(animation_type, TextIntro):
|
|
87
|
+
self.animation_type = "in"
|
|
88
|
+
elif isinstance(animation_type, TextOutro):
|
|
89
|
+
self.animation_type = "out"
|
|
90
|
+
elif isinstance(animation_type, TextLoopAnim):
|
|
91
|
+
self.animation_type = "loop"
|
|
92
|
+
|
|
93
|
+
self.is_video_animation = False
|
|
94
|
+
|
|
95
|
+
class SegmentAnimations:
|
|
96
|
+
"""附加于某素材上的一系列动画
|
|
97
|
+
|
|
98
|
+
对视频片段:入场、出场或组合动画;对文本片段:入场、出场或循环动画"""
|
|
99
|
+
|
|
100
|
+
animation_id: str
|
|
101
|
+
"""系列动画的全局id, 自动生成"""
|
|
102
|
+
|
|
103
|
+
animations: List[Animation]
|
|
104
|
+
"""动画列表"""
|
|
105
|
+
|
|
106
|
+
def __init__(self):
|
|
107
|
+
self.animation_id = uuid.uuid4().hex
|
|
108
|
+
self.animations = []
|
|
109
|
+
|
|
110
|
+
def get_animation_trange(self, animation_type: Literal["in", "out", "group", "loop"]) -> Optional[Timerange]:
|
|
111
|
+
"""获取指定类型的动画的时间范围"""
|
|
112
|
+
for animation in self.animations:
|
|
113
|
+
if animation.animation_type == animation_type:
|
|
114
|
+
return Timerange(animation.start, animation.duration)
|
|
115
|
+
return None
|
|
116
|
+
|
|
117
|
+
def add_animation(self, animation: Union[VideoAnimation, Text_animation]) -> None:
|
|
118
|
+
# 不允许添加超过一个同类型的动画(如两个入场动画)
|
|
119
|
+
if animation.animation_type in [ani.animation_type for ani in self.animations]:
|
|
120
|
+
raise ValueError(f"当前片段已存在类型为 '{animation.animation_type}' 的动画")
|
|
121
|
+
|
|
122
|
+
if isinstance(animation, VideoAnimation):
|
|
123
|
+
# 不允许组合动画与出入场动画同时出现
|
|
124
|
+
if any(ani.animation_type == "group" for ani in self.animations):
|
|
125
|
+
raise ValueError("当前片段已存在组合动画, 此时不能添加其它动画")
|
|
126
|
+
if animation.animation_type == "group" and len(self.animations) > 0:
|
|
127
|
+
raise ValueError("当前片段已存在动画时, 不能添加组合动画")
|
|
128
|
+
elif isinstance(animation, Text_animation):
|
|
129
|
+
if any(ani.animation_type == "loop" for ani in self.animations):
|
|
130
|
+
raise ValueError("当前片段已存在循环动画, 若希望同时使用循环动画和入出场动画, 请先添加出入场动画再添加循环动画")
|
|
131
|
+
|
|
132
|
+
self.animations.append(animation)
|
|
133
|
+
|
|
134
|
+
def export_json(self) -> Dict[str, Any]:
|
|
135
|
+
return {
|
|
136
|
+
"id": self.animation_id,
|
|
137
|
+
"type": "sticker_animation",
|
|
138
|
+
"multi_language_current": "none",
|
|
139
|
+
"animations": [animation.export_json() for animation in self.animations]
|
|
140
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""
|
|
2
|
+
pyJianYingDraft 的资源管理模块,提供集中管理资源文件的方式,避免硬编码路径
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
# 获取当前模块所在目录
|
|
8
|
+
ASSETS_DIR = Path(__file__).parent
|
|
9
|
+
|
|
10
|
+
# 资源文件映射表 - 集中管理所有asset文件名
|
|
11
|
+
ASSET_FILES = {
|
|
12
|
+
# 模板文件
|
|
13
|
+
'DRAFT_CONTENT_TEMPLATE': 'draft_content_template.json',
|
|
14
|
+
'DRAFT_META_TEMPLATE': 'draft_meta_info.json',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
def get_asset_path(asset_name: str) -> Path:
|
|
18
|
+
"""
|
|
19
|
+
获取指定资源文件的完整路径
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
asset_name: 资源名称(ASSET_FILES中的key)
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
Path: 资源文件的完整路径
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
KeyError: 资源名称不存在
|
|
29
|
+
FileNotFoundError: 文件不存在
|
|
30
|
+
"""
|
|
31
|
+
if asset_name not in ASSET_FILES:
|
|
32
|
+
raise KeyError(f"Asset '{asset_name}' not found. Available assets: {list(ASSET_FILES.keys())}")
|
|
33
|
+
|
|
34
|
+
file_path = ASSETS_DIR / ASSET_FILES[asset_name]
|
|
35
|
+
|
|
36
|
+
if not file_path.exists():
|
|
37
|
+
raise FileNotFoundError(f"Asset file '{file_path}' does not exist")
|
|
38
|
+
|
|
39
|
+
return file_path
|
|
40
|
+
|
|
41
|
+
# 导出主要接口
|
|
42
|
+
__all__ = [
|
|
43
|
+
'get_asset_path',
|
|
44
|
+
'ASSET_FILES'
|
|
45
|
+
]
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
{
|
|
2
|
+
"canvas_config": {
|
|
3
|
+
"height": 1080,
|
|
4
|
+
"ratio": "original",
|
|
5
|
+
"width": 1920
|
|
6
|
+
},
|
|
7
|
+
"color_space": 0,
|
|
8
|
+
"config": {
|
|
9
|
+
"adjust_max_index": 1,
|
|
10
|
+
"attachment_info": [],
|
|
11
|
+
"combination_max_index": 1,
|
|
12
|
+
"export_range": null,
|
|
13
|
+
"extract_audio_last_index": 1,
|
|
14
|
+
"lyrics_recognition_id": "",
|
|
15
|
+
"lyrics_sync": true,
|
|
16
|
+
"lyrics_taskinfo": [],
|
|
17
|
+
"maintrack_adsorb": true,
|
|
18
|
+
"material_save_mode": 0,
|
|
19
|
+
"multi_language_current": "none",
|
|
20
|
+
"multi_language_list": [],
|
|
21
|
+
"multi_language_main": "none",
|
|
22
|
+
"multi_language_mode": "none",
|
|
23
|
+
"original_sound_last_index": 1,
|
|
24
|
+
"record_audio_last_index": 1,
|
|
25
|
+
"sticker_max_index": 1,
|
|
26
|
+
"subtitle_keywords_config": null,
|
|
27
|
+
"subtitle_recognition_id": "",
|
|
28
|
+
"subtitle_sync": true,
|
|
29
|
+
"subtitle_taskinfo": [],
|
|
30
|
+
"system_font_list": [],
|
|
31
|
+
"video_mute": false,
|
|
32
|
+
"zoom_info_params": null
|
|
33
|
+
},
|
|
34
|
+
"cover": null,
|
|
35
|
+
"create_time": 0,
|
|
36
|
+
"duration": 0,
|
|
37
|
+
"extra_info": null,
|
|
38
|
+
"fps": 30.0,
|
|
39
|
+
"free_render_index_mode_on": false,
|
|
40
|
+
"group_container": null,
|
|
41
|
+
"id": "91E08AC5-22FB-47e2-9AA0-7DC300FAEA2B",
|
|
42
|
+
"keyframe_graph_list": [],
|
|
43
|
+
"keyframes": {
|
|
44
|
+
"adjusts": [],
|
|
45
|
+
"audios": [],
|
|
46
|
+
"effects": [],
|
|
47
|
+
"filters": [],
|
|
48
|
+
"handwrites": [],
|
|
49
|
+
"stickers": [],
|
|
50
|
+
"texts": [],
|
|
51
|
+
"videos": []
|
|
52
|
+
},
|
|
53
|
+
"last_modified_platform": {
|
|
54
|
+
"app_id": 3704,
|
|
55
|
+
"app_source": "lv",
|
|
56
|
+
"app_version": "5.9.0",
|
|
57
|
+
"os": "windows"
|
|
58
|
+
},
|
|
59
|
+
"platform": {
|
|
60
|
+
"app_id": 3704,
|
|
61
|
+
"app_source": "lv",
|
|
62
|
+
"app_version": "5.9.0",
|
|
63
|
+
"os": "windows"
|
|
64
|
+
},
|
|
65
|
+
"materials": {
|
|
66
|
+
"ai_translates": [],
|
|
67
|
+
"audio_balances": [],
|
|
68
|
+
"audio_effects": [],
|
|
69
|
+
"audio_fades": [],
|
|
70
|
+
"audio_track_indexes": [],
|
|
71
|
+
"audios": [],
|
|
72
|
+
"beats": [],
|
|
73
|
+
"canvases": [],
|
|
74
|
+
"chromas": [],
|
|
75
|
+
"color_curves": [],
|
|
76
|
+
"digital_humans": [],
|
|
77
|
+
"drafts": [],
|
|
78
|
+
"effects": [],
|
|
79
|
+
"flowers": [],
|
|
80
|
+
"green_screens": [],
|
|
81
|
+
"handwrites": [],
|
|
82
|
+
"hsl": [],
|
|
83
|
+
"images": [],
|
|
84
|
+
"log_color_wheels": [],
|
|
85
|
+
"loudnesses": [],
|
|
86
|
+
"manual_deformations": [],
|
|
87
|
+
"masks": [],
|
|
88
|
+
"material_animations": [],
|
|
89
|
+
"material_colors": [],
|
|
90
|
+
"multi_language_refs": [],
|
|
91
|
+
"placeholders": [],
|
|
92
|
+
"plugin_effects": [],
|
|
93
|
+
"primary_color_wheels": [],
|
|
94
|
+
"realtime_denoises": [],
|
|
95
|
+
"shapes": [],
|
|
96
|
+
"smart_crops": [],
|
|
97
|
+
"smart_relights": [],
|
|
98
|
+
"sound_channel_mappings": [],
|
|
99
|
+
"speeds": [],
|
|
100
|
+
"stickers": [],
|
|
101
|
+
"tail_leaders": [],
|
|
102
|
+
"text_templates": [],
|
|
103
|
+
"texts": [],
|
|
104
|
+
"time_marks": [],
|
|
105
|
+
"transitions": [],
|
|
106
|
+
"video_effects": [],
|
|
107
|
+
"video_trackings": [],
|
|
108
|
+
"videos": [],
|
|
109
|
+
"vocal_beautifys": [],
|
|
110
|
+
"vocal_separations": []
|
|
111
|
+
},
|
|
112
|
+
"mutable_config": null,
|
|
113
|
+
"name": "",
|
|
114
|
+
"new_version": "110.0.0",
|
|
115
|
+
"relationships": [],
|
|
116
|
+
"render_index_track_mode_on": false,
|
|
117
|
+
"retouch_cover": null,
|
|
118
|
+
"source": "default",
|
|
119
|
+
"static_cover_image_path": "",
|
|
120
|
+
"time_marks": null,
|
|
121
|
+
"tracks": [
|
|
122
|
+
],
|
|
123
|
+
"update_time": 0,
|
|
124
|
+
"version": 360000
|
|
125
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cloud_package_completed_time": "",
|
|
3
|
+
"draft_cloud_capcut_purchase_info": "",
|
|
4
|
+
"draft_cloud_last_action_download": false,
|
|
5
|
+
"draft_cloud_materials": [],
|
|
6
|
+
"draft_cloud_purchase_info": "",
|
|
7
|
+
"draft_cloud_template_id": "",
|
|
8
|
+
"draft_cloud_tutorial_info": "",
|
|
9
|
+
"draft_cloud_videocut_purchase_info": "",
|
|
10
|
+
"draft_cover": "",
|
|
11
|
+
"draft_deeplink_url": "",
|
|
12
|
+
"draft_enterprise_info": {
|
|
13
|
+
"draft_enterprise_extra": "",
|
|
14
|
+
"draft_enterprise_id": "",
|
|
15
|
+
"draft_enterprise_name": "",
|
|
16
|
+
"enterprise_material": []
|
|
17
|
+
},
|
|
18
|
+
"draft_fold_path": "",
|
|
19
|
+
"draft_id": "BC69C7CD-7C5E-4185-B284-AF3E1047A664",
|
|
20
|
+
"draft_is_ai_packaging_used": false,
|
|
21
|
+
"draft_is_ai_shorts": false,
|
|
22
|
+
"draft_is_ai_translate": false,
|
|
23
|
+
"draft_is_article_video_draft": false,
|
|
24
|
+
"draft_is_from_deeplink": "false",
|
|
25
|
+
"draft_is_invisible": false,
|
|
26
|
+
"draft_materials": [
|
|
27
|
+
{
|
|
28
|
+
"type": 0,
|
|
29
|
+
"value": []
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"type": 1,
|
|
33
|
+
"value": []
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"type": 2,
|
|
37
|
+
"value": []
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"type": 3,
|
|
41
|
+
"value": []
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"type": 6,
|
|
45
|
+
"value": []
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"type": 7,
|
|
49
|
+
"value": []
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"type": 8,
|
|
53
|
+
"value": []
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
"draft_materials_copied_info": [],
|
|
57
|
+
"draft_name": "",
|
|
58
|
+
"draft_new_version": "",
|
|
59
|
+
"draft_removable_storage_device": "",
|
|
60
|
+
"draft_root_path": "",
|
|
61
|
+
"draft_segment_extra_info": [],
|
|
62
|
+
"draft_type": "",
|
|
63
|
+
"tm_draft_cloud_completed": "",
|
|
64
|
+
"tm_draft_cloud_modified": 0,
|
|
65
|
+
"tm_draft_removed": 0,
|
|
66
|
+
"tm_duration": 0
|
|
67
|
+
}
|