transcriptionv2 / app.py
KIMOSSINO's picture
Update app.py
5c8b131 verified
import gradio as gr
import whisper
import os
import asyncio
import edge_tts
from transformers import pipeline
from deep_translator import GoogleTranslator
from docx import Document
import tempfile
from datetime import datetime
import logging
from pydub import AudioSegment
# إعداد التسجيل
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
handlers=[
logging.FileHandler("app.log"),
logging.StreamHandler(),
],
)
logger = logging.getLogger(__name__)
# قائمة اللغات المدعومة
SUPPORTED_LANGUAGES = {
"ar": "العربية",
"en": "English",
"fr": "Français",
"es": "Español",
"de": "Deutsch",
}
# تعيين أصوات لكل لغة
VOICE_MAPPINGS = {
"ar": "ar-EG-ShakirNeural",
"en": "en-US-EricNeural",
"fr": "fr-FR-HenriNeural",
"es": "es-ES-AlvaroNeural",
"de": "de-DE-ConradNeural",
}
# تحديد اللغات RTL
RTL_LANGUAGES = ["ar"]
# وظيفة تنظيف النص
def clean_text(text):
return (
text.replace("’", "'")
.replace("«", "")
.replace("»", "")
.replace("\n", " ")
.strip()
)
# وظيفة توليد الصوت
async def generate_speech(text, lang):
"""توليد الصوت باستخدام edge-tts"""
try:
voice = VOICE_MAPPINGS.get(lang, "en-US-EricNeural")
communicate = edge_tts.Communicate(text, voice)
audio_path = tempfile.mktemp(suffix=".mp3")
await communicate.save(audio_path)
if os.path.exists(audio_path) and os.path.getsize(audio_path) > 0:
logger.info(f"تم إنشاء ملف صوتي: {audio_path}")
return audio_path
else:
logger.error("فشل إنشاء ملف صوتي صالح")
return None
except Exception as e:
logger.error(f"خطأ في توليد الصوت: {str(e)}")
return None
# تحويل النص إلى صوت
def text_to_speech(text, lang):
if not text:
logger.warning("لم يتم تقديم نص للتحويل إلى صوت")
return None
try:
text = clean_text(text)
max_length = 1000
text_parts = [text[i : i + max_length] for i in range(0, len(text), max_length)]
audio_files = []
for part in text_parts:
audio_path = asyncio.run(generate_speech(part, lang))
if audio_path:
audio_files.append(audio_path)
if len(audio_files) == 1:
return audio_files[0]
final_audio = AudioSegment.from_mp3(audio_files[0])
for audio_file in audio_files[1:]:
final_audio += AudioSegment.from_mp3(audio_file)
final_path = tempfile.mktemp(suffix=".mp3")
final_audio.export(final_path, format="mp3")
for file in audio_files:
os.remove(file)
return final_path
except Exception as e:
logger.error(f"خطأ في تحويل النص إلى صوت: {str(e)}")
return None
# الترجمة
def translate_text(text, source_lang, target_lang):
if source_lang == target_lang:
return text
try:
translator = GoogleTranslator(source=source_lang, target=target_lang)
max_length = 5000
text_parts = [text[i : i + max_length] for i in range(0, len(text), max_length)]
translated_parts = [translator.translate(part) for part in text_parts]
return " ".join(translated_parts)
except Exception as e:
logger.error(f"خطأ في الترجمة: {str(e)}")
return f"خطأ في الترجمة: {str(e)}"
# معالجة الفيديو
def process_video(video, source_lang="en", target_lang="ar"):
if video is None:
return {
"error": "الرجاء رفع ملف فيديو",
"original": "",
"translated": "",
}
try:
temp_path = video.name
model = whisper.load_model("base")
result = model.transcribe(temp_path, language=source_lang)
transcribed_text = result["text"]
translated_text = translate_text(transcribed_text, source_lang, target_lang)
return {
"error": None,
"original": transcribed_text,
"translated": translated_text,
}
except Exception as e:
logger.error(f"خطأ في معالجة الفيديو: {str(e)}")
return {
"error": f"حدث خطأ: {str(e)}",
"original": "",
"translated": "",
}
# إنشاء الواجهة
def create_ui():
with gr.Blocks() as demo:
gr.Markdown("# 🎥 تحويل الفيديو إلى نصوص وصوت")
with gr.Row():
video_input = gr.File(label="📁 رفع فيديو", file_types=["video"])
source_lang = gr.Dropdown(
choices=list(SUPPORTED_LANGUAGES.keys()),
value="en",
label="🗣️ لغة الفيديو الأصلية",
)
target_lang = gr.Dropdown(
choices=list(SUPPORTED_LANGUAGES.keys()),
value="ar",
label="🌐 لغة الترجمة",
)
process_btn = gr.Button("🎯 معالجة الفيديو")
with gr.Tabs():
with gr.TabItem("النص الأصلي"):
original_text = gr.Textbox(label="النص المستخرج", lines=10)
original_audio = gr.Audio(label="الصوت")
with gr.TabItem("النص المترجم"):
translated_text = gr.Textbox(label="النص المترجم", lines=10)
translated_audio = gr.Audio(label="الصوت")
def update_ui(video, src_lang, tgt_lang):
result = process_video(video, src_lang, tgt_lang)
return {
original_text: result["original"],
translated_text: result["translated"],
}
process_btn.click(
fn=update_ui,
inputs=[video_input, source_lang, target_lang],
outputs=[original_text, translated_text],
)
return demo
if __name__ == "__main__":
demo = create_ui()
demo.launch()