"""
Whisperモデルを使用して音声ファイルを文字起こしするスクリプト。
コマンドライン引数で入力ファイル、出力ファイル、モデル名、言語などを指定し、
GPUの利用状況を確認しながら文字起こしを実行します。
結果は時間情報付きのテキストファイルと純粋なテキストファイルとして保存されます。
:doc:`transcribe_simple_usage`
"""
import os
import glob
import argparse
import whisper
import torch
pause = 0
[ドキュメント]
def terminate():
"""
スクリプトを終了する。
`pause` グローバル変数が真の場合、ユーザーにEnterキーの入力を要求してからスクリプトを終了します。
"""
if pause:
input("\nPress ENTER to terminate\n")
exit()
[ドキュメント]
def check_gpu():
"""
GPUの利用可能性を確認し、その情報を表示する。
PyTorchの `torch.cuda.is_available()` を使用してGPUが利用可能かチェックします。
利用可能な場合は、GPUの名前とCUDAのバージョンを表示します。
利用できない場合はその旨を通知します。
"""
if torch.cuda.is_available():
print(f"GPU name: {torch.cuda.get_device_name(0)}")
print(f"Torch CUDA ver: {torch.version.cuda}")
else:
print("No GPU available")
[ドキュメント]
def transcribe_audio(infile, outfile1, outfile2, model_name, lang, device_name = ""):
"""
指定された音声ファイルをWhisperモデルで文字起こしし、結果をファイルに保存する。
Whisperモデルをロードし、入力音声ファイルに対して文字起こしを実行します。
文字起こしの結果は、時間セグメント情報を含む形式と、純粋なテキスト形式の
2つのファイルに保存され、コンソールにも出力されます。
:param infile: (str) 文字起こしする音声ファイルのパス。
:param outfile1: (str) 時間範囲情報を含む文字起こし結果を保存する出力ファイルのパス。
:param outfile2: (str) 純粋な文字起こしテキストを保存する出力ファイルのパス。
:param model_name: (str) 使用するWhisperモデルの名前(例: 'base', 'small', 'medium', 'large')。
:param lang: (str) 音声の言語コード(例: 'JA'、'EN')。
:param device_name: (str, optional) 使用するGPU/CPUデバイス名。空文字の場合は自動選択(通常はGPU)。
"""
if device_name == "":
model = whisper.load_model(model_name)
else:
model = whisper.load_model(model_name, device = device_name)
print(f"Using device [{model.device}]")
# 文字起こし実行
result = model.transcribe(infile, language=lang, verbose=True)
# 結果をファイルに保存
print()
print(f"Save to [{outfile1}]")
with open(outfile1, "w", encoding="utf-8") as file:
for segment in result["segments"]:
start = segment["start"]
end = segment["end"]
text = segment["text"]
file.write(f"[{start:.2f} - {end:.2f}] {text}\n")
print(f"Save to [{outfile2}]")
with open(outfile2, "w", encoding="utf-8") as f:
f.write(result["text"])
# 結果を出力
print(result["text"])
[ドキュメント]
def main():
"""
スクリプトのメイン処理を実行する。
コマンドライン引数を解析し、指定された入力音声ファイル(ワイルドカードを含む)に対して
文字起こし処理を順次実行します。出力ファイル名が指定されていない場合は、
入力ファイル名に基づいて自動生成されます。処理開始前にGPUの利用状況を確認します。
"""
global pause
parser = argparse.ArgumentParser(description="Whisper音声文字起こしツール")
parser.add_argument("infile", type=str, help="入力音声ファイル名")
parser.add_argument("--outfile1", type=str, default = '', help="出力テキストファイル名 (時間範囲入り)")
parser.add_argument("--outfile2", type=str, default = '', help="出力テキストファイル名 (時間範囲なし)")
parser.add_argument("-m", "--model", type=str, default="base", help="Whisperモデル名 (default: base)")
parser.add_argument("-d", "--device", type=str, default="", help="GPU/CPUデバイス名 (default: '' for GPU)")
parser.add_argument("-l", "--lang", type=str, default="JA", help="使用言語 (default: JA)")
parser.add_argument("--pause", type=int, default=0, help="終了時にENTERキー入力を要求するか (デフォルト: 0)")
args = parser.parse_args()
pause = args.pause
# 文字起こし実行
files = glob.glob(args.infile)
print()
print(f"infile={args.infile}")
if len(files) == 0:
print("\nError: No file found.\n")
return
print(f" files:", files)
print(f"model={args.model}")
print(f"lang={args.lang}")
print(f"device={args.device}")
print()
check_gpu()
for f in files:
if args.outfile1 == "":
outfile1 = os.path.splitext(os.path.basename(f))[0] + "-time.txt"
else:
outfile1 = args.outfile1
if args.outfile2 == "":
outfile2 = os.path.splitext(os.path.basename(f))[0] + ".txt"
else:
outfile2 = args.outfile2
print(f"infile={f}")
print(f"outfile1={outfile1}")
print(f"outfile2={outfile2}")
transcribe_audio(f, outfile1, outfile2, args.model, args.lang, args.device)
if __name__ == "__main__":
main()
terminate()