はじめに
最近英語を勉強してますが、英語の映画やアニメに英語字幕がないことが多いです。英語学習のため、あるフォルダ内の全てのビデオに一括で字幕を生成したいと考えています。そこで「whisper」を見つけて試してみました、試したところ英語学習には全く問題ありません。
Whisper
OpenAIのWhisperは、高精度で多言語に対応した自動音声認識(ASR)システムです。このシステムは、大規模なデータセットを用いた深層学習によって訓練されており、様々な言語やアクセント、さらにはノイズが含まれる環境下でも効果的に音声をテキストに変換する能力を持っています。
実践
import whisper
import datetime
from moviepy.editor import VideoFileClip, AudioFileClip
import srt
from pathlib import Path
import os
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "max_split_size_mb:50"
def generate_srt(transcription):
"""Generate SRT subtitles from transcription."""
subtitles = []
for segment in transcription["segments"]:
start = datetime.timedelta(seconds=segment["start"])
end = datetime.timedelta(seconds=segment["end"])
text = segment["text"]
subtitles.append(srt.Subtitle(index=len(subtitles) + 1, start=start, end=end, content=text))
return srt.compose(subtitles)
def extract_audio(video_path, audio_path="temp_audio.wav"):
"""Extract audio from video."""
video_clip = VideoFileClip(video_path)
video_clip.audio.write_audiofile(audio_path)
return audio_path
def split_audio(audio_path, num_segments=4):
"""Split the audio into multiple segments."""
audio_clip = AudioFileClip(audio_path)
duration = audio_clip.duration
segment_duration = duration / num_segments
segments = []
for i in range(num_segments):
start = i * segment_duration
end = min((i + 1) * segment_duration, duration)
segment = audio_clip.subclip(start, end)
segment_path = f"temp_segment_{i}.wav"
segment.write_audiofile(segment_path)
segments.append(segment_path)
return segments
def transcribe_segment(segment_path, model):
"""Transcribe a single audio segment."""
result = model.transcribe(segment_path,language="en")
return result
def generate_sub(transcription):
"""Generate SUB subtitles from transcription."""
subtitles = []
for segment in transcription["segments"]:
start = segment["start"]
end = segment["end"]
text = segment["text"]
subtitles.append(f"{start:.2f} --> {end:.2f}\n{text}\n\n")
return "".join(subtitles)
def main(folder_path, output_folder_path, num_segments=1):
Path(output_folder_path).mkdir(parents=True, exist_ok=True)
video_files = [f for f in Path(folder_path).glob("**/*") if f.is_file() and f.suffix.lower() in ['.mp4', '.mkv', '.avi', '.mov', '.flv', '.wmv']]
model = whisper.load_model("large-v3", device="cuda")
for video_file in video_files:
video_path = str(video_file)
audio_path = extract_audio(video_path)
transcription = transcribe_segment(audio_path, model)
subtitles = generate_srt(transcription)
output_sub_path = os.path.join(output_folder_path, video_file.stem + ".srt")
with open(output_sub_path, "w") as f:
f.write(subtitles)
# 使用例
folder_path = "./" # あなたの動画フォルダのパスに置き換えてください
output_folder_path = "./" # 出力字幕フォルダのパスに置き換えてください
main(folder_path, output_folder_path)
最後の一言
もしメモリが十分であれば、v3を使うのが最善です。私が「けいおん!」第1話の英語字幕を生成したとき、精度が明らかに向上しました。メモリが不足している場合は、量子化やより小さなモデルを検討するしかありません(8GBの現存ではv3は使用できません)。