sonika1503 commited on
Commit
da17856
·
1 Parent(s): 3104c71

Add application file

Browse files
Files changed (1) hide show
  1. app.py +332 -0
app.py ADDED
@@ -0,0 +1,332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import torch
3
+ import cv2
4
+ import instaloader
5
+ from PIL import Image
6
+ from transformers import AutoProcessor, AutoModelForCausalLM
7
+ from dotenv import load_dotenv
8
+ from typing import Optional, List, Dict, Union
9
+
10
+ import os
11
+ import torch
12
+ import cv2
13
+ import instaloader
14
+ from PIL import Image
15
+ from transformers import AutoProcessor, AutoModelForCausalLM
16
+ import streamlit as st
17
+
18
+ def download_instagram_reels(hashtag, num_reels=1, username="your_username", password="your_password"):
19
+ # Remove previous downloads if they exist
20
+ os.system("rm -rf downloaded_reels")
21
+ os.makedirs("downloaded_reels", exist_ok=True)
22
+
23
+ loader = instaloader.Instaloader(download_videos=True, download_video_thumbnails=True, download_comments=True)
24
+
25
+ try:
26
+ # Login to Instagram
27
+ loader.login(username, password)
28
+
29
+ # Get posts by hashtag
30
+ posts = instaloader.Hashtag.from_name(loader.context, hashtag).get_posts()
31
+
32
+ reel_urls = []
33
+ for post in posts:
34
+ if post.is_video:
35
+ reel_urls.append(post.url)
36
+ if len(reel_urls) >= num_reels:
37
+ break
38
+
39
+ for reel_url in reel_urls:
40
+ shortcode = reel_url.split('/')[-2]
41
+ post = instaloader.Post.from_shortcode(loader.context, shortcode)
42
+ loader.download_post(post, target='downloaded_reels')
43
+
44
+ # Find the video file name
45
+ video_files = [f for f in os.listdir('downloaded_reels') if f.endswith('.mp4')]
46
+
47
+ if not video_files:
48
+ raise ValueError("No video file found in the downloaded reels.")
49
+
50
+ return [os.path.join('downloaded_reels', video_files[i]) for i in range(0, len(video_files))], reel_urls
51
+
52
+ except Exception as e:
53
+ print(f"Error downloading reels: {e}")
54
+ return [], []
55
+
56
+
57
+ def parse_query_with_groq(
58
+ query: str,
59
+ groq_api_key: str,
60
+ seed: int = 42,
61
+ llama_model: str = "llama-3.2-11b-text-preview"
62
+ ) -> Optional[str]:
63
+ """
64
+ Enhanced sentiment analysis with Groq API
65
+
66
+ Args:
67
+ query: Input text for sentiment analysis
68
+ groq_api_key: API key for Groq
69
+ seed: Random seed for reproducibility
70
+ llama_model: Model identifier
71
+ """
72
+ url = "https://api.groq.com/openai/v1/chat/completions"
73
+
74
+ # Normalize query
75
+ #query = ' '.join(query.lower().split())
76
+
77
+ headers = {
78
+ "Authorization": f"Bearer {groq_api_key}",
79
+ "Content-Type": "application/json"
80
+ }
81
+
82
+ system_message = """You are a precise sentiment analysis assistant.
83
+ Analyze the user_prompt and provide a JSON-formatted list of objects, where each object contains:
84
+ - sentiment_score: a float between -1 (very negative) and 1 (very positive)
85
+ - frame_index: the corresponding frame index
86
+
87
+ Strictly follow this JSON format:
88
+ [
89
+ {"sentiment_score": <float>, "frame_index": <int>},
90
+ ...
91
+ ]
92
+ """
93
+
94
+ payload = {
95
+ "model": llama_model,
96
+ "response_format": {
97
+ "type": "json_schema",
98
+ "json_schema": {
99
+ "type": "array",
100
+ "items": {
101
+ "type": "object",
102
+ "properties": {
103
+ "sentiment_score": {"type": "number"},
104
+ "frame_index": {"type": "integer"}
105
+ },
106
+ "required": ["sentiment_score", "frame_index"]
107
+ }
108
+ }
109
+ },
110
+ "messages": [
111
+ {"role": "system", "content": system_message},
112
+ {"role": "user", "content": query}
113
+ ],
114
+ "temperature": 0,
115
+ "max_tokens": 300,
116
+ "seed": seed
117
+ }
118
+
119
+ try:
120
+ response = requests.post(url, headers=headers, json=payload, timeout=30)
121
+ response.raise_for_status()
122
+ print(f"DEBUG : Raw Response is {response}")
123
+ parsed_response = response.json()['choices'][0]['message']['content']
124
+ print(f"DEBUG : Raw Response is {parsed_response}")
125
+ return parsed_response
126
+ except Exception as e:
127
+ print(f"Sentiment Analysis Error: {e}")
128
+ return None
129
+
130
+ def extract_frames(video_path, output_folder, fps=1):
131
+ # Create the output folder if it doesn't exist
132
+ os.makedirs(output_folder, exist_ok=True)
133
+
134
+ # Open the video file
135
+ cap = cv2.VideoCapture(video_path)
136
+
137
+ # Check if the video was opened successfully
138
+ if not cap.isOpened():
139
+ print(f"Error: Could not open video file {video_path}")
140
+ return
141
+
142
+ # Get the frames per second of the video
143
+ video_fps = cap.get(cv2.CAP_PROP_FPS)
144
+
145
+ # Calculate the interval between frames to capture based on desired fps
146
+ frame_interval = int(video_fps / fps)
147
+
148
+ count = 0
149
+ frame_count = 0
150
+ time_stamps = []
151
+
152
+ while True:
153
+ # Read a frame from the video
154
+ ret, frame = cap.read()
155
+
156
+ # Break the loop if there are no more frames
157
+ if not ret:
158
+ break
159
+
160
+ # Save every 'frame_interval' frame
161
+ if count % frame_interval == 0:
162
+ frame_filename = os.path.join(output_folder, f"image{frame_count}.jpg")
163
+ cv2.imwrite(frame_filename, frame)
164
+ print(f"Extracted: {frame_filename}")
165
+ frame_count += 1
166
+ time_stamps.append(count/video_fps)
167
+
168
+ count += 1
169
+
170
+ # Release the video capture object
171
+ cap.release()
172
+ print("Frame extraction completed.")
173
+ return frame_count, time_stamps
174
+
175
+ def download_instagram_reel_old(reel_url, username="[email protected]", password="instagram@123"):
176
+ # Remove previous downloads if they exist
177
+ os.system("rm -rf downloaded_reels")
178
+ os.makedirs("downloaded_reels", exist_ok=True)
179
+
180
+ # Create an instance of Instaloader
181
+ print(f"Creating instance of instaloader")
182
+ loader = instaloader.Instaloader(
183
+ download_videos=True,
184
+ download_video_thumbnails=True,
185
+ download_comments=True
186
+ )
187
+
188
+ try:
189
+ # Login to Instagram
190
+ loader.login(username, password)
191
+
192
+ # Extract the shortcode from the URL
193
+ shortcode = reel_url.split('/')[-2]
194
+
195
+ # Download the reel using the shortcode
196
+ post = instaloader.Post.from_shortcode(loader.context, shortcode)
197
+ loader.download_post(post, target='downloaded_reels')
198
+
199
+ # Extract comments
200
+ comments = post.get_comments()
201
+
202
+ print(f"Comments are : {comments}")
203
+ for comment in comments:
204
+ print(f"{comment.owner.username}: {comment.text}")
205
+
206
+ # Find the video file name
207
+ video_files = [f for f in os.listdir('downloaded_reels') if f.endswith('.mp4')]
208
+
209
+ if not video_files:
210
+ raise ValueError("No video file found in the downloaded reels.")
211
+
212
+ return os.path.join('downloaded_reels', video_files[0])
213
+
214
+ except Exception as e:
215
+ print(f"Error downloading reel: {e}")
216
+ return None
217
+
218
+ def analyze_frames_with_florence(image_folder, timestamps):
219
+ # Set up device and dtype
220
+ device = "cuda:0" if torch.cuda.is_available() else "cpu"
221
+ torch_dtype = torch.float16 if torch.cuda.is_available() else torch.float32
222
+
223
+ # Load Florence-2 model
224
+ model = AutoModelForCausalLM.from_pretrained(
225
+ "microsoft/Florence-2-large",
226
+ torch_dtype=torch_dtype,
227
+ trust_remote_code=True
228
+ ).to(device)
229
+
230
+ processor = AutoProcessor.from_pretrained(
231
+ "microsoft/Florence-2-large",
232
+ trust_remote_code=True
233
+ )
234
+
235
+ prompt = "<DETAILED_CAPTION>"
236
+
237
+ # Collect frame analysis results
238
+ frame_analyses = []
239
+
240
+ # Iterate through all images in the specified folder
241
+ N = len(os.listdir(image_folder)) # Count number of images in the folder
242
+
243
+ for i in range(N):
244
+ image_path = os.path.join(image_folder, f"image{i}.jpg")
245
+ image = Image.open(image_path)
246
+
247
+ inputs = processor(text=prompt, images=image, return_tensors="pt").to(device)
248
+
249
+ generated_ids = model.generate(
250
+ input_ids=inputs["input_ids"],
251
+ pixel_values=inputs["pixel_values"],
252
+ max_new_tokens=1024,
253
+ num_beams=3,
254
+ do_sample=False
255
+ )
256
+
257
+ generated_text = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
258
+
259
+ parsed_answer = processor.post_process_generation(
260
+ generated_text,
261
+ task=prompt,
262
+ image_size=(image.width, image.height)
263
+ )
264
+
265
+ frame_analyses.append({
266
+ 'Frame_Index': i,
267
+ 'Caption': parsed_answer
268
+ })
269
+ print(f"Frame {i}, TimeStamp {timestamps[i]} sec : {parsed_answer}")
270
+
271
+ return frame_analyses
272
+
273
+ def main():
274
+ # Specify the URL of the reel
275
+ reel_url = "https://www.instagram.com/purnagummies/reel/C7RRVstqtwY/"
276
+
277
+ fps = 0.5
278
+
279
+ # Download the reel
280
+
281
+ st.title("BrandScan")
282
+
283
+ hashtag = st.text_input("Enter the hashtag (without #):", "purnagummies")
284
+
285
+ if st.button("Download Reels"):
286
+ if hashtag:
287
+ with st.spinner("Downloading reels..."):
288
+ video_paths, reel_urls = download_instagram_reels(hashtag)
289
+ if reel_urls:
290
+ st.success(f"Downloaded {len(video_paths)} reels:")
291
+ for url in reel_urls:
292
+ st.write(url)
293
+ else:
294
+ st.error("No reels found or an error occurred.")
295
+ else:
296
+ st.error("Please enter a valid hashtag.")
297
+
298
+ #video_path = download_instagram_reel(reel_urls[0])
299
+
300
+ if len(video_paths) == 0:
301
+ print("Failed to download the reel.")
302
+ return
303
+
304
+ #video_path
305
+ video_path = video_paths[0]
306
+
307
+ # Collect images from the video
308
+ image_folder = "downloaded_reels/images"
309
+ os.makedirs(image_folder, exist_ok=True)
310
+
311
+ # Extract frames from the video
312
+ N, timestamps = extract_frames(video_path, image_folder, fps)
313
+
314
+ print(f"Analyzing video {video_path} with {N} frames extracted at {fps} frames per second")
315
+ # Analyze frames with Florence-2
316
+ frame_analyses = analyze_frames_with_florence(image_folder, timestamps)
317
+
318
+ # Optional: You can further process or store the frame_analyses as needed
319
+ print("Frame analysis completed.")
320
+
321
+ frame_analyses_str = "<Frame_Index>; <Description>\n"
322
+ for item in frame_analyses:
323
+ frame_analyses_str += item['Frame_Index'] + "; " + item['Caption'] + "\n"
324
+
325
+ print(frame_analyses_str)
326
+ sentiment_analysis = parse_query_with_groq(frame_analyses_str, os.getenv("GROQ_API_KEY"))
327
+
328
+ print("Sentiment Analysis on the video:")
329
+ print(sentiment_analysis)
330
+
331
+ if __name__ == "__main__":
332
+ main()