Pythonで音声ファイルの文字起こしを行う方法。事前準備で人間の試聴作業負担を軽減。

例えば、次のような音声ファイルの一覧と、その内容(台本)があるとします。今回の業務では、これらの音声ファイルの中身が台本と一致しているかどうかを確認して納品することを想定します。

なお、以下のデータは実際の作業データとは一切関係ありません。英文はChatGPTにて作成しました。また、音声データは合成音声によるもので、人間のナレーターが読んだ英文の認識精度とは異なります。

エクセルの内容一覧(左)とファイルの一覧(右)

本記事では、音声ファイルを、Pythonを使って文字起こしを行い、各音声ファイルの内容を確認する方法について解説します。

音声ファイルには、人の声や音楽など、様々な情報が含まれています。今回の作業では、最終的に人間が内容を確認して納品することを想定します。ファイル名と内容(台本)の不一致や過不足があった場合、ファイルを聞いて確認するのは、非常に手間がかかります。そのため、事前に正しいファイルかどうかを簡易的に確認し、人間の確認を最小限で済むように工夫します。

上記のスクリーンショットでは、台本(左)は9ファイル分、ファイルの一覧(右)は10ファイルあり、すでにファイル1つ分多いことがわかります。これを人間の耳でチェックして探すのは一苦労です。プログラムによるチェックを行うことで、以下の結果を得ることができます。

エクセルの内容一覧(左)と出力結果(右・加工済)

左右の一覧を見ると、赤く色をつけている部分が異なることがわかります。厳密に一致しているわけではありませんが、ぱっと見でわかる範囲で、違っていることを確認できます。

具体的には
「04」「05」は中身が入れ替わっています。(データの取り違え)
「09」は文の前半しか読まれていません。(不完全なデータ)

プログラムによってoutput.txtに結果が出力されます。その出力結果をエクセルに貼り付けて、並べ替え等の整形を行っています。

この事前のチェックを経て、人間がチェックすることで、ミスを減らした状態で確認作業を進めることができます。人間が聞いて確認する前段階として準備を行い、より効率的に音声ファイルをチェックすることができます。

実際のPythonコード

from pydub import AudioSegment
import speech_recognition as sr
import io
import os

def recognize(file):
    #音声ファイルを読み込み
    wav = AudioSegment.from_file(file, format="mp3").export(io.BytesIO(), format="wav")
    audio_file = sr.AudioFile(wav)

    #音声認識オブジェクトを作成
    r = sr.Recognizer()

    #音声ファイルをオーディオソースとして読み込み
    with audio_file as source:
        audio = r.record(source)

    #音声認識を実行
    # text = r.recognize_google(audio, language='en-US')
    text = r.recognize_sphinx(audio, language='en-US')

    return text

def get_file_paths(folder_path):
    file_paths = []
    for root, dirs, files in os.walk(folder_path):
        for file_path in files:
            input_path = os.path.join(root, file_path)
            file_paths.append(input_path)
    return file_paths

def get_filename_from_path(path):
    # パスからファイル名だけを取得する
    filename = os.path.basename(path)
    return filename

def find_files_with_keyword(path, keyword):
    matching_files = []
    for root, dir, files in os.walk(path):
        for filename in files:
            if keyword in filename:
                if os.path.isfile(os.path.join(root, filename)):
                    matching_files.append(os.path.join(root, filename))
    return matching_files


path = 'path/to/folder'
keyword = '.mp3'
paths = find_files_with_keyword(path, keyword)

output_list = []
for p in paths:
    t = recognize(p)
    output_list.append(f"{get_filename_from_path(p)}\t{t}t\n")
    print(p, ":",t) # 結果の出力

# テキストへ書き込む
with open('output.txt', 'w') as f:
    f.writelines(output_list)

プログラム全体の解説

今回のプログラムは、指定されたフォルダ内にあるキーワードを含んだ音声ファイルを読み込み、文字起こしを行い、結果をテキストファイルに書き出すためのコードです。

関数化している部分は後述します。まずはプログラムの全体を確認します。

path = 'path/to/folder'
keyword = '.mp3'
paths = find_files_with_keyword(path, keyword)

最初のブロックでは、読み込むフォルダのパスと、読み込むファイルのキーワードを指定しています。キーワードは拡張子に限らず、「eigo」のようにファイル名の一部を指定することもできます。後述するfind_files_with_keyword()関数を使用して、指定されたフォルダ内のキーワードを含むファイルパスをリストとして取得します。この関数により、読み込むファイルの一覧を取得することができます。

output_list = []
for p in paths:
    t = recognize(p)
    output_list.append(f"{get_filename_from_path(p)}\t{t}t\n")
    print(p, ":",t) # 結果の出力

指定されたフォルダ内に含まれる音声ファイルの文字起こしを行います。先程取得したファイルパスのリスト(paths)をforループで順番に読み込み、recognize()関数(解説は後述)を使用して、各音声ファイルの文字起こしを行います。結果をoutput_listリストに格納しています。各要素は、ファイル名と文字起こしの結果がタブ(\t)区切りで格納されています。

print関数で結果を出力しているので、実行中にも文字起こしの結果を確認することができます。

# テキストへ書き込む
with open('output.txt', 'w') as f:
    f.writelines(output_list)

最後に、結果をテキストファイルに書き出しています。with文を使用して、書き込みモードでファイルを開き、output_listリストの要素を一括して書き出しています。書き出しファイル名は、'output.txt'としています。

関数の解説

音声ファイルの文字起こしを行うコードは関数化しています。これにより、より簡潔なコードで処理を行うことができます。

文字起こしを行う関数

def recognize(file):
    #音声ファイルを読み込み
    wav = AudioSegment.from_file(file, format="mp3").export(io.BytesIO(), format="wav")
    audio_file = sr.AudioFile(wav)

    #音声認識オブジェクトを作成
    r = sr.Recognizer()

    #音声ファイルをオーディオソースとして読み込み
    with audio_file as source:
        audio = r.record(source)

    #音声認識を実行
    # text = r.recognize_google(audio, language='en-US')
    text = r.recognize_sphinx(audio, language='en-US')

    return text

以下、関数内部の処理について解説します。

指定されたファイルをAudioSegmentクラスを使用して読み込み、MP3形式からWAV形式に変換します。変換後のデータはBytesIOオブジェクトに格納されます。その後、speech_recognitionライブラリのAudioFileクラスに、WAV形式のデータを渡して、音声認識を行うための準備を行います。

そして、speech_recognitionライブラリのRecognizerクラスのインスタンスを作成します。これは、音声認識を実行するためのオブジェクトです。

次に、AudioFileクラスを使用して、音声ファイルをオーディオソースとして読み込みます。そして、Recognizerオブジェクトのrecord()メソッドを使用して、オーディオソースから音声データを取得します。これにより、音声データを認識可能な形式に変換することができます。

最後に、Recognizerオブジェクトのrecognize_sphinx()メソッドを使用して、音声データの認識を実行します。このメソッドは、音声認識エンジンのひとつであるSphinxを使用して、音声データをテキストデータに変換します。認識したテキストデータを戻り値として返します。

上記のコード上ではコメントアウトしていますが、recognize_google()メソッドは、Googleの音声認識APIを使用して、音声ファイルを文字起こしするためのメソッドです。このメソッドを使用する場合、以下のことに注意する必要があります。

  • データ送信の可能性:Googleの音声認識APIを使用する場合、音声データがGoogleに送信されるため、プライバシーに関する問題が発生する可能性があります。Googleは音声データの一部を収集することがありますので、個人情報が含まれている場合は特に注意が必要です。

  • 使用回数の制限:Googleの音声認識APIを使用する場合、一定の回数の使用制限があります。使用回数が制限を超えると、APIを使用できなくなるため、注意が必要です。

今回は、業務上の都合で、外部へデータを送信することがない方法を採用し、recognize_sphinx()メソッドを使用しています。

ファイルの一覧を取得する関数

def find_files_with_keyword(path, keyword):
    matching_files = []
    for root, dir, files in os.walk(path):
        for filename in files:
            if keyword in filename:
                if os.path.isfile(os.path.join(root, filename)):
                    matching_files.append(os.path.join(root, filename))
    return matching_files

このプログラムは、指定されたパス以下のすべてのファイルを探索し、ファイル名に指定されたキーワードが含まれているファイルのパスをリストに格納する関数です。

最初にキーワードにマッチするファイルのパスを格納するリストを初期化します。

os.walk()関数を使用して、指定されたパス以下のすべてのフォルダとファイルを順番に取得します。

各フォルダ内のファイルリスト(files)をforループで順番に取得します。各ファイル名に、指定されたキーワードが含まれているかどうかを判定します。

各ファイルが実際にファイルであることを確認します。os.path.isfile()関数を使用して、ファイルかどうかを判定します。

最後にキーワードにマッチするファイルのパスを格納したリストを、戻り値として返します。

パスからファイル名だけを取り出す関数

def get_filename_from_path(path):
    # パスからファイル名だけを取得する
    filename = os.path.basename(path)
    return filename

指定されたファイルパスから、ファイル名のみを取得します。os.path.basename()関数を使用して、ファイルパスからファイル名を抽出し、filename変数に格納します。ファイル名のみを格納した変数を、戻り値として返します。

まとめ

今回の記事では、Pythonを使って音声ファイルの文字起こしを行う方法について解説しました。Pythonを使って音声ファイルの文字起こしを行い、認識結果をテキストファイルに書き出し事前にチェックを行うことで、成果物のエラーを少しでも減らした状態で確認作業を進めることができます。

今回の案件では、必ず人間が最終的な確認を行う必要がありました。しかし、事前の準備によってミスが減った状態であれば、人間が最終的な確認を行った際により精度の高い成果物を納品することができます。


この記事が気に入ったらサポートをしてみませんか?