Pixabay / app.py
Rezfars's picture
Update app.py
2e9c550 verified
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()