kader1997 commited on
Commit
e15af47
·
verified ·
1 Parent(s): 62041f5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -85
app.py CHANGED
@@ -1,118 +1,64 @@
1
  import os
2
  import time
3
- import numpy as np
4
- import librosa
5
  import gradio as gr
6
- from scipy.signal import butter, lfilter
7
 
8
- # ضبط مسار ImageMagick
9
- os.environ["IMAGEMAGICK_BINARY"] = r"C:\Program Files\ImageMagick-7.1.2-Q16-HDRI\magick.exe"
 
10
 
11
- try:
12
- from moviepy.editor import VideoFileClip, concatenate_videoclips
13
- except ImportError:
14
- from moviepy import VideoFileClip, concatenate_videoclips
15
-
16
- # ------------------ أدوات مساعدة ------------------
17
-
18
- def safe_subclip(clip, start, end):
19
- if hasattr(clip, 'subclipped'):
20
- return clip.subclipped(start, end)
21
- return clip.subclip(start, end)
22
-
23
- def highpass_filter(y, sr, cutoff=80):
24
- nyquist = 0.5 * sr
25
- normal_cutoff = cutoff / nyquist
26
- b, a = butter(1, normal_cutoff, btype='high', analog=False)
27
- return lfilter(b, a, y)
28
-
29
- # ------------------ الدالة الرئيسية ------------------
30
-
31
- def remove_silence(video_path, threshold, progress=gr.Progress()):
32
- if not video_path:
33
- return None, "يرجى رفع فيديو أولاً."
34
-
35
- output_filename = f"final_result_{int(time.time())}.mp4"
36
  video = None
 
 
37
 
38
  try:
39
- progress(0.1, desc="جاري تحليل الصوت...")
40
  video = VideoFileClip(video_path)
41
-
42
- fps_audio = 22050
43
- audio = video.audio
44
- audio_array = audio.to_soundarray(fps=fps_audio)
45
-
46
- if audio_array.ndim > 1:
47
- audio_array = np.mean(audio_array, axis=1)
48
-
49
- audio_array = librosa.util.normalize(audio_array)
50
- audio_array = highpass_filter(audio_array, fps_audio)
51
-
52
- progress(0.3, desc="تحديد فترات الكلام...")
53
- intervals = librosa.effects.split(audio_array, top_db=abs(threshold))
54
 
55
- if len(intervals) == 0:
56
- return None, "تنبيه: لم يتم اكتشاف صوت فوق العتبة المحددة."
57
-
58
- keep_clips = []
59
- padding = 0.1
60
- video_duration = video.duration
61
-
62
- for start_idx, end_idx in intervals:
63
- t_start = max(0, (start_idx / fps_audio) - padding)
64
- t_end = min(video_duration, (end_idx / fps_audio) + padding)
65
- if t_end - t_start > 0.1:
66
- keep_clips.append(safe_subclip(video, t_start, t_end))
67
-
68
- if not keep_clips:
69
- return None, "لم يتم العثور على مقاطع صالحة للقص."
70
-
71
- progress(0.6, desc="دمج الفيديو...")
72
- final_video = concatenate_videoclips(keep_clips, method="compose")
73
 
74
- progress(0.8, desc="تصدير الملف النهائي...")
75
  final_video.write_videofile(
76
  output_filename,
77
  fps=video.fps,
78
  codec="libx264",
79
  audio_codec="aac",
80
- temp_audiofile="temp-audio.m4a",
81
- remove_temp=True,
82
  threads=4,
83
  preset="ultrafast",
84
  logger=None
85
  )
86
 
87
- # تحرير الذاكرة وإغلاق الكليبات
88
  video.close()
89
- for c in keep_clips:
90
- c.close()
91
- final_video.close()
92
-
93
- return output_filename, "تمت المعالجة بنجاح!"
94
 
95
  except Exception as e:
96
- if video:
97
- video.close()
98
  return None, f"خطأ تقني: {str(e)}"
99
 
100
- # ------------------ واجهة Gradio ------------------
101
-
102
- # إزالة theme من هنا لتجنب التحذير
103
- with gr.Blocks(title="SilentCut Pro") as demo:
104
- gr.Markdown("# 🎬 SilentCut Pro")
105
  with gr.Row():
106
  with gr.Column():
107
- v_in = gr.Video(label="ارفع الفيديو")
108
- slider = gr.Slider(minimum=-60, maximum=-10, value=-30, label="حساسية الصمت (ديسيبل)")
109
- btn = gr.Button("🚀 بدء المعالجة", variant="primary")
 
110
  with gr.Column():
111
- v_out = gr.Video(label="الفيديو الناتج")
112
  status = gr.Textbox(label="الحالة", interactive=False)
113
 
114
- btn.click(fn=remove_silence, inputs=[v_in, slider], outputs=[v_out, status])
115
 
116
  if __name__ == "__main__":
117
- # نقل الـ theme والـ ssr_mode إلى هنا
118
- demo.launch(theme=gr.themes.Soft(), ssr_mode=False)
 
1
  import os
2
  import time
 
 
3
  import gradio as gr
4
+ from moviepy.editor import VideoFileClip, AudioFileClip
5
 
6
+ def sync_audio_video(video_path, audio_path, progress=gr.Progress()):
7
+ if not video_path or not audio_path:
8
+ return None, "يرجى رفع ملف الفيديو وملف الصوت."
9
 
10
+ output_filename = f"synced_video_{int(time.time())}.mp4"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  video = None
12
+ audio = None
13
+ final_video = None
14
 
15
  try:
16
+ progress(0.2, desc="تحميل الملفات...")
17
  video = VideoFileClip(video_path)
18
+ audio = AudioFileClip(audio_path)
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ progress(0.5, desc="جاري المزامنة...")
21
+
22
+ # إذا كان الصوت أطول من الفيديو، سيتم قص الصوت
23
+ # إذا كان الفيديو أطول، سيتم قص الفيديو ليناسب الصوت (أو العكس حسب رغبتك)
24
+ min_duration = min(video.duration, audio.duration)
25
+
26
+ # ضبط الصوت للفيديو
27
+ final_video = video.set_audio(audio).set_duration(min_duration)
 
 
 
 
 
 
 
 
 
 
28
 
29
+ progress(0.7, desc="بدء التصدير النهائي...")
30
  final_video.write_videofile(
31
  output_filename,
32
  fps=video.fps,
33
  codec="libx264",
34
  audio_codec="aac",
 
 
35
  threads=4,
36
  preset="ultrafast",
37
  logger=None
38
  )
39
 
 
40
  video.close()
41
+ audio.close()
42
+ return output_filename, "تمت المزامنة بنجاح!"
 
 
 
43
 
44
  except Exception as e:
 
 
45
  return None, f"خطأ تقني: {str(e)}"
46
 
47
+ # واجهة Gradio للمزامنة
48
+ with gr.Blocks(theme=gr.themes.Soft(), title="Audio Sync Pro") as demo:
49
+ gr.Markdown("# 🎵 مزامنة الصوت مع الفيديو")
50
+
 
51
  with gr.Row():
52
  with gr.Column():
53
+ v_in = gr.Video(label="ارفع الفيديو (بدون صوت أو بصوت ضعيف)")
54
+ a_in = gr.Audio(label="ارفع ملف الصوت (MP3, WAV)", type="filepath")
55
+ btn = gr.Button("🔗 ابدأ المزامنة الآن", variant="primary")
56
+
57
  with gr.Column():
58
+ v_out = gr.Video(label="الفيديو المدمج")
59
  status = gr.Textbox(label="الحالة", interactive=False)
60
 
61
+ btn.click(fn=sync_audio_video, inputs=[v_in, a_in], outputs=[v_out, status])
62
 
63
  if __name__ == "__main__":
64
+ demo.launch()