Spaces:
Sleeping
Sleeping
File size: 8,148 Bytes
89328d3 56c7995 23669f0 56c7995 89328d3 56c7995 | 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 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | import streamlit as st
import whisper
import os
import requests
from bs4 import BeautifulSoup
from moviepy.editor import *
import arabic_reshaper
from bidi.algorithm import get_display
from googletrans import Translator
import time
# --- فەنکشنە پێشکەوتووەکان ---
def apply_text_motion(clip, text, font_path, motion_type, duration):
"""دانانی مۆشنی تێکست بەپێی جۆری هەڵبژێردراو."""
# چاککردنی فارسی/کوردی
reshaped_text = arabic_reshaper.reshape(text)
bidi_text = get_display(reshaped_text)
# دانانی شێوازی بنەڕەتی بۆ تێکست
txt_clip = TextClip(bidi_text, fontsize=80, color='yellow', font=font_path, stroke_color='black', stroke_width=3, method='caption', align='center', size=(700, None))
if motion_type == "Fade In/Out":
# دەرکەوتن و ونبوون
clip = txt_clip.set_duration(duration).set_pos('bottom').fx(fadein, 0.5).fx(fadeout, 0.5)
elif motion_type == "Zoom In":
# زووم کردن و گەورەبوون
def zoom_in_effect(t):
scale = 1 + 0.5 * (t / duration)
return txt_clip.set_scale(scale).get_frame(t)
clip = txt_clip.set_duration(duration).set_pos('center').fl(zoom_in_effect, apply_to=['mask', 'video'])
elif motion_type == "Slide Up":
# هاتنەسەرەوە لە خوارەوە
w, h = txt_clip.size
clip = txt_clip.set_duration(duration)
clip = clip.set_pos(lambda t: ('center', 100 + h * (1 - t / duration)))
else: # Default (Simple Fade In/Out)
clip = txt_clip.set_duration(duration).set_pos('bottom').fx(fadein, 0.5).fx(fadeout, 0.5)
return clip.set_duration(duration)
def apply_image_motion(image_clip, motion_type):
"""دانانی ئیفێکتی Ken Burns و جوڵەی تری وێنە."""
if motion_type == "Ken Burns (Zoom Out)":
# زووم ئاوتێکی هێواش
clip = image_clip.fx(vfx.resize, lambda t: 1.2 - 0.2 * (t / image_clip.duration))
elif motion_type == "Ken Burns (Zoom In)":
# زووم ئینێکی هێواش
clip = image_clip.fx(vfx.resize, lambda t: 1 + 0.2 * (t / image_clip.duration))
elif motion_type == "Slide Right":
# خشاندن بۆ لای ڕاست
w, h = image_clip.size
clip = image_clip.set_pos(lambda t: ('-100+{}'.format(int(200 * t / image_clip.duration)), 'center'))
else:
clip = image_clip # بێ جوڵە
# دڵنیابوون لە قەبارەی شۆرتی یوتیوب (9:16)
clip = vfx.resize(clip, height=1280)
clip = vfx.crop(clip, width=720, height=1280, x_center=clip.w / 2, y_center=clip.h / 2)
return clip
# --- فەنکشنی دروستکردنی ڤیدیۆ (بۆ تێست) ---
# تێبینی: بەهۆی قورسی دروستکردنی AI Image لەسەر سێرڤەری خۆڕایی، ئێمە وێنەی ڕەنگینی سادە بەکاردێنین بۆ تێست
def create_ai_images(prompts):
"""لێرە کۆدی دروستکردنی وێنە بە AI (Stable Diffusion/Hugging Face API) دادەنرێت"""
st.info("بەهۆی سنوورداربوونی سێرڤەری خۆڕایی، 5 وێنەی کاتی دروست دەکرێت.")
images = []
colors = [(255, 100, 100), (100, 255, 100), (100, 100, 255), (255, 255, 100), (100, 255, 255)]
for i in range(5):
# دروستکردنی وێنەی ڕەنگ بە پیلۆ
img = ImageClip(np.array([colors[i]]*100*100, dtype=np.uint8).reshape(100, 100, 3), duration=3)
images.append(img)
return images
# --- UI سەرەکی ---
st.title("🎼 ئۆتۆمەیشنی شۆرتی گۆرانی فارسی (پڕۆ)")
st.caption("سیستەمی 'یەک کلیک' لەسەر Hugging Face Spaces + Streamlit")
# ئیختیاراتی بەکاربەر
st.sidebar.header("🎨 هەڵبژاردەی کوالێتی")
text_motion = st.sidebar.selectbox("جوڵەی تێکست (Text Motion):", ["Fade In/Out", "Zoom In", "Slide Up", "بێ جوڵە"])
image_motion = st.sidebar.selectbox("جوڵەی وێنە (Image Motion):", ["Ken Burns (Zoom Out)", "Ken Burns (Zoom In)", "Slide Right", "بێ جوڵە"])
uploaded_file = st.file_uploader("فایلی گۆرانییەکە ئەپلۆد بکە (.mp3, .wav)", type=["mp3", "wav"])
if uploaded_file is not None:
st.audio(uploaded_file, format='audio/mp3')
if st.button('◀️ دروستکردنی ڤیدیۆ (دەستپێکردن)', key='start_button'):
# دڵنیابوون لە سڕینەوەی فایلی پێشوو
if os.path.exists("temp_audio.mp3"): os.remove("temp_audio.mp3")
if os.path.exists("final_short.mp4"): os.remove("final_short.mp4")
# 1. خەزنکردنی دەنگ
with open("temp_audio.mp3", "wb") as f:
f.write(uploaded_file.getbuffer())
# 2. Transcribe & Search (هەنگاوەکان)
with st.spinner('1. ساغکردنەوەی دەنگ و دۆزینەوەی شعر...'):
model = whisper.load_model("base")
result = model.transcribe("temp_audio.mp3")
transcribed_text = result["text"]
# لێرە کۆدی گەڕان لە گوگڵ و بەراوردکردن دادەنرێت
# دابەشکردنی تێکست بۆ دێڕی کورت بۆ نیشاندان
lyrics_lines = final_lyrics.split('\n')
if len(lyrics_lines) < 5: lyrics_lines = [final_lyrics] * 5
st.success(f"شعرەکە دۆزرایەوە (نموونە): {lyrics_lines[0]}...")
# 3. AI Image Generation (یاخود وێنەی کاتی)
with st.spinner('2. دروستکردنی وێنەکانی چیرۆکەکە...'):
image_clips = create_ai_images(lyrics_lines)
st.success(f"5 وێنەی کاتی دروست کرا.")
# 4. Video Construction
with st.spinner('3. مۆنتاژکردن و دانانی مۆشنی پڕۆفیشناڵ...'):
final_clips = []
segment_duration = audio_clip.duration / len(image_clips) # دابەشکردنی کات
# دروستکردنی ڤیدیۆی سەرەکی
for i, img_clip in enumerate(image_clips):
# دانانی کات بۆ وێنەکە
img_clip = img_clip.set_duration(segment_duration)
# دانانی جوڵە بۆ وێنە (Ken Burns, Slide)
motion_clip = apply_image_motion(img_clip, image_motion)
# دانانی تێکست لەسەر وێنەکە
if i < len(lyrics_lines):
text_segment = lyrics_lines[i]
# دانانی جوڵە بۆ تێکست
text_clip = apply_text_motion(motion_clip, text_segment, 'Arial', text_motion, segment_duration)
final_clip = CompositeVideoClip([motion_clip, text_clip])
else:
final_clip = motion_clip
final_clips.append(final_clip)
# یەکخستنی هەموو بەشەکان
final_video = concatenate_videoclips(final_clips)
# دانانی دەنگەکە لەسەر ڤیدیۆ کۆتاییەکە
audio_clip = AudioFileClip("temp_audio.mp3")
final_video = final_video.set_audio(audio_clip)
# Render
final_video.write_videofile("final_short.mp4", fps=24, threads=4, logger=None)
st.success("✅ ڤیدیۆکە بە سەرکەوتوویی دروست کرا!")
st.video("final_short.mp4")
with open("final_short.mp4", "rb") as file:
st.download_button(
label="داگرتنی ڤیدیۆکە (.mp4)",
data=file,
file_name="youtube_short.mp4",
mime="video/mp4"
) |