Convertire un file audio in testo tramite Python

Per trascrivere un file audio in formato wav in un testo con il linguaggio Python, utilizzo una combinazione di moduli.

  • `pydub` è  il modulo utilizzato per manipolare file audio (caricare, spezzare, esportare).
  • `speech_recognition` è il modulo utilizzato per convertire l'audio in testo tramite il servizio di riconoscimento vocale di Google.

from pydub import AudioSegment
import speech_recognition as sr

# Carica il file audio
audio = AudioSegment.from_wav("/path/audio.wav")

# Definisci la lunghezza dei segmenti (es. 30 secondi)
segment_length = 30 * 1000  # in millisecondi
segments = [audio[i:i+segment_length] for i in range(0, len(audio), segment_length)]

recognizer = sr.Recognizer()

# Trascrivi ogni segmento
for i, segment in enumerate(segments):
    segment.export(f"segment_{i}.wav", format="wav")
    with sr.AudioFile(f"segment_{i}.wav") as source:
        audio_data = recognizer.record(source)
        try:
            text = recognizer.recognize_google(audio_data, language='it-IT')
            print(f"Segment {i}: {text}")
        except sr.RequestError as e:
            print(f"Errore nella trascrizione del segmento {i}: {e}")
        except sr.UnknownValueError:
            print(f"Non è stato possibile trascrivere il segmento {i}")

Il codice ha lo scopo di trascrivere un file audio in testo utilizzando il servizio Google Speech Recognition.

Tuttavia, se il file audio è troppo lungo, il codice lo spezza in segmenti più piccoli e li trascrive uno per uno per evitare problemi di connessione o timeout.

Nota. Dividere un file audio lungo in segmenti più piccoli è un approccio che aiuta a evitare errori legati alla dimensione del file o ai limiti di tempo delle richieste, migliorando la probabilità di successo della trascrizione. Ogni segmento viene processato e trascritto separatamente, e i risultati sono mostrati per ogni segmento.

Prima di eseguire il programma per la prima volta bisogna aver installato i moduli esterni.

In questo caso sto lavorando in ambiente Python 3.4. Qualsiasi altra versione superiore non dovrebbe dare problemi.

Per installarli basta digitare dal terminale

pip install --upgrade SpeechRecognition pydub

Il file audio deve essere disponibile in formato wav.

audio = AudioSegment.from_wav("/path/audio.wav")

Il codice carica il file audio WAV in un oggetto `AudioSegment` che permette di manipolare facilmente l'audio.

A questo punto il programma provvede alla divisione dell'audio in segmenti:

segment_length = 30 * 1000 # in millisecondi
segments = [audio[i:i+segment_length] for i in range(0, len(audio), segment_length)]

Il file audio viene spezzato in segmenti di 30 secondi (o un'altra durata a tua scelta). Ogni segmento è memorizzato in una lista `segments`.

Ogni segmento viene esportato come un file WAV temporaneo e caricato usando `speech_recognition`.

Il codice cerca di trascrivere l'audio in testo usando il servizio di Google.

Infine, il testo del segmento trascritto viene stampato a video.

for i, segment in enumerate(segments):
    segment.export(f"segment_{i}.wav", format="wav")
    with sr.AudioFile(f"segment_{i}.wav") as source:
        audio_data = recognizer.record(source)
        try:
            text = recognizer.recognize_google(audio_data, language='it-IT')
            print(f"Segment {i}: {text}")
        except sr.RequestError as e:
            print(f"Errore nella trascrizione del segmento {i}: {e}")
        except sr.UnknownValueError:
            print(f"Non è stato possibile trascrivere il segmento {i}")

Il codice gestisce eventuali errori di connessione (`RequestError`) o di riconoscimento vocale (`UnknownValueError`), così da continuare la trascrizione anche se un segmento non viene trascritto correttamente.

E per convertire i file MP3?

Se il file audio sorgente è in formato MP3, posso convertirlo in un file tempoeraneo WAV direttamente nel codice, prima dell'elaborazione.

Sostituisco la riga di codice

audio = AudioSegment.from_wav("audio.wav")

con la seguente che legge il file MP3 e lo converte in WAv

audio = AudioSegment.from_mp3(audio_path)
audio.export("audio.wav", format="wav")

In alternativa, dal terminale posso convertire manualmente il file MP3 in WAV usando FFMEG

ffmpeg -i audio.mp3 -ar 16000 -ac 1 audio.wav

E se il file sorgente è un video?

Anche in questo caso mi basta estrarre l'audio in formato WAV dal video tramite FFMEG

Ad esempio, ecco il comando per estrarre l'audio da un file video WEBM.

ffmpeg -i nome_del_video.webm -vn -acodec pcm_s16le -ar 44100 -ac 2 audio.wav

    Versione migliorata

    Questa versione migliora l'overlap, evita che le frasi vengano interrotte a metà parola.

    Per evitare che le frasi vengano interrotte a metà parola, i segmenti sono ora tagliati con un piccolo margine di sovrapposizione (es. 700 - 1200 ms).

    audio_path = r"C:\temp\audio.wav"
    from pydub import AudioSegment, effects
    import speech_recognition as sr

    # Parametri

    LANG = "en-US" # oppure "en-US"/"en-GB"
    SEGMENT_MS = 20_000
    OVERLAP_MS = 700 # evita di troncare parole

    # Carica WAV (ok senza ffmpeg) e fai un po' di pulizia base
    audio = AudioSegment.from_wav(audio_path)
    audio = audio.set_channels(1).set_frame_rate(16000)
    audio = effects.normalize(audio)

    # Segmenti con overlap
    step = max(1, SEGMENT_MS - OVERLAP_MS)
    segments = [audio[i:i + SEGMENT_MS] for i in range(0, len(audio), step)]
    recognizer = sr.Recognizer()
    for i, segment in enumerate(segments):
         # >>> NIENTE export(): creiamo AudioData direttamente dalla memoria <<<
         raw = segment.raw_data
         sample_rate = segment.frame_rate
         sample_width = segment.sample_width # in bytes
         audio_data = sr.AudioData(raw, sample_rate, sample_width)
         try:
              text = recognizer.recognize_google(audio_data, language=LANG)
              print(text)
         except sr.RequestError as e:
              print(f"Errore nella trascrizione del segmento {i}: {e}")
         except sr.UnknownValueError:
              print(f"Non è stato possibile trascrivere il segmento {i}")

    Alcuni consigli utili:

    Se il programma “mangia” ancora troppe parole ai bordi dei segmenti, è utile portare il parametro OVERLAP_MS a 900 - 1200 ms.

    Se, invece, l’audio è basso o rumoroso, la normalize() aiuta; in casi è utile aumenta il volume dell’audio di +3 decibel (dB) con il comando audio = audio.apply_gain(+3).

    E così via.

     


     

    Segnalami un errore, un refuso o un suggerimento per migliorare gli appunti

    FacebookTwitterLinkedinLinkedin
    knowledge base
    1. Il linguaggio Python
    2. Come installare Python sul PC
    3. Come scrivere un programma in Python
    4. Come usare Python in modalità interattiva
    5. Le variabili
    6. I numeri
    7. Gli operatori logici
    8. Le strutture iterative ( o cicli )
    9. Le strutture condizionali
    10. Le eccezioni
    11. I file in python
    12. Le classi
    13. I moduli