sreepathi-ravikumar commited on
Commit
8e3c369
·
verified ·
1 Parent(s): 96f419b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -101
app.py CHANGED
@@ -1,151 +1,108 @@
1
- import os
2
- import tempfile
3
- import traceback
4
  from flask import Flask, request, jsonify, send_file
5
- from PIL import Image
6
- from moviepy.editor import *
7
- from gtts import gTTS
8
- from mutagen.mp3 import MP3
9
- import pytesseract
10
- import numpy as np
11
- from video import create_text_image
12
  import uuid
13
  import glob
 
 
 
 
14
 
15
  app = Flask(__name__)
16
 
17
- def video_func(id, lines):
18
- try:
19
- # Temp files
20
- temp_audio = tempfile.NamedTemporaryFile(delete=False, suffix='.mp3')
21
- temp_audio.close()
22
-
23
- # Text-to-Speech
24
- tts = gTTS(text=lines[id], lang='ta', slow=False)
25
- tts.save(temp_audio.name)
26
-
27
- audio = MP3(temp_audio.name)
28
- duration = audio.info.length
29
-
30
- image_path = f"/tmp/images/slide{id}.png"
31
- video_duration = duration
32
- highlight_color = (255, 255, 0)
33
- highlight_opacity = 0.5
34
-
35
- # OCR: Extract words
36
- img = Image.open(image_path)
37
- data = pytesseract.image_to_data(img, output_type=pytesseract.Output.DICT)
38
-
39
- words = []
40
- for i in range(len(data['text'])):
41
- word = data['text'][i].strip()
42
- if word and int(data['conf'][i]) > 60:
43
- x, y, w, h = data['left'][i], data['top'][i], data['width'][i], data['height'][i]
44
- words.append({'text': word, 'box': (x, y, w, h)})
45
-
46
- image_clip = ImageClip(image_path).set_duration(video_duration)
47
-
48
- # Highlight effect
49
- n_words = len(words)
50
- highlight_duration = video_duration / max(n_words, 1)
51
- highlight_clips = []
52
-
53
- for i, word in enumerate(words):
54
- x, y, w, h = word['box']
55
- start = i * highlight_duration
56
- end = start + highlight_duration
57
-
58
- rect = ColorClip(size=(w, h), color=highlight_color)
59
- rect = rect.set_opacity(highlight_opacity).set_position((x, y)).set_start(start).set_end(end)
60
- highlight_clips.append(rect)
61
-
62
- final_clip = CompositeVideoClip([image_clip] + highlight_clips)
63
- audio = AudioFileClip(temp_audio.name)
64
- final_clip = final_clip.set_audio(audio)
65
- final_clip.write_videofile(f"/tmp/clip{id}.mp4", fps=24)
66
-
67
- except Exception as e:
68
- print(f"Error in video_func for ID {id}: {e}")
69
- traceback.print_exc()
70
-
71
 
72
  @app.route("/generate", methods=["POST"])
73
  def generate_video():
74
  try:
75
  data = request.get_json()
76
  prompt = data.get("duration", '').strip()
77
- prompts = prompt.replace("**", "")
78
-
79
- if not prompts:
80
- return jsonify({"error": "prompts must not be empty"}), 400
81
-
82
- raw_lines = prompts.splitlines()
 
 
83
  lines = []
 
84
  i = 0
85
-
86
  while i < len(raw_lines):
87
  line = raw_lines[i].strip()
88
-
89
- if line.startswith("#") and (line.endswith('?') or line.endswith(':')):
90
- block = line
 
91
  i += 1
 
 
92
  paragraph_lines = []
93
-
94
  while i < len(raw_lines):
95
  next_line = raw_lines[i].strip()
96
- if next_line.startswith("#") and (next_line.endswith('?') or next_line.endswith(':')):
 
 
97
  break
 
98
  paragraph_lines.append(next_line)
99
  i += 1
 
 
100
  if len(paragraph_lines) >= 5:
101
  break
102
-
 
103
  if paragraph_lines:
104
  block += '\n' + '\n'.join(paragraph_lines)
 
105
  lines.append(block)
 
106
  else:
 
107
  block_lines = []
108
  count = 0
 
109
  while i < len(raw_lines) and count < 5:
110
  next_line = raw_lines[i].strip()
111
- if next_line.startswith("#") and (next_line.endswith('?') or next_line.endswith(':')):
 
 
112
  break
 
113
  block_lines.append(next_line)
114
  i += 1
115
  count += 1
 
116
  if block_lines:
117
  lines.append('\n'.join(block_lines))
118
-
119
- # Slide image creation
120
- image_olst = []
 
121
  for id in range(len(lines)):
122
- create_text_image(lines[id], id, image_olst)
123
-
124
- for i in range(len(lines)):
125
- video_func(i, lines)
126
-
127
- clips = [VideoFileClip(f"/tmp/clip{id}.mp4") for id in range(len(lines))]
128
- final_video = concatenate_videoclips(clips)
129
- output_path = "/tmp/final_output.mp4"
130
- final_video.write_videofile(output_path, fps=24)
131
-
132
- # Clean up
133
- for img in image_olst:
134
  os.remove(img)
135
 
136
- return send_file(output_path, mimetype='video/mp4')
137
 
138
  except Exception as e:
139
  traceback.print_exc()
140
  return jsonify({"error": str(e)}), 500
141
 
142
-
143
- @app.route("/")
144
- def home():
145
- return "Flask Video Generator is Running"
146
-
147
-
148
  if __name__ == "__main__":
149
  app.run(host="0.0.0.0", port=7860)
150
 
151
-
 
1
+
 
 
2
  from flask import Flask, request, jsonify, send_file
3
+ from moviepy.editor import ColorClip,ImageClip, concatenate_videoclips
4
+ import traceback
 
 
 
 
 
5
  import uuid
6
  import glob
7
+ import os
8
+ import asyncio
9
+ from image_fetcher import main
10
+ from video import create_text_image
11
 
12
  app = Flask(__name__)
13
 
14
+ @app.route("/")
15
+ def home():
16
+ return "Flask Video Generator is Running"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
  @app.route("/generate", methods=["POST"])
19
  def generate_video():
20
  try:
21
  data = request.get_json()
22
  prompt = data.get("duration", '').strip()
23
+ prompts=prompt.replace("**","")
24
+ print(prompts)
25
+ if prompts == '':
26
+ return jsonify({"error": "prompts be must"}), 400
27
+ image_folder = "/tmp/images"
28
+ #line=prompts.splitlines()
29
+ #asyncio.run(main(line))
30
+ raw_lines = prompts.splitlines(keepends=False)
31
  lines = []
32
+
33
  i = 0
 
34
  while i < len(raw_lines):
35
  line = raw_lines[i].strip()
36
+
37
+ # Check if current line is a heading
38
+ if line.strip().startswith("#") and (line.endswith('?') or line.endswith(':')):
39
+ block = line # Start block with heading
40
  i += 1
41
+
42
+ # Accumulate body lines until next heading or 5+ lines
43
  paragraph_lines = []
 
44
  while i < len(raw_lines):
45
  next_line = raw_lines[i].strip()
46
+
47
+ # Stop if next line is a heading
48
+ if next_line.strip().startswith("#") and (next_line.endswith('?') or next_line.endswith(':')):
49
  break
50
+
51
  paragraph_lines.append(next_line)
52
  i += 1
53
+
54
+ # If we've gathered enough lines for a slide, break to next
55
  if len(paragraph_lines) >= 5:
56
  break
57
+
58
+ # Combine heading + paragraph
59
  if paragraph_lines:
60
  block += '\n' + '\n'.join(paragraph_lines)
61
+
62
  lines.append(block)
63
+
64
  else:
65
+ # Group normal lines (not part of any heading)
66
  block_lines = []
67
  count = 0
68
+
69
  while i < len(raw_lines) and count < 5:
70
  next_line = raw_lines[i].strip()
71
+
72
+ # If this is a heading, break to handle it separately
73
+ if next_line.strip().startswith("#") and (next_line.endswith('?') or next_line.endswith(':')):
74
  break
75
+
76
  block_lines.append(next_line)
77
  i += 1
78
  count += 1
79
+
80
  if block_lines:
81
  lines.append('\n'.join(block_lines))
82
+
83
+ # Print or use lines as slides
84
+
85
+ image_olst=[]
86
  for id in range(len(lines)):
87
+ create_text_image(lines[id],id,image_olst)
88
+ image_files = sorted(glob.glob(os.path.join(image_folder, "*.png")))
89
+ if not image_files:
90
+ raise ValueError("No images found in folder!")
91
+
92
+ clips = [ImageClip(m).set_duration(5) for m in image_files]
93
+ video = concatenate_videoclips(clips, method="compose")
94
+ video_path = f"/tmp/video_{uuid.uuid4().hex}.mp4"
95
+ video.write_videofile(video_path, fps=24)
96
+ for img in image_files:
 
 
97
  os.remove(img)
98
 
99
+ return send_file(video_path, mimetype='video/mp4')
100
 
101
  except Exception as e:
102
  traceback.print_exc()
103
  return jsonify({"error": str(e)}), 500
104
 
 
 
 
 
 
 
105
  if __name__ == "__main__":
106
  app.run(host="0.0.0.0", port=7860)
107
 
108
+ # Example call (remove or change in your actual app)