ismdrobiul489 commited on
Commit
2f7f045
·
1 Parent(s): 5257b31

feat: Natural chat AI, TTS speed 1.3x, HF upload to text_story folder

Browse files
modules/text_story/router.py CHANGED
@@ -105,31 +105,49 @@ async def generate_text_story_video(job_id: str, request: TextStoryRequest):
105
  output_dir=temp_dir
106
  )
107
 
108
- # ============ STEP 5: Save Final Video ============
109
- update_job(job_id, "processing", 90, "Saving video...")
110
 
111
- # Create output directory
112
  videos_dir = os.path.join("videos", "text_story")
113
  os.makedirs(videos_dir, exist_ok=True)
114
 
115
  final_path = os.path.join(videos_dir, f"text_story_{job_id}.mp4")
116
  shutil.copy2(output_path, final_path)
117
 
118
- # Also save to persistent storage if available
119
- persistent_dir = "/data/videos/text_story"
120
- if os.path.exists("/data"):
121
- os.makedirs(persistent_dir, exist_ok=True)
122
- shutil.copy2(output_path, os.path.join(persistent_dir, f"text_story_{job_id}.mp4"))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
  # Cleanup temp
125
  shutil.rmtree(temp_dir, ignore_errors=True)
126
 
127
- video_url = f"/api/text-story/{job_id}/video"
 
128
  update_job(job_id, "ready", 100, "Complete!", video_url=video_url)
129
  logger.info(f"TextStory: Job {job_id} completed successfully")
130
 
131
  except Exception as e:
132
  logger.error(f"TextStory: Job {job_id} failed - {e}")
 
 
133
  update_job(job_id, "failed", 0, error=str(e))
134
 
135
  # Cleanup on failure
@@ -263,24 +281,32 @@ async def ai_generate_conversation(request: AiGenerateRequest):
263
 
264
  tone_instruction = tone_prompts.get(request.tone, tone_prompts["emotional"])
265
 
266
- system_prompt = f"""You are a viral content script writer. Generate a fake text message conversation.
267
 
268
  RULES:
269
- 1. Create exactly {request.message_count} messages
270
- 2. Alternate between Person A ({request.person_a_name}) and Person B ({request.person_b_name})
271
- 3. {tone_instruction}
272
- 4. Make it engaging and viral-worthy
273
- 5. Keep messages short (1-3 sentences each)
274
- 6. End with impact (twist or emotional ending)
 
 
 
 
 
 
 
275
 
276
  OUTPUT FORMAT (strict JSON):
277
  {{
278
  "messages": [
279
- {{"sender": "B", "text": "message from {request.person_b_name}"}},
280
- {{"sender": "A", "text": "message from {request.person_a_name}"}},
 
281
  ...
282
  ],
283
- "ending_text": "Optional ending text like 'To be continued...'"
284
  }}
285
 
286
  Only output valid JSON, nothing else."""
 
105
  output_dir=temp_dir
106
  )
107
 
108
+ # ============ STEP 5: Upload to HF Dataset ============
109
+ update_job(job_id, "processing", 90, "Uploading to cloud...")
110
 
111
+ # Create local output directory
112
  videos_dir = os.path.join("videos", "text_story")
113
  os.makedirs(videos_dir, exist_ok=True)
114
 
115
  final_path = os.path.join(videos_dir, f"text_story_{job_id}.mp4")
116
  shutil.copy2(output_path, final_path)
117
 
118
+ # Upload to HF Dataset using shared module
119
+ cloud_url = None
120
+ try:
121
+ from pathlib import Path
122
+ from modules.shared.services.hf_storage import HFStorageClient
123
+
124
+ hf_repo = os.getenv("HF_REPO", "")
125
+ hf_token = os.getenv("HF_TOKEN", "")
126
+
127
+ if hf_repo and hf_token:
128
+ hf_client = HFStorageClient(repo_id=hf_repo, token=hf_token)
129
+ cloud_url = hf_client.upload_video(
130
+ local_path=Path(final_path),
131
+ video_id=f"text_story_{job_id}",
132
+ folder="text_story" # Upload to text_story folder
133
+ )
134
+ if cloud_url:
135
+ logger.info(f"TextStory: Uploaded to HF: {cloud_url}")
136
+ except Exception as e:
137
+ logger.warning(f"TextStory: HF upload failed: {e}")
138
 
139
  # Cleanup temp
140
  shutil.rmtree(temp_dir, ignore_errors=True)
141
 
142
+ # Use cloud URL if available, otherwise local
143
+ video_url = cloud_url or f"/api/text-story/{job_id}/video"
144
  update_job(job_id, "ready", 100, "Complete!", video_url=video_url)
145
  logger.info(f"TextStory: Job {job_id} completed successfully")
146
 
147
  except Exception as e:
148
  logger.error(f"TextStory: Job {job_id} failed - {e}")
149
+ import traceback
150
+ logger.error(traceback.format_exc())
151
  update_job(job_id, "failed", 0, error=str(e))
152
 
153
  # Cleanup on failure
 
281
 
282
  tone_instruction = tone_prompts.get(request.tone, tone_prompts["emotional"])
283
 
284
+ system_prompt = f"""You are a viral content script writer. Generate a NATURAL fake text message conversation.
285
 
286
  RULES:
287
+ 1. Create approximately {request.message_count} messages (can be slightly more or less)
288
+ 2. Person A is "{request.person_a_name}" (sender: "A") - shown on right side (blue bubbles)
289
+ 3. Person B is "{request.person_b_name}" (sender: "B") - shown on left side (gray bubbles)
290
+ 4. {tone_instruction}
291
+ 5. NATURAL CHAT PATTERN - same person CAN send multiple messages in a row! Examples:
292
+ - Person sends a message, then follows up with another right after
293
+ - "Wait" ... "I need to tell you something"
294
+ - "Are you there?" ... "Hello??"
295
+ - Breaking long thoughts into 2-3 short messages
296
+ 6. Keep messages SHORT (1-2 sentences max per message)
297
+ 7. Usually B starts first (the "other" person initiates)
298
+ 8. End with impact (twist, cliffhanger, or emotional ending)
299
+ 9. Make it viral-worthy and engaging
300
 
301
  OUTPUT FORMAT (strict JSON):
302
  {{
303
  "messages": [
304
+ {{"sender": "B", "text": "Hey..."}},
305
+ {{"sender": "B", "text": "We need to talk"}},
306
+ {{"sender": "A", "text": "What's up?"}},
307
  ...
308
  ],
309
+ "ending_text": "To be continued..."
310
  }}
311
 
312
  Only output valid JSON, nothing else."""
modules/text_story/services/tts_handler.py CHANGED
@@ -52,7 +52,8 @@ class TTSHandler:
52
  payload = {
53
  "model": "kokoro",
54
  "input": text,
55
- "voice": voice
 
56
  }
57
 
58
  async with session.post(
 
52
  payload = {
53
  "model": "kokoro",
54
  "input": text,
55
+ "voice": voice,
56
+ "speed": 1.3 # Faster voice for engaging content
57
  }
58
 
59
  async with session.post(