0Pricing
AI Agents · درس

تحويل الكلام إلى نص باستخدام Whisper وDeepgram

التفريغ الفوري والدُفعي، واكتشاف اللغة، وإضافة علامات الترقيم

تحويل الكلام إلى نص باستخدام Whisper وDeepgram درس مجاني في AI Agents على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Agents، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Agents 4 دروس في المجموع.

تحويل الكلام إلى نص في الوكلاء الصوتيين

يجب على الوكيل الصوتي تحويل الصوت المنطوق إلى نص قبل أن يتمكن نموذج اللغة الكبير من معالجته. تُسمّى هذه الخطوة تحويل الكلام إلى نص (STT) أو التعرّف التلقائي على الكلام (ASR).

هناك خياران رائدان: OpenAI Whisper (يعتمد على الملفات ويعالجها على دفعات) وDeepgram (للبثّ الفوري، مع تمييز المتحدثين والطوابع الزمنية للكلمات).

OpenAI Whisper: التفريغ الأساسي

يُستخدم Whisper عبر OpenAI API لتفريغ الملفات الصوتية. التنسيقات المدعومة: mp3 وmp4 وwav وwebm وm4a وflac. الحد الأقصى لحجم الملف: 25MB.

import openai
import os

client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))

def transcribe_file(audio_path, language=None):
    with open(audio_path, 'rb') as audio_file:
        params = {
            'model': 'whisper-1',
            'file': audio_file,
            'response_format': 'json'  # or 'text', 'srt', 'vtt', 'verbose_json'
        }
        if language:
            params['language'] = language  # e.g., 'en', 'fr', 'de'

        transcript = client.audio.transcriptions.create(**params)

    return transcript.text

# Basic usage
text = transcribe_file('meeting_recording.mp3')
print('Transcribed:', text[:200])

Whisper مع الطوابع الزمنية للكلمات

استخدم response_format='verbose_json' للحصول على الطوابع الزمنية لكل كلمة ومقطع. يفيد ذلك في العثور على لحظات محددة في التسجيلات، وإبراز الكلمات بأسلوب الكاريوكي، ومواءمة النصوص المفرغة مع تشغيل الصوت.

import openai
import os

client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))

def transcribe_with_timestamps(audio_path):
    with open(audio_path, 'rb') as f:
        result = client.audio.transcriptions.create(
            model='whisper-1',
            file=f,
            response_format='verbose_json',
            timestamp_granularities=['word', 'segment']  # get both word and segment times
        )

    segments = []
    for seg in result.segments:
        segments.append({
            'start': seg.start,
            'end':   seg.end,
            'text':  seg.text
        })

    words = []
    if hasattr(result, 'words'):
        for word in result.words:
            words.append({'word': word.word, 'start': word.start, 'end': word.end})

    return {'text': result.text, 'segments': segments, 'words': words}

Deepgram SDK: البث غير المتزامن

تم تحسين Deepgram لتفريغ الصوت عبر البث الفوري. يُرسَل الصوت على دفعات أثناء تسجيله، وتُعاد النصوص المفرغة جزئيًا قبل أن ينهي المتحدث جملته.

ثبّته باستخدام pip install deepgram-sdk.

import asyncio
import os
from deepgram import DeepgramClient, PrerecordedOptions

client = DeepgramClient(os.getenv('DEEPGRAM_API_KEY'))

async def transcribe_with_deepgram(audio_path):
    with open(audio_path, 'rb') as f:
        audio_data = f.read()

    options = PrerecordedOptions(
        model='nova-2',            # Deepgram's best accuracy model
        language='en',
        smart_format=True,         # auto-add punctuation and formatting
        utterances=True,           # segment by speaker turns
        punctuate=True,
        diarize=True               # speaker identification
    )

    response = await client.listen.asyncrest.v('1').transcribe_file(
        {'buffer': audio_data},
        options
    )

    return response.results.channels[0].alternatives[0].transcript

تمييز المتحدثين

يحدّد تمييز المتحدثين هوية المتحدث في كل لحظة، وذلك بوسم المقاطع مثل Speaker 0 وSpeaker 1 وغيرهما. ويُعدّ ذلك مهمًا جدًا لنصوص الاجتماعات والمحادثات متعددة الأطراف.

async def transcribe_with_diarization(audio_path):
    from deepgram import DeepgramClient, PrerecordedOptions
    import os

    dg_client = DeepgramClient(os.getenv('DEEPGRAM_API_KEY'))

    options = PrerecordedOptions(
        model='nova-2',
        diarize=True,
        utterances=True,
        smart_format=True
    )

    with open(audio_path, 'rb') as f:
        audio_data = f.read()

    response = await dg_client.listen.asyncrest.v('1').transcribe_file(
        {'buffer': audio_data}, options
    )

    utterances = []
    for utt in response.results.utterances:
        utterances.append({
            'speaker': f'Speaker {utt.speaker}',
            'start':   round(utt.start, 2),
            'end':     round(utt.end, 2),
            'text':    utt.transcript
        })

    return utterances

# Output:
# [{'speaker': 'Speaker 0', 'start': 0.0, 'end': 3.2, 'text': 'Hello everyone.'},
#  {'speaker': 'Speaker 1', 'start': 3.5, 'end': 6.1, 'text': 'Good morning!'}]

اكتشاف اللغة

عندما تكون لغة المستخدم غير معروفة، يستطيع كل من Whisper وDeepgram اكتشاف اللغة المنطوقة تلقائيًا. يكتشف Whisper اللغة من أول 30 ثانية من الصوت.

import openai
import os

client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))

def detect_language(audio_path):
    with open(audio_path, 'rb') as f:
        # Use translations endpoint to get verbose JSON with language detection
        result = client.audio.transcriptions.create(
            model='whisper-1',
            file=f,
            response_format='verbose_json'
        )
    return {
        'detected_language': result.language,
        'text': result.text
    }

result = detect_language('user_audio.wav')
print(f"Language: {result['detected_language']}")
print(f"Text: {result['text'][:100]}")

# Deepgram: set language='auto' in options
from deepgram import PrerecordedOptions
options = PrerecordedOptions(model='nova-2', language='auto', detect_language=True)

تقسيم الملفات الصوتية الطويلة إلى مقاطع

يعني حد Whisper البالغ 25MB أن التسجيلات الطويلة، مثل اجتماعات مدتها ساعة، تحتاج إلى تقسيمها إلى مقاطع. قسّم الصوت عند مواضع الصمت باستخدام pydub، ثم فرّغ كل مقطع وادمج النتائج.

ثبّته باستخدام pip install pydub. ويتطلب ffmpeg.

from pydub import AudioSegment
from pydub.silence import split_on_silence
import io

def transcribe_long_audio(audio_path, chunk_length_ms=60000):
    audio = AudioSegment.from_file(audio_path)

    # Split on silence
    chunks = split_on_silence(
        audio,
        min_silence_len=1000,   # 1 second of silence
        silence_thresh=-40,     # dBFS
        keep_silence=500        # keep 500ms at each end
    )

    # If no silence splitting worked, use fixed-length chunks
    if len(chunks) <= 1:
        chunks = [
            audio[i:i + chunk_length_ms]
            for i in range(0, len(audio), chunk_length_ms)
        ]

    full_transcript = []
    for i, chunk in enumerate(chunks):
        print(f'Transcribing chunk {i+1}/{len(chunks)}')
        buf = io.BytesIO()
        chunk.export(buf, format='mp3')
        buf.seek(0)
        buf.name = f'chunk_{i}.mp3'
        result = client.audio.transcriptions.create(model='whisper-1', file=buf)
        full_transcript.append(result.text)

    return ' '.join(full_transcript)

البث المباشر عبر Deepgram

للمحادثات الصوتية الفورية، استخدم واجهة WebSocket للبث المباشر في Deepgram. تُرسَل المقاطع الصوتية أثناء تسجيلها، وتصل النصوص المفرغة المؤقتة والنهائية خلال أجزاء من الثانية.

import asyncio
import os
from deepgram import DeepgramClient, LiveTranscriptionEvents, LiveOptions

async def live_transcribe(on_transcript_callback):
    dg_client = DeepgramClient(os.getenv('DEEPGRAM_API_KEY'))

    connection = dg_client.listen.asynclive.v('1')

    async def on_message(self, result, **kwargs):
        sentence = result.channel.alternatives[0].transcript
        is_final = result.is_final
        if sentence:
            await on_transcript_callback(sentence, is_final)

    connection.on(LiveTranscriptionEvents.Transcript, on_message)

    options = LiveOptions(
        model='nova-2',
        language='en',
        smart_format=True,
        interim_results=True,  # get partial results before sentence ends
        endpointing=500        # ms of silence before finalizing
    )

    await connection.start(options)
    return connection  # caller sends audio chunks via connection.send(audio_chunk)

معالجة الأخطاء وإعادة المحاولات

قد تفشل واجهات برمجة تطبيقات تفريغ الصوت بسبب مشكلات الشبكة أو التنسيقات غير المدعومة أو تجاوز حدود المعدل. نفّذ إعادة المحاولة مع تأخير أُسّي متزايد، وتحقق من صحة الصوت قبل إرساله.

import time
import os

MAX_FILE_SIZE_BYTES = 25 * 1024 * 1024  # 25MB
SUPPORTED_FORMATS = ('.mp3', '.mp4', '.wav', '.webm', '.m4a', '.flac', '.ogg')

def validate_audio_file(audio_path):
    if not os.path.exists(audio_path):
        raise FileNotFoundError(f'Audio file not found: {audio_path}')
    size = os.path.getsize(audio_path)
    if size > MAX_FILE_SIZE_BYTES:
        raise ValueError(f'File too large: {size / 1024 / 1024:.1f}MB (max 25MB)')
    ext = os.path.splitext(audio_path)[1].lower()
    if ext not in SUPPORTED_FORMATS:
        raise ValueError(f'Unsupported format: {ext}. Supported: {SUPPORTED_FORMATS}')

def transcribe_with_retry(audio_path, max_retries=3):
    validate_audio_file(audio_path)
    for attempt in range(max_retries):
        try:
            return transcribe_file(audio_path)
        except Exception as e:
            if attempt < max_retries - 1:
                wait = 2 ** attempt
                print(f'Retry {attempt + 1} after error: {e}. Waiting {wait}s')
                time.sleep(wait)
            else:
                raise

الاختيار بين Whisper وDeepgram

يتفوّق كل من الأداتين في سيناريوهات مختلفة. استخدم مصفوفة القرار هذه لاختيار الأداة المناسبة لوكيلك الصوتي.

COMPARISON = '''
Whisper (OpenAI API):
  - Best for: batch transcription, podcast processing, meeting notes
  - Latency: file upload latency + ~1-5 seconds processing
  - Strengths: excellent multilingual, high accuracy, cheap
  - Word timestamps: yes (verbose_json)
  - Diarization: NO (must use separate tool)
  - Use when: accuracy > speed, offline processing

DeeGram:
  - Best for: real-time voice agents, call center transcription
  - Latency: <300ms for streaming, ~1s for file upload
  - Strengths: streaming, diarization, custom vocabulary
  - Word timestamps: yes, with confidence scores
  - Diarization: YES (built-in, up to 10 speakers)
  - Use when: speed > accuracy, real-time required

Rule of thumb:
  Agent voice conversation -> Deepgram live streaming
  Batch audio files -> Whisper API
  Meeting transcripts with speakers -> Deepgram with diarize=True
'''
print(COMPARISON)

تحويل تنسيق الصوت

يدعم Whisper وDeepgram تنسيقات الصوت الشائعة، لكن صوت المستخدم قد يصل بتنسيقات غير معتادة، مثل ogg وopus وwebm من المتصفحات وm4a من iOS. حوّل الصوت إلى WAV أو MP3 قياسي قبل إرساله إلى واجهة برمجة التطبيقات.

from pydub import AudioSegment
import os

SUPPORTED_FORMATS = {'.mp3', '.wav', '.flac', '.m4a', '.ogg', '.webm', '.opus'}

def convert_to_wav(input_path, output_path=None):
    ext = os.path.splitext(input_path)[1].lower()
    if ext not in SUPPORTED_FORMATS:
        raise ValueError(f'Unsupported audio format: {ext}')

    if output_path is None:
        output_path = input_path.rsplit('.', 1)[0] + '.wav'

    # pydub handles format detection automatically
    audio = AudioSegment.from_file(input_path)

    # Normalize to 16kHz mono (optimal for Whisper)
    audio = audio.set_frame_rate(16000).set_channels(1)

    audio.export(output_path, format='wav')
    print(f'Converted {input_path} -> {output_path} ({len(audio) / 1000:.1f}s)')
    return output_path

def ensure_compatible_audio(audio_path):
    ext = os.path.splitext(audio_path)[1].lower()
    if ext in {'.mp3', '.wav', '.m4a', '.flac'}:
        return audio_path  # already compatible
    return convert_to_wav(audio_path)

اختبار المعرفة

ما المقصود بتمييز المتحدثين في سياق تفريغ الكلام إلى نص؟

مراجعة: تحويل الكلام إلى نص باستخدام Whisper وDeepgram

يُعدّ Whisper (عبر OpenAI API) مناسبًا للتفريغ على دفعات؛ فهو عالي الدقة ومتعدد اللغات، ويوفر طوابع زمنية للكلمات عبر verbose_json. استخدمه لمعالجة الملفات عندما لا يكون زمن الاستجابة عاملًا حاسمًا.

صُمّم Deepgram للبث الفوري؛ إذ يوفر تفريغًا مباشرًا عبر WebSocket مع نتائج مؤقتة، وتمييزًا مدمجًا للمتحدثين، وزمن استجابة أقل من 300ms. استخدمه للوكلاء الصوتيين التفاعليين. تدعم الأداتان اكتشاف اللغة، وتحتاجان في بيئة الإنتاج إلى منطق لإعادة المحاولة والتحقق من صحة الملفات.

الأسئلة الشائعة

هل درس «تحويل الكلام إلى نص باستخدام Whisper وDeepgram» مجاني؟

نعم — نص درس «تحويل الكلام إلى نص باستخدام Whisper وDeepgram» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Agents، انتقل إلى CoddyKit PRO. تتضمن دورة AI Agents 4 دروس في المجموع.

ماذا ستتعلم في «تحويل الكلام إلى نص باستخدام Whisper وDeepgram»؟

التفريغ الفوري والدُفعي، واكتشاف اللغة، وإضافة علامات الترقيم تتمرن على AI Agents مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ AI Agents؟

لا تُشترط خبرة سابقة. AI Agents على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «تحويل الكلام إلى نص باستخدام Whisper وDeepgram»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس AI Agents هذا؟

نعم. كل درس في AI Agents يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. تحويل الكلام إلى نص باستخدام Whisper وDeepgram
  2. تحويل النص إلى كلام في استجابات الوكيل
  3. بناء حلقة محادثة صوتية
  4. تحسين زمن الاستجابة للوكلاء الصوتيين
← العودة إلى AI Agents