Whisperとdeep-translator:を使用したYouTube動画の高精度文字起こしと翻訳

# WhisperとGoogle ColabでYouTube音声の文字起こしと日本語翻訳を行う方法

今回は、**Whisperモデル**と**Google Colab**を使用して、YouTubeの音声を文字起こしし、日本語に翻訳する方法を解説します。特に、英語と日本語のテキストを見やすく表示する方法に焦点を当てます。

## 目次

1. [はじめに](#はじめに)
2. [環境のセットアップ](#環境のセットアップ)
   - [Google ColabでのGPU設定](#google-colabでのgpu設定)
   - [必要なライブラリのインストール](#必要なライブラリのインストール)
3. [コードの説明](#コードの説明)
   - [ライブラリのインポート](#ライブラリのインポート)
   - [YouTubeから音声をダウンロードする関数](#youtubeから音声をダウンロードする関数)
   - [テキストを翻訳する関数](#テキストを翻訳する関数)
   - [音声を文字起こしし、翻訳する関数](#音声を文字起こしし翻訳する関数)
   - [メイン関数](#メイン関数)
4. [結果の表示とダウンロード](#結果の表示とダウンロード)
5. [完全なコード](#完全なコード)
6. [まとめ](#まとめ)

## はじめに

動画の音声を文字起こしし、日本語に翻訳したいと思ったことはありませんか？この記事では、Google ColabとWhisperモデルを使って、それを簡単に実現する方法を紹介します。

- **Whisperモデル**: OpenAIが開発した高精度な音声認識モデルです。
- **Google Colab**: ブラウザ上でPythonコードを実行できるクラウドサービスです。

## 環境のセットアップ

### Google ColabでのGPU設定

1. **Google Colabにアクセス**し、新しいノートブックを作成します。
2. 上部メニューの「**ランタイム**」をクリックし、「**ランタイムのタイプを変更**」を選択します。
3. 「**ハードウェアアクセラレータ**」のドロップダウンから「**GPU**」を選択し、「**保存**」をクリックします。

### 必要なライブラリのインストール

以下のコードをセルに入力して実行し、必要なライブラリをインストールします。

```python
!pip install yt-dlp openai-whisper deep-translator
```

- `yt-dlp`: YouTubeから音声をダウンロードするためのライブラリ。
- `openai-whisper`: Whisperモデルを使用するためのライブラリ。
- `deep-translator`: テキストの翻訳を行うためのライブラリ。

## コードの説明

### ライブラリのインポート

```python
import whisper
import os
import yt_dlp
from deep_translator import GoogleTranslator
import time
```

### YouTubeから音声をダウンロードする関数

```python
def download_youtube_audio(youtube_url, output_path='./'):
    ydl_opts = {
        'format': 'bestaudio/best',
        'postprocessors': [{
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'mp3',
            'preferredquality': '192',
        }],
        'outtmpl': f'{output_path}/%(title)s.%(ext)s',
    }

    try:
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            print(f"Downloading audio from: {youtube_url}")
            info = ydl.extract_info(youtube_url, download=True)
            filename = ydl.prepare_filename(info)
            filename = filename.rsplit('.', 1)[0] + '.mp3'
            print(f"Download completed: {filename}")
            return filename
    except Exception as e:
        print(f"An error occurred during download: {str(e)}")
        return None
```

- **機能**: YouTubeのURLから音声をMP3形式でダウンロードします。

### テキストを翻訳する関数

```python
def translate_text(text, target_language='ja'):
    try:
        translated = GoogleTranslator(source='auto', target=target_language).translate(text)
        return translated
    except Exception as e:
        print(f"翻訳中にエラーが発生しました: {e}")
        return None
```

- **機能**: 与えられたテキストを指定した言語に翻訳します。

### 音声を文字起こしし、翻訳する関数

```python
def transcribe_and_translate(audio_file_path, target_language="ja"):
    try:
        print("Whisperモデルをロード中...")
        model = whisper.load_model("large")  # モデルサイズは必要に応じて変更可能

        print(f"{audio_file_path} の文字起こしを実行中...")
        result = model.transcribe(audio_file_path, language='en')

        print("文字起こし結果を整形中...")
        segments = result['segments']
        formatted_transcript = ''
        translated_transcript = ''
        for i, segment in enumerate(segments):
            english_text = segment['text'].strip()
            formatted_transcript += english_text + '\n'  # 段落ごとの改行を1行に

            print(f"セグメント {i+1}/{len(segments)} を翻訳中...")
            # 各セグメントを個別に翻訳
            translated_text = translate_text(english_text, target_language)
            if translated_text is None:
                print("一部のテキストの翻訳に失敗しました。")
                translated_text = ''
            translated_transcript += translated_text + '\n'  # 改行を1行に
            time.sleep(1)  # レート制限を避けるための待機

        full_transcript = formatted_transcript.strip()
        full_translation = translated_transcript.strip()

        base_name = os.path.basename(audio_file_path).rsplit('.', 1)[0]
        output_filename = f"transcription_and_translation_{base_name}.txt"
        with open(output_filename, "w", encoding='utf-8') as f:
            f.write("=== 英語の文字起こし ===\n")
            f.write(full_transcript + "\n")
            f.write(f"=== 日本語訳 ===\n")
            f.write(full_translation)

        print(f"文字起こしと翻訳結果を {output_filename} に保存しました")
        return output_filename
    except Exception as e:
        print(f"エラーが発生しました: {e}")
        return None
```

- **機能**:
  - 音声ファイルをWhisperモデルで文字起こし。
  - 文字起こし結果をセグメントごとに翻訳。
  - 英語と日本語のテキストをそれぞれ段落ごとに整理。

### メイン関数

```python
def main():
    youtube_url = input("YouTubeのURLを入力してください: ")

    audio_file = download_youtube_audio(youtube_url)

    if audio_file:
        translated_file = transcribe_and_translate(audio_file)

        if translated_file:
            print(f"処理が完了しました。結果は {translated_file} に保存されています。")
        else:
            print("文字起こしと翻訳に失敗しました。")
    else:
        print("音声のダウンロードに失敗しました。")

if __name__ == "__main__":
    main()
```

- **機能**: ユーザーからYouTubeのURLを取得し、一連の処理を実行します。

## 結果の表示とダウンロード

以下のコードを実行すると、結果を表示し、ローカルにダウンロードできます。

```python
from google.colab import files
import glob
import os

result_files = glob.glob("transcription_and_translation_*.txt")
if result_files:
    result_file = max(result_files, key=os.path.getctime)

    print(f"\nファイル '{result_file}' の内容:")
    print("-" * 80)
    with open(result_file, 'r', encoding='utf-8') as f:
        print(f.read())
    print("-" * 80)

    files.download(result_file)
else:
    print("結果ファイルが見つかりません。")
```

## 完全なコード

以下に、上記のコードをすべてまとめた完全なコードを示します。Google Colabのセルにコピーしてそのまま実行できます。

```python
# 必要なライブラリのインストール
!pip install yt-dlp openai-whisper deep-translator

# ライブラリのインポート
import whisper
import os
import yt_dlp
from deep_translator import GoogleTranslator
import time

def download_youtube_audio(youtube_url, output_path='./'):
    ydl_opts = {
        'format': 'bestaudio/best',
        'postprocessors': [{
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'mp3',
            'preferredquality': '192',
        }],
        'outtmpl': f'{output_path}/%(title)s.%(ext)s',
    }

    try:
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            print(f"Downloading audio from: {youtube_url}")
            info = ydl.extract_info(youtube_url, download=True)
            filename = ydl.prepare_filename(info)
            filename = filename.rsplit('.', 1)[0] + '.mp3'
            print(f"Download completed: {filename}")
            return filename
    except Exception as e:
        print(f"An error occurred during download: {str(e)}")
        return None

def translate_text(text, target_language='ja'):
    try:
        translated = GoogleTranslator(source='auto', target=target_language).translate(text)
        return translated
    except Exception as e:
        print(f"翻訳中にエラーが発生しました: {e}")
        return None

def transcribe_and_translate(audio_file_path, target_language="ja"):
    try:
        print("Whisperモデルをロード中...")
        model = whisper.load_model("large")  # モデルサイズは必要に応じて変更可能

        print(f"{audio_file_path} の文字起こしを実行中...")
        result = model.transcribe(audio_file_path, language='en')

        print("文字起こし結果を整形中...")
        segments = result['segments']
        formatted_transcript = ''
        translated_transcript = ''
        for i, segment in enumerate(segments):
            english_text = segment['text'].strip()
            formatted_transcript += english_text + '\n'  # 改行を1行に

            print(f"セグメント {i+1}/{len(segments)} を翻訳中...")
            # 各セグメントを個別に翻訳
            translated_text = translate_text(english_text, target_language)
            if translated_text is None:
                print("一部のテキストの翻訳に失敗しました。")
                translated_text = ''
            translated_transcript += translated_text + '\n'  # 改行を1行に
            time.sleep(1)  # レート制限を避けるための待機

        full_transcript = formatted_transcript.strip()
        full_translation = translated_transcript.strip()

        base_name = os.path.basename(audio_file_path).rsplit('.', 1)[0]
        output_filename = f"transcription_and_translation_{base_name}.txt"
        with open(output_filename, "w", encoding='utf-8') as f:
            f.write("=== 英語の文字起こし ===\n")
            f.write(full_transcript + "\n")
            f.write(f"=== 日本語訳 ===\n")
            f.write(full_translation)

        print(f"文字起こしと翻訳結果を {output_filename} に保存しました")
        return output_filename
    except Exception as e:
        print(f"エラーが発生しました: {e}")
        return None

def main():
    youtube_url = input("YouTubeのURLを入力してください: ")

    audio_file = download_youtube_audio(youtube_url)

    if audio_file:
        translated_file = transcribe_and_translate(audio_file)

        if translated_file:
            print(f"処理が完了しました。結果は {translated_file} に保存されています。")
        else:
            print("文字起こしと翻訳に失敗しました。")
    else:
        print("音声のダウンロードに失敗しました。")

if __name__ == "__main__":
    main()
```

```python
# 結果の表示とダウンロード

from google.colab import files
import glob
import os

result_files = glob.glob("transcription_and_translation_*.txt")
if result_files:
    result_file = max(result_files, key=os.path.getctime)

    print(f"\nファイル '{result_file}' の内容:")
    print("-" * 80)
    with open(result_file, 'r', encoding='utf-8') as f:
        print(f.read())
    print("-" * 80)

    files.download(result_file)
else:
    print("結果ファイルが見つかりません。")
```

## まとめ

この記事では、WhisperモデルとGoogle Colabを使用して、YouTubeの音声を文字起こしし、日本語に翻訳する方法を解説しました。英語と日本語のテキストを見やすく整理することで、長いテキストでも読みやすくなります。