nazib61 commited on
Commit
f4082e2
Β·
verified Β·
1 Parent(s): efb68a6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -53
app.py CHANGED
@@ -4,14 +4,11 @@ import os
4
  import uuid
5
  import json
6
 
7
- def initialize_env():
8
- if not os.path.exists("node_modules"):
9
- subprocess.run(["npm", "install"], check=True)
10
-
11
- initialize_env()
12
 
13
  def get_video_dimensions(url):
14
- """Checks video dimensions using ffprobe"""
15
  try:
16
  cmd = [
17
  "ffprobe", "-v", "error", "-select_streams", "v:0",
@@ -19,9 +16,7 @@ def get_video_dimensions(url):
19
  ]
20
  result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
21
  data = json.loads(result.stdout)
22
- width = data['streams'][0]['width']
23
- height = data['streams'][0]['height']
24
- return width, height
25
  except:
26
  return 0, 0
27
 
@@ -29,81 +24,85 @@ def process_video(query, orientation, start_time, end_time, progress=gr.Progress
29
  if not query:
30
  return None, "⚠️ Please enter a keyword."
31
 
32
- progress(0, desc="πŸ” Searching Pinterest...")
33
  search_query = query if "video" in query.lower() else f"{query} video"
34
 
35
  try:
36
- # 1. Run Node Scraper (collects many links)
37
  result = subprocess.run(
38
  ["node", "scraper.js", search_query],
39
- capture_output=True, text=True, timeout=180 # Increased timeout for deep search
40
  )
41
-
42
  all_urls = [line.strip() for line in result.stdout.split('\n') if line.strip().startswith("http")]
43
 
44
  if not all_urls:
45
- return None, "❌ No videos found in the search results."
46
 
47
- # 2. Loop through every found URL until the orientation matches
48
  selected_url = None
49
- total = len(all_urls)
50
-
51
  for i, url in enumerate(all_urls):
52
- progress((i+1)/total, desc=f"Checking video {i+1}/{total} for {orientation}...")
53
-
54
  if orientation == "Any":
55
- selected_url = url
56
- break
57
-
58
  w, h = get_video_dimensions(url)
59
  if orientation == "Portrait" and h > w:
60
- selected_url = url
61
- break
62
  if orientation == "Landscape" and w > h:
63
- selected_url = url
64
- break
65
- # If no match, the loop continues to the next URL automatically
66
 
67
  if not selected_url:
68
- return None, f"❌ Searched {total} videos, but none were {orientation}. Pinterest is mostly Portrait content."
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
- # 3. Trim and return the video
71
- progress(0.9, desc="βœ‚οΈ Trimming video...")
72
- output_filename = f"final_{uuid.uuid4().hex[:8]}.mp4"
73
  ffmpeg_cmd = [
74
- "ffmpeg", "-ss", str(start_time), "-to", str(end_time),
75
- "-i", selected_url, "-c:v", "libx264", "-c:a", "aac", "-y", output_filename
 
 
 
 
 
 
 
 
76
  ]
77
-
78
- if end_time <= 0:
79
- ffmpeg_cmd.pop(3); ffmpeg_cmd.pop(3)
80
 
81
  subprocess.run(ffmpeg_cmd, check=True)
82
- return output_filename, f"βœ… Success! Found {orientation} video after checking {i+1} results."
83
 
84
  except Exception as e:
85
- return None, f"❌ System Error: {str(e)}"
86
 
87
- # --- UI Layout ---
88
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
89
- gr.Markdown("# πŸ“Œ Pinterest Deep Search & Filter")
90
- gr.Markdown("This app will scroll and search deep into Pinterest until it finds the orientation you want.")
91
 
92
  with gr.Row():
93
  with gr.Column():
94
- query_input = gr.Textbox(label="Topic", placeholder="e.g. Ocean Nature")
95
- filter_input = gr.Dropdown(choices=["Any", "Portrait", "Landscape"], value="Landscape", label="Required Orientation")
96
-
97
  with gr.Row():
98
- start_input = gr.Number(label="Start (sec)", value=0)
99
- end_input = gr.Number(label="End (sec, 0=full)", value=5)
100
-
101
- btn = gr.Button("πŸš€ Deep Search & Process", variant="primary")
102
 
103
  with gr.Column():
104
- video_output = gr.Video(label="Trimmed Result")
105
- status_output = gr.Textbox(label="Search Progress / Status")
106
 
107
- btn.click(process_video, [query_input, filter_input, start_input, end_input], [video_output, status_output])
108
 
109
- demo.launch()
 
 
4
  import uuid
5
  import json
6
 
7
+ # Startup: Install Node modules if missing
8
+ if not os.path.exists("node_modules"):
9
+ subprocess.run(["npm", "install"], check=True)
 
 
10
 
11
  def get_video_dimensions(url):
 
12
  try:
13
  cmd = [
14
  "ffprobe", "-v", "error", "-select_streams", "v:0",
 
16
  ]
17
  result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
18
  data = json.loads(result.stdout)
19
+ return data['streams'][0]['width'], data['streams'][0]['height']
 
 
20
  except:
21
  return 0, 0
22
 
 
24
  if not query:
25
  return None, "⚠️ Please enter a keyword."
26
 
27
+ progress(0, desc="πŸ” Searching deep on Pinterest...")
28
  search_query = query if "video" in query.lower() else f"{query} video"
29
 
30
  try:
31
+ # 1. Run Node Scraper
32
  result = subprocess.run(
33
  ["node", "scraper.js", search_query],
34
+ capture_output=True, text=True, timeout=240
35
  )
 
36
  all_urls = [line.strip() for line in result.stdout.split('\n') if line.strip().startswith("http")]
37
 
38
  if not all_urls:
39
+ return None, "❌ No videos found in search."
40
 
41
+ # 2. Filter for match
42
  selected_url = None
 
 
43
  for i, url in enumerate(all_urls):
44
+ progress((i+1)/len(all_urls), desc=f"Checking video {i+1} for {orientation}...")
 
45
  if orientation == "Any":
46
+ selected_url = url; break
 
 
47
  w, h = get_video_dimensions(url)
48
  if orientation == "Portrait" and h > w:
49
+ selected_url = url; break
 
50
  if orientation == "Landscape" and w > h:
51
+ selected_url = url; break
 
 
52
 
53
  if not selected_url:
54
+ return None, f"❌ Checked {len(all_urls)} videos, but no {orientation} found."
55
+
56
+ # 3. ULTRA 4K ENHANCEMENT & 9:16 CROP
57
+ # We use 2160:3840 for 4K Portrait 9:16
58
+ progress(0.8, desc="πŸ’Ž Upscaling to 4K & Sharpening... (Takes time)")
59
+ output_filename = f"enhanced_4k_{uuid.uuid4().hex[:5]}.mp4"
60
+
61
+ # Filter: Scale to fit 4K, Crop to 9:16, Sharpening (Unsharp mask)
62
+ filter_complex = (
63
+ "scale=2160:3840:force_original_aspect_ratio=increase," # Upscale
64
+ "crop=2160:3840," # Force 9:16
65
+ "unsharp=5:5:1.5:5:5:0.0" # Sharpening
66
+ )
67
 
 
 
 
68
  ffmpeg_cmd = [
69
+ "ffmpeg",
70
+ "-ss", str(start_time),
71
+ "-to", str(end_time) if end_time > 0 else "999",
72
+ "-i", selected_url,
73
+ "-vf", filter_complex,
74
+ "-c:v", "libx264",
75
+ "-preset", "medium", # Balanced speed/quality for HF CPU
76
+ "-crf", "18", # High quality bitrate
77
+ "-c:a", "aac",
78
+ "-y", output_filename
79
  ]
 
 
 
80
 
81
  subprocess.run(ffmpeg_cmd, check=True)
82
+ return output_filename, f"βœ… 4K Sharpened & Cropped (Checked {i+1} pins)"
83
 
84
  except Exception as e:
85
+ return None, f"❌ Error: {str(e)}"
86
 
87
+ # --- Gradio Interface ---
88
+ with gr.Blocks() as demo:
89
+ gr.Markdown("# πŸ“Œ Pinterest Ultra-HD 4K Downloader")
90
+ gr.Markdown("Deep searches Pinterest, filters by orientation, and enhances video to **4K (2160x3840)** with **Sharpening Filters**.")
91
 
92
  with gr.Row():
93
  with gr.Column():
94
+ q = gr.Textbox(label="Topic", placeholder="e.g. Nature Relaxing")
95
+ o = gr.Dropdown(choices=["Any", "Portrait", "Landscape"], value="Landscape", label="Required Orientation")
 
96
  with gr.Row():
97
+ s = gr.Number(label="Start (sec)", value=0)
98
+ e = gr.Number(label="End (sec, 0=Full)", value=5)
99
+ btn = gr.Button("πŸš€ Deep Search & Enhance", variant="primary")
 
100
 
101
  with gr.Column():
102
+ out_v = gr.Video(label="Enhanced 4K Result")
103
+ out_s = gr.Textbox(label="Status")
104
 
105
+ btn.click(process_video, [q, o, s, e], [out_v, out_s])
106
 
107
+ if __name__ == "__main__":
108
+ demo.launch()