Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -8,6 +8,9 @@ from transformers import AutoFeatureExtractor, AutoModelForAudioFrameClassificat
|
|
| 8 |
from recitations_segmenter import segment_recitations, clean_speech_intervals
|
| 9 |
import io
|
| 10 |
from PIL import Image
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
# Setup device and model
|
| 13 |
device = 'cuda' if torch.cuda.is_available() else 'cpu'
|
|
@@ -93,7 +96,7 @@ def process_audio(audio_file, min_silence_ms, min_speech_ms, pad_ms):
|
|
| 93 |
"""معالجة الملف الصوتي وتقطيعه"""
|
| 94 |
|
| 95 |
if audio_file is None:
|
| 96 |
-
return None, "⚠️ من فضلك ارفع ملف صوتي", []
|
| 97 |
|
| 98 |
try:
|
| 99 |
# قراءة الملف
|
|
@@ -125,7 +128,6 @@ def process_audio(audio_file, min_silence_ms, min_speech_ms, pad_ms):
|
|
| 125 |
plot_img, stats_text = plot_signal(wav, intervals)
|
| 126 |
|
| 127 |
# استخراج المقاطع الصوتية
|
| 128 |
-
audio_segments = []
|
| 129 |
num_segments = len(intervals)
|
| 130 |
|
| 131 |
result_text = f"✅ تم التقطيع بنجاح!\n\n"
|
|
@@ -135,6 +137,10 @@ def process_audio(audio_file, min_silence_ms, min_speech_ms, pad_ms):
|
|
| 135 |
result_text += stats_text
|
| 136 |
result_text += "=" * 50 + "\n\n"
|
| 137 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
for idx in range(num_segments):
|
| 139 |
audio_seg = get_interval(
|
| 140 |
x=wav,
|
|
@@ -150,12 +156,34 @@ def process_audio(audio_file, min_silence_ms, min_speech_ms, pad_ms):
|
|
| 150 |
duration = len(audio_seg) / 16000
|
| 151 |
result_text += f"مقطع {idx + 1}: من {intervals[idx][0]:.2f}s إلى {intervals[idx][1]:.2f}s (المدة: {duration:.2f}s)\n"
|
| 152 |
|
| 153 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
|
| 155 |
-
return plot_img, result_text,
|
| 156 |
|
| 157 |
except Exception as e:
|
| 158 |
-
return None, f"❌ حدث خطأ: {str(e)}", []
|
| 159 |
|
| 160 |
# إنشاء واجهة Gradio
|
| 161 |
with gr.Blocks(title="تقطيع التلاوات القرآنية") as demo:
|
|
@@ -210,19 +238,27 @@ with gr.Blocks(title="تقطيع التلاوات القرآنية") as demo:
|
|
| 210 |
max_lines=20
|
| 211 |
)
|
| 212 |
|
| 213 |
-
gr.Markdown("###
|
| 214 |
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 218 |
|
| 219 |
def process_and_show(audio, min_sil, min_sp, pad):
|
| 220 |
-
plot, text, segments = process_audio(audio, min_sil, min_sp, pad)
|
|
|
|
|
|
|
| 221 |
|
| 222 |
-
|
| 223 |
-
for i in range(
|
| 224 |
if i < len(segments):
|
| 225 |
-
outputs.append(gr.Audio(value=segments[i], visible=True))
|
| 226 |
else:
|
| 227 |
outputs.append(gr.Audio(visible=False))
|
| 228 |
|
|
@@ -231,7 +267,7 @@ with gr.Blocks(title="تقطيع التلاوات القرآنية") as demo:
|
|
| 231 |
process_btn.click(
|
| 232 |
fn=process_and_show,
|
| 233 |
inputs=[audio_input, min_silence, min_speech, padding],
|
| 234 |
-
outputs=[plot_output, result_text] +
|
| 235 |
)
|
| 236 |
|
| 237 |
gr.Markdown("""
|
|
@@ -240,8 +276,10 @@ with gr.Blocks(title="تقطيع التلاوات القرآنية") as demo:
|
|
| 240 |
|
| 241 |
- الأداة تستخدم نموذج AI مدرب خصيصاً لتقطيع التلاوات القرآنية
|
| 242 |
- يتم اكتشاف فترات الكلام والسكوت تلقائياً
|
| 243 |
-
- يمكنك
|
|
|
|
| 244 |
""")
|
| 245 |
|
| 246 |
if __name__ == "__main__":
|
| 247 |
-
demo.launch()
|
|
|
|
|
|
| 8 |
from recitations_segmenter import segment_recitations, clean_speech_intervals
|
| 9 |
import io
|
| 10 |
from PIL import Image
|
| 11 |
+
import tempfile
|
| 12 |
+
import os
|
| 13 |
+
import zipfile
|
| 14 |
|
| 15 |
# Setup device and model
|
| 16 |
device = 'cuda' if torch.cuda.is_available() else 'cpu'
|
|
|
|
| 96 |
"""معالجة الملف الصوتي وتقطيعه"""
|
| 97 |
|
| 98 |
if audio_file is None:
|
| 99 |
+
return None, "⚠️ من فضلك ارفع ملف صوتي", None, []
|
| 100 |
|
| 101 |
try:
|
| 102 |
# قراءة الملف
|
|
|
|
| 128 |
plot_img, stats_text = plot_signal(wav, intervals)
|
| 129 |
|
| 130 |
# استخراج المقاطع الصوتية
|
|
|
|
| 131 |
num_segments = len(intervals)
|
| 132 |
|
| 133 |
result_text = f"✅ تم التقطيع بنجاح!\n\n"
|
|
|
|
| 137 |
result_text += stats_text
|
| 138 |
result_text += "=" * 50 + "\n\n"
|
| 139 |
|
| 140 |
+
# إنشاء مجلد مؤقت للمقاطع
|
| 141 |
+
temp_dir = tempfile.mkdtemp()
|
| 142 |
+
segment_files = []
|
| 143 |
+
|
| 144 |
for idx in range(num_segments):
|
| 145 |
audio_seg = get_interval(
|
| 146 |
x=wav,
|
|
|
|
| 156 |
duration = len(audio_seg) / 16000
|
| 157 |
result_text += f"مقطع {idx + 1}: من {intervals[idx][0]:.2f}s إلى {intervals[idx][1]:.2f}s (المدة: {duration:.2f}s)\n"
|
| 158 |
|
| 159 |
+
# حفظ المقطع
|
| 160 |
+
segment_path = os.path.join(temp_dir, f"segment_{idx+1:03d}.wav")
|
| 161 |
+
sf.write(segment_path, audio_seg, 16000)
|
| 162 |
+
segment_files.append(segment_path)
|
| 163 |
+
|
| 164 |
+
# إنشاء ملف ZIP
|
| 165 |
+
zip_path = os.path.join(temp_dir, "segments.zip")
|
| 166 |
+
with zipfile.ZipFile(zip_path, 'w') as zipf:
|
| 167 |
+
for seg_file in segment_files:
|
| 168 |
+
zipf.write(seg_file, os.path.basename(seg_file))
|
| 169 |
+
|
| 170 |
+
# إنشاء HTML لعرض المقاطع
|
| 171 |
+
audio_html = "<div style='max-height: 500px; overflow-y: auto;'>"
|
| 172 |
+
for idx, seg_file in enumerate(segment_files):
|
| 173 |
+
audio_html += f"""
|
| 174 |
+
<div style='margin: 10px 0; padding: 10px; border: 1px solid #ddd; border-radius: 5px;'>
|
| 175 |
+
<h4 style='margin: 5px 0;'>🎵 مقطع {idx + 1}</h4>
|
| 176 |
+
<audio controls style='width: 100%;'>
|
| 177 |
+
<source src='file/{seg_file}' type='audio/wav'>
|
| 178 |
+
</audio>
|
| 179 |
+
</div>
|
| 180 |
+
"""
|
| 181 |
+
audio_html += "</div>"
|
| 182 |
|
| 183 |
+
return plot_img, result_text, zip_path, segment_files
|
| 184 |
|
| 185 |
except Exception as e:
|
| 186 |
+
return None, f"❌ حدث خطأ: {str(e)}", None, []
|
| 187 |
|
| 188 |
# إنشاء واجهة Gradio
|
| 189 |
with gr.Blocks(title="تقطيع التلاوات القرآنية") as demo:
|
|
|
|
| 238 |
max_lines=20
|
| 239 |
)
|
| 240 |
|
| 241 |
+
gr.Markdown("### 💾 تحميل المقاطع")
|
| 242 |
|
| 243 |
+
zip_download = gr.File(label="📦 حمل كل المقاطع (ZIP)")
|
| 244 |
+
|
| 245 |
+
gr.Markdown("### 🎵 استماع للمقاطع")
|
| 246 |
+
|
| 247 |
+
# عرض المقاطع الصوتية
|
| 248 |
+
segment_outputs = []
|
| 249 |
+
for i in range(50): # حد أقصى 50 مقطع
|
| 250 |
+
audio_out = gr.Audio(label=f"مقطع {i+1}", visible=False)
|
| 251 |
+
segment_outputs.append(audio_out)
|
| 252 |
|
| 253 |
def process_and_show(audio, min_sil, min_sp, pad):
|
| 254 |
+
plot, text, zip_file, segments = process_audio(audio, min_sil, min_sp, pad)
|
| 255 |
+
|
| 256 |
+
outputs = [plot, text, zip_file]
|
| 257 |
|
| 258 |
+
# إظهار المقاطع
|
| 259 |
+
for i in range(50):
|
| 260 |
if i < len(segments):
|
| 261 |
+
outputs.append(gr.Audio(value=segments[i], visible=True, label=f"مقطع {i+1}"))
|
| 262 |
else:
|
| 263 |
outputs.append(gr.Audio(visible=False))
|
| 264 |
|
|
|
|
| 267 |
process_btn.click(
|
| 268 |
fn=process_and_show,
|
| 269 |
inputs=[audio_input, min_silence, min_speech, padding],
|
| 270 |
+
outputs=[plot_output, result_text, zip_download] + segment_outputs
|
| 271 |
)
|
| 272 |
|
| 273 |
gr.Markdown("""
|
|
|
|
| 276 |
|
| 277 |
- الأداة تستخدم نموذج AI مدرب خصيصاً لتقطيع التلاوات القرآنية
|
| 278 |
- يتم اكتشاف فترات الكلام والسكوت تلقائياً
|
| 279 |
+
- يمكنك تحميل كل المقاطع دفعة واحدة من ملف ZIP
|
| 280 |
+
- أو الاستماع لكل مقطع على حدة
|
| 281 |
""")
|
| 282 |
|
| 283 |
if __name__ == "__main__":
|
| 284 |
+
demo.launch()
|
| 285 |
+
|