@danhachuel/thunderbolt 0.5.100 → 0.6.1
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/app/main.py +41 -0
- package/hermes_ui/domain.py +26 -1
- package/package.json +1 -1
package/app/main.py
CHANGED
|
@@ -1311,6 +1311,45 @@ def render_channel_videos(channel: dict) -> None:
|
|
|
1311
1311
|
render_channel_video_editor(video, channel_id)
|
|
1312
1312
|
|
|
1313
1313
|
|
|
1314
|
+
def render_channel_audio_subtitle_defaults(channel: dict) -> None:
|
|
1315
|
+
"""Render and persist the audio/subtitle defaults used by channel automations."""
|
|
1316
|
+
channel_id = str(channel.get("id") or "")
|
|
1317
|
+
subtitle_font = str(channel.get("default_subtitle_font") or SUBTITLE_FONT_OPTIONS[0])
|
|
1318
|
+
subtitle_position = str(channel.get("default_subtitle_position") or SUBTITLE_POSITION_OPTIONS[0])
|
|
1319
|
+
music_source = str(channel.get("default_background_music_source") or "Sem música")
|
|
1320
|
+
music_volume = str(channel.get("default_background_music_volume") or "20%")
|
|
1321
|
+
with st.expander("Configurações de legendas", expanded=False):
|
|
1322
|
+
subtitle_cols = st.columns(2)
|
|
1323
|
+
with subtitle_cols[0]:
|
|
1324
|
+
enable_subtitles = st.checkbox("Enable Subtitles", value=bool(channel.get("default_enable_subtitles", True)), key=f"channel_default_subtitles_{channel_id}")
|
|
1325
|
+
selected_font = st.selectbox("Font", SUBTITLE_FONT_OPTIONS, index=SUBTITLE_FONT_OPTIONS.index(subtitle_font) if subtitle_font in SUBTITLE_FONT_OPTIONS else 0, key=f"channel_default_subtitle_font_{channel_id}")
|
|
1326
|
+
selected_position = st.selectbox("Position", SUBTITLE_POSITION_OPTIONS, index=SUBTITLE_POSITION_OPTIONS.index(subtitle_position) if subtitle_position in SUBTITLE_POSITION_OPTIONS else 0, key=f"channel_default_subtitle_position_{channel_id}")
|
|
1327
|
+
subtitle_color = st.color_picker("Color", str(channel.get("default_subtitle_color") or "#FFFFFF"), key=f"channel_default_subtitle_color_{channel_id}")
|
|
1328
|
+
subtitle_background = st.checkbox("Background", value=bool(channel.get("default_subtitle_background", True)), key=f"channel_default_subtitle_background_{channel_id}")
|
|
1329
|
+
subtitle_background_color = st.color_picker("Background Color", str(channel.get("default_subtitle_background_color") or "#000000"), key=f"channel_default_subtitle_background_color_{channel_id}")
|
|
1330
|
+
subtitle_rounded_background = st.checkbox("Rounded Background", value=bool(channel.get("default_subtitle_rounded_background", False)), key=f"channel_default_subtitle_rounded_background_{channel_id}")
|
|
1331
|
+
with subtitle_cols[1]:
|
|
1332
|
+
subtitle_font_size = st.slider("Font Size", min_value=12, max_value=96, value=int(channel.get("default_subtitle_font_size") or 60), key=f"channel_default_subtitle_font_size_{channel_id}")
|
|
1333
|
+
subtitle_outline = st.color_picker("Outline", str(channel.get("default_subtitle_outline") or "#000000"), key=f"channel_default_subtitle_outline_{channel_id}")
|
|
1334
|
+
subtitle_outline_width = st.slider("Outline Width", min_value=0.0, max_value=5.0, value=float(channel.get("default_subtitle_outline_width") or 1.5), step=0.25, key=f"channel_default_subtitle_outline_width_{channel_id}")
|
|
1335
|
+
if st.button("Guardar configurações de legendas", type="primary", key=f"save_channel_subtitle_defaults_{channel_id}", use_container_width=True):
|
|
1336
|
+
update_channel(channel_id, {
|
|
1337
|
+
"default_enable_subtitles": bool(enable_subtitles), "default_subtitle_font": selected_font, "default_subtitle_position": selected_position,
|
|
1338
|
+
"default_subtitle_color": subtitle_color, "default_subtitle_background": bool(subtitle_background), "default_subtitle_background_color": subtitle_background_color,
|
|
1339
|
+
"default_subtitle_rounded_background": bool(subtitle_rounded_background), "default_subtitle_font_size": int(subtitle_font_size),
|
|
1340
|
+
"default_subtitle_outline": subtitle_outline, "default_subtitle_outline_width": float(subtitle_outline_width),
|
|
1341
|
+
})
|
|
1342
|
+
st.success("Default de legendas guardado para este canal.")
|
|
1343
|
+
st.rerun()
|
|
1344
|
+
with st.expander("Configurações de Audio", expanded=False):
|
|
1345
|
+
selected_music_source = st.selectbox("Fonte da música de fundo", BACKGROUND_MUSIC_SOURCE_OPTIONS, index=BACKGROUND_MUSIC_SOURCE_OPTIONS.index(music_source) if music_source in BACKGROUND_MUSIC_SOURCE_OPTIONS else BACKGROUND_MUSIC_SOURCE_OPTIONS.index("Sem música"), key=f"channel_default_music_source_{channel_id}")
|
|
1346
|
+
selected_music_volume = st.selectbox("Volume da música de fundo", BACKGROUND_MUSIC_VOLUME_OPTIONS, index=BACKGROUND_MUSIC_VOLUME_OPTIONS.index(music_volume) if music_volume in BACKGROUND_MUSIC_VOLUME_OPTIONS else 2, key=f"channel_default_music_volume_{channel_id}")
|
|
1347
|
+
if st.button("Guardar configurações de Audio", type="primary", key=f"save_channel_audio_defaults_{channel_id}", use_container_width=True):
|
|
1348
|
+
update_channel(channel_id, {"default_background_music_source": selected_music_source, "default_background_music_volume": selected_music_volume})
|
|
1349
|
+
st.success("Default de Audio guardado para este canal.")
|
|
1350
|
+
st.rerun()
|
|
1351
|
+
|
|
1352
|
+
|
|
1314
1353
|
def render_channel_edit_form(channel: dict, youtube_account_ids: list[str], youtube_account_labels: dict[str, str], youtube_accounts_by_id: dict[str, dict[str, Any]]) -> None:
|
|
1315
1354
|
channel_id = str(channel["id"])
|
|
1316
1355
|
blueprint_ids, blueprint_labels, current_blueprint, voice_options, current_voice = channel_default_options(channel)
|
|
@@ -2341,6 +2380,7 @@ def render_tiktok_channels():
|
|
|
2341
2380
|
update_channel(channel_id, {"name": edit_name.strip(), "url": edit_url.strip(), "handle": edit_handle.strip(), "language": edit_language, "niche": edit_niche.strip(), "reference_channels": [edit_niche.strip()] if edit_niche.strip() else [], "default_voice": edit_voice, "voice": edit_voice, "style_wide": channel_video_source_storage(edit_source), "video_aspect_ratio": edit_aspect, "automation_on": edit_automation, "automation_time": edit_time.strip(), "description": edit_description.strip(), "platform": "tiktok"})
|
|
2342
2381
|
st.session_state.pop(f"tiktok_edit_{channel_id}", None)
|
|
2343
2382
|
st.rerun()
|
|
2383
|
+
render_channel_audio_subtitle_defaults(channel)
|
|
2344
2384
|
with st.expander("Últimos 10 vídeos publicados", expanded=False):
|
|
2345
2385
|
recent_videos = channel_videos_for(channel, limit=10)
|
|
2346
2386
|
if not recent_videos:
|
|
@@ -3032,6 +3072,7 @@ def render_channels():
|
|
|
3032
3072
|
st.success("Conta Google e DELEGATED_SESSION_ID individual do canal guardados.")
|
|
3033
3073
|
st.rerun()
|
|
3034
3074
|
|
|
3075
|
+
render_channel_audio_subtitle_defaults(channel)
|
|
3035
3076
|
render_channel_videos(channel)
|
|
3036
3077
|
|
|
3037
3078
|
|
package/hermes_ui/domain.py
CHANGED
|
@@ -53,6 +53,18 @@ def create_channel(name: str, url: str = "", metadata: dict[str, Any] | None = N
|
|
|
53
53
|
"style_wide": "pexels",
|
|
54
54
|
"voice": "",
|
|
55
55
|
"default_voice": "",
|
|
56
|
+
"default_enable_subtitles": True,
|
|
57
|
+
"default_subtitle_font": "MicrosoftYaHeiBold.ttc",
|
|
58
|
+
"default_subtitle_position": "Bottom (Recommended)",
|
|
59
|
+
"default_subtitle_color": "#FFFFFF",
|
|
60
|
+
"default_subtitle_background": True,
|
|
61
|
+
"default_subtitle_background_color": "#000000",
|
|
62
|
+
"default_subtitle_rounded_background": False,
|
|
63
|
+
"default_subtitle_font_size": 60,
|
|
64
|
+
"default_subtitle_outline": "#000000",
|
|
65
|
+
"default_subtitle_outline_width": 1.5,
|
|
66
|
+
"default_background_music_source": "Sem música",
|
|
67
|
+
"default_background_music_volume": "20%",
|
|
56
68
|
"delegated_session_id": "",
|
|
57
69
|
"automation_on": False,
|
|
58
70
|
"automation_time": "00:00",
|
|
@@ -164,6 +176,19 @@ def create_tasks_for_batch(batch: dict[str, Any]) -> list[dict[str, Any]]:
|
|
|
164
176
|
if thumbnail_path:
|
|
165
177
|
artifacts.setdefault("thumbnail", thumbnail_path)
|
|
166
178
|
initial_stage = "topic" if pending_creative else "script"
|
|
179
|
+
channel_generation_defaults = {
|
|
180
|
+
key.removeprefix("default_"): channel[key]
|
|
181
|
+
for key in (
|
|
182
|
+
"default_enable_subtitles", "default_subtitle_font", "default_subtitle_position", "default_subtitle_color",
|
|
183
|
+
"default_subtitle_background", "default_subtitle_background_color", "default_subtitle_rounded_background",
|
|
184
|
+
"default_subtitle_font_size", "default_subtitle_outline", "default_subtitle_outline_width",
|
|
185
|
+
"default_background_music_source", "default_background_music_volume",
|
|
186
|
+
)
|
|
187
|
+
if key in channel
|
|
188
|
+
}
|
|
189
|
+
configured_generation_settings = options.get("generation_settings") if isinstance(options.get("generation_settings"), dict) else {}
|
|
190
|
+
payload_generation_settings = payload.get("generation_settings") if isinstance(payload.get("generation_settings"), dict) else {}
|
|
191
|
+
generation_settings = {**channel_generation_defaults, **configured_generation_settings, **payload_generation_settings}
|
|
167
192
|
task = {
|
|
168
193
|
"id": make_id("video"),
|
|
169
194
|
"batch_id": batch["id"],
|
|
@@ -183,7 +208,7 @@ def create_tasks_for_batch(batch: dict[str, Any]) -> list[dict[str, Any]]:
|
|
|
183
208
|
"music_path": payload.get("music_path", options.get("music_path", "")),
|
|
184
209
|
"music_source": payload.get("music_source", options.get("music_source", "")),
|
|
185
210
|
"background_mode": payload.get("background_mode", options.get("background_mode", "stock")),
|
|
186
|
-
"generation_settings":
|
|
211
|
+
"generation_settings": generation_settings,
|
|
187
212
|
"blueprint_id": payload.get("blueprint_id") or channel.get("default_blueprint_id") or channel.get("blueprint_id", ""),
|
|
188
213
|
"blueprint_name": payload.get("blueprint_name", ""),
|
|
189
214
|
"thumbnail_blueprint_id": payload.get("thumbnail_blueprint_id") or channel.get("default_thumbnail_blueprint_id") or channel.get("thumbnail_blueprint_id") or GENERIC_THUMBNAIL_BLUEPRINT_ID,
|
package/package.json
CHANGED