File size: 6,733 Bytes
ebec731
e254e59
 
 
ecd69bd
7071c4e
7aefecc
e254e59
 
 
 
 
 
 
7071c4e
e254e59
 
 
 
 
 
7071c4e
e254e59
 
7071c4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e254e59
7071c4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e254e59
7071c4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e254e59
7071c4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e254e59
7071c4e
 
 
e254e59
7071c4e
 
e254e59
7071c4e
e254e59
 
 
 
 
 
 
7071c4e
e254e59
 
 
 
 
7071c4e
e254e59
 
 
 
 
 
 
 
 
 
 
ebec731
e254e59
7071c4e
 
 
 
 
 
 
 
 
 
e254e59
 
 
 
7071c4e
e254e59
 
 
 
7071c4e
e254e59
 
 
 
ebec731
e254e59
 
 
7071c4e
 
e254e59
fde92ad
e254e59
ecd69bd
 
e254e59
f9a6912
6f18f29
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
import os
import sys
import logging
import warnings
import torch
from typing import Optional, Dict, Any

# הגדרת logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# התעלמות מאזהרות לא רלוונטיות
warnings.filterwarnings("ignore", category=UserWarning)

try:
    import gradio as gr
    from pyannote.audio import Pipeline
except ImportError as e:
    logger.error(f"שגיאה בטעינת הספריות הנדרשות: {str(e)}")
    sys.exit(1)

def initialize_pipeline() -> Optional[Pipeline]:
    """אתחול מודל הדיאריזציה עם טיפול שגיאות"""
    try:
        hf_token = os.getenv('HF_TOKEN')
        if not hf_token:
            raise ValueError("לא נמצא HF_TOKEN במשתני הסביבה")

        pipeline = Pipeline.from_pretrained(
            "pyannote/[email protected]",
            use_auth_token=hf_token
        )

        # העברה ל-GPU אם זמין
        if torch.cuda.is_available():
            pipeline = pipeline.to(torch.device("cuda"))
            logger.info("המודל הועבר ל-GPU")
        else:
            logger.info("רץ על CPU")

        return pipeline

    except Exception as e:
        logger.error(f"שגיאה באתחול המודל: {str(e)}")
        return None

def process_audio(audio_path: str, min_speakers: int = None, max_speakers: int = None) -> Dict[str, Any]:
    """עיבוד קובץ האודיו וזיהוי דוברים"""
    try:
        # בדיקות תקינות
        if not audio_path or not os.path.exists(audio_path):
            return {"error": "לא נבחר קובץ אודיו תקין"}

        file_size_mb = os.path.getsize(audio_path) / (1024 * 1024)
        if file_size_mb > 100:  # הגבלת גודל ל-100MB
            return {"error": f"גודל הקובץ ({file_size_mb:.1f}MB) גדול מדי. המקסימום הוא 100MB"}

        # אתחול המודל
        pipeline = initialize_pipeline()
        if pipeline is None:
            return {"error": "שגיאה באתחול המודל"}

        # הגדרת פרמטרים לזיהוי
        diarization_options = {}
        if min_speakers and min_speakers > 0:
            diarization_options['min_speakers'] = min_speakers
        if max_speakers and max_speakers > 0:
            diarization_options['max_speakers'] = max_speakers

        # זיהוי דוברים
        diarization = pipeline(audio_path, **diarization_options)

        # עיבוד התוצאות
        results = []
        speakers = set()
        total_duration = 0

        for turn, _, speaker in diarization.itertracks(yield_label=True):
            segment = {
                "start": turn.start,
                "end": turn.end,
                "duration": turn.duration,
                "speaker": speaker
            }
            results.append(segment)
            speakers.add(speaker)
            total_duration += turn.duration

        # יצירת פלט מעוצב
        output = [
            "תוצאות זיהוי הדוברים:",
            "=" * 30,
            ""
        ]

        for segment in results:
            output.append(
                f"[{segment['start']:.1f}s -> {segment['end']:.1f}s] "
                f"{segment['speaker']}"
            )

        output.extend([
            "",
            "=" * 30,
            "סיכום:",
            f"• מספר דוברים שזוהו: {len(speakers)}",
            f"• משך כולל: {total_duration:.1f} שניות",
            f"• גודל הקובץ: {file_size_mb:.1f}MB",
        ])

        if min_speakers or max_speakers:
            constraints = []
            if min_speakers:
                constraints.append(f"מינימום {min_speakers} דוברים")
            if max_speakers:
                constraints.append(f"מקסימום {max_speakers} דוברים")
            output.append(f"• הגבלות: {', '.join(constraints)}")

        return {"text": "\n".join(output)}

    except Exception as e:
        logger.error(f"שגיאה בעיבוד האודיו: {str(e)}")
        return {"error": f"שגיאה בעיבוד: {str(e)}"}

def create_gradio_interface() -> gr.Interface:
    """יצירת ממשק המשתמש"""
    return gr.Interface(
        fn=lambda audio, min_spk, max_spk: process_audio(audio, min_spk, max_spk).get("text", "שגיאה בעיבוד"),
        inputs=[
            gr.Audio(
                label="קובץ אודיו",
                type="filepath"
            ),
            gr.Number(
                label="מינימום דוברים (אופציונלי)",
                value=None,
                minimum=0,
                step=1
            ),
            gr.Number(
                label="מקסימום דוברים (אופציונלי)",
                value=None,
                minimum=0,
                step=1
            )
        ],
        outputs=gr.Textbox(
            label="תוצאות הזיהוי",
            lines=10
        ),
        title="זיהוי דוברים בהקלטות",
        description="""
        העלה קובץ אודיו לזיהוי הדוברים השונים והזמנים שלהם.
        
        הערות:
        • תומך בפורמטים: WAV, MP3, FLAC
        • גודל קובץ מקסימלי: 100MB
        • מומלץ להשתמש בהקלטות באיכות טובה
        • אם ידוע מספר הדוברים, ציון שלו יכול לשפר את הדיוק
        """,
        article="""
        שים לב:
        1. הזיהוי הכי מדויק בהקלטות ללא רעשי רקע
        2. לפעמים המודל יכול לזהות את אותו דובר פעמיים
        3. הזמנים מוצגים בשניות
        """,
        examples=[
            ["example.wav", 2, 4],
            ["interview.mp3", 2, 2]
        ]
    )

if __name__ == "__main__":
    try:
        # מידע על הסביבה
        logger.info(f"Python version: {sys.version}")
        logger.info(f"PyTorch version: {torch.__version__}")
        logger.info(f"Space ID: {os.getenv('SPACE_ID', 'unknown')}")
        logger.info(f"GPU available: {torch.cuda.is_available()}")
        
        if torch.cuda.is_available():
            logger.info(f"GPU model: {torch.cuda.get_device_name(0)}")

        # יצירה והפעלת הממשק
        demo = create_gradio_interface()
        demo.launch(
            share=True
        )
        
    except Exception as e:
        logger.error(f"שגיאה קריטית: {str(e)}")
        sys.exit(1)