File size: 5,520 Bytes
2e9c550 c10bf88 f30d0fa c10bf88 2e9c550 814058a 2e9c550 b35d379 2e9c550 c10bf88 2e9c550 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | import gradio as gr
import requests
import os
from moviepy.editor import VideoFileClip, concatenate_videoclips
import tempfile
# ---------------- تنظیمات ----------------
PIXABAY_API_KEY = os.getenv("PIXABAY_API_KEY") # در Settings → Secrets در Hugging Face بگذار
if not PIXABAY_API_KEY:
raise ValueError("لطفاً PIXABAY_API_KEY را در Secrets فضای خود قرار دهید!")
VIDEO_SEARCH_URL = "https://pixabay.com/api/videos/"
CLIP_DURATION = 3.0 # ثانیه
def download_video(url, temp_dir):
"""دانلود ویدیو و برگرداندن مسیر فایل"""
response = requests.get(url, stream=True)
if response.status_code != 200:
return None
temp_path = os.path.join(temp_dir, "clip.mp4")
with open(temp_path, "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
return temp_path
def search_pixabay_videos(query, per_page=10):
params = {
"key": PIXABAY_API_KEY,
"q": query,
"video_type": "all", # all / film / animation
"per_page": per_page,
"min_duration": 4, # حداقل ۴ ثانیه که بتوان ۳ ثانیه برداشت
"safesearch": "true"
}
try:
r = requests.get(VIDEO_SEARCH_URL, params=params, timeout=15)
r.raise_for_status()
data = r.json()
videos = []
for hit in data.get("hits", []):
# بهترین کیفیت ممکن (large یا medium)
vid = hit.get("videos", {})
if "large" in vid and vid["large"]["url"]:
videos.append(vid["large"]["url"])
elif "medium" in vid and vid["medium"]["url"]:
videos.append(vid["medium"]["url"])
return videos[:8] # حداکثر ۸ تا ویدیو بگیریم که پردازش سنگین نشود
except Exception as e:
print(e)
return []
def create_montage(keywords):
if not keywords.strip():
return None, "لطفاً کلمات کلیدی وارد کنید"
query = keywords.strip().replace(",", " ").replace(" ", " ")
with tempfile.TemporaryDirectory() as tmpdirname:
video_urls = search_pixabay_videos(query)
if not video_urls:
return None, f"هیچ ویدیویی برای '{query}' پیدا نشد."
clips = []
count = 0
for url in video_urls:
try:
path = download_video(url, tmpdirname)
if not path:
continue
clip = VideoFileClip(path)
# اگر ویدیو کوتاهتر از ۳ ثانیه بود → skip
if clip.duration < CLIP_DURATION:
clip.close()
continue
# برش ۳ ثانیه (مثلاً از وسط یا اول)
start = max(0, (clip.duration - CLIP_DURATION) / 2) # وسط ویدیو
subclip = clip.subclip(start, start + CLIP_DURATION)
clips.append(subclip)
count += 1
clip.close()
if count >= 5: # مثلاً حداکثر ۵ قطعه → حدود ۱۵ ثانیه
break
except Exception as e:
print(f"خطا در پردازش ویدیو: {e}")
continue
if not clips:
return None, "متأسفانه نتوانستیم ویدیوهای مناسب دانلود/برش دهیم."
try:
final_clip = concatenate_videoclips(clips, method="compose")
# خروجی موقت
output_path = os.path.join(tmpdirname, "montage.mp4")
final_clip.write_videofile(output_path,
codec="libx264",
audio_codec="aac",
fps=24,
preset="medium",
threads=4,
logger=None)
return output_path, f"ویدیو با موفقیت ساخته شد ({len(clips)} قطعه × ۳ ثانیه)"
except Exception as e:
return None, f"خطا در ساخت ویدیو: {str(e)}"
finally:
# تمیز کردن حافظه
for c in clips:
c.close()
if 'final_clip' in locals():
final_clip.close()
# ---------------- رابط کاربری Gradio ----------------
with gr.Blocks(title="Pixabay Video Montage") as demo:
gr.Markdown("# ساخت مونتاژ ویدیو از Pixabay\nکلمات کلیدی را وارد کنید (مثال: nature, sunset, drone)")
textbox = gr.Textbox(label="کلمات کلیدی (با کاما یا فاصله جدا کنید)", placeholder="ocean waves, beach, sunset")
btn = gr.Button("ساخت ویدیو (۳ ثانیه از هر کلیپ)")
output_video = gr.Video(label="ویدیوی نهایی")
status = gr.Textbox(label="وضعیت")
btn.click(
fn=create_montage,
inputs=textbox,
outputs=[output_video, status],
api_name="make_montage"
)
if __name__ == "__main__":
demo.launch() |