1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

アニメで語学学習したい! 動画のテロップ自動書き出しプログラム

1
Posted at

概要

動画の字幕をテキストに書き起こすプログラムを書きました。

動機

海外アニメで外国語を勉強したい!

「日本のアニメで日本語を勉強した」って言う外国人のかた、多くいらっしゃいますよね。
じゃあ、逆もできるでしょう!
海外アニメを現地語で理解できるようになれば、学習のモチベーションになりそう!
……と思いたったものの、まあ、難しいです。

例えば中国語の場合。
知らない漢字が出てきて、読みがわからないから辞書で引けない。入力ができない。

これ、全部テキスト化できないかな……。そうすれば機械翻訳もしやすいのに。

……と思ったのがきっかけです。

↑ 例えばこんな感じ。現地語字幕がついていると嬉しいですね。

やったこと

  • 動画の字幕を読み取って、テキスト化するプログラムを作った!

利用した技術

  • OCR:Tesseract(テッセラクト)
    • オープンソースのOCR(文字認識)ツール。
      ローカルで動くので、API制限を気にしなくていいのが良いところ。
      ただし精度はそこまで高くない。
  • 言語:PHP
  • 画像処理:ffmpeg
  • データ蓄積:SQLite

コード

transcriber.php
<?php
// 設定 ================================================================
$lang = 'jpn';     // OCRで読み取る言語(日本語:jpn)
$fps = 1;          // 画像の切り出しのFPS
$bottom = 0.1;     // 画像の下側の切り出しの割合
$threshold = 220;  // 画像二値化の閾値

// ビデオファイルの存在チェック ================================================================
$videoFile = $_SERVER['argv'][1];
if (!file_exists($videoFile)) {
    echo "--- Video File Not Found ---\n";
    return;
}

// SQLiteの準備 ================================================================
$dbFile = 'database.sqlite';
if (file_exists($dbFile)) {
    unlink($dbFile); // 初期化するため、古いファイルを削除
}
$db = new PDO("sqlite:$dbFile");
$db->exec("CREATE TABLE IF NOT EXISTS transcripts (id INTEGER PRIMARY KEY, timestamp TEXT, content TEXT)");

// 画像の切り出し ================================================================
echo "--- Begin Extracting Frames ---\n";

$frameDir = 'frames/';
mkdir($frameDir, 0777, true);

$crop = "iw:ih*$bottom:0:ih-ih*$bottom"; // 下部分(割合:$bottom)を切り出し
$filters = "format=gray,lutyuv=y='if(gt(val,$threshold),255,0)',negate"; // 閾値:$threshold で二値化、反転

$ffmpegCmd = "ffmpeg -i " . escapeshellarg($videoFile) . " -vf \"fps=$fps,crop=$crop,$filters\" {$frameDir}frame_%04d.png";
shell_exec($ffmpegCmd);

// 画像の読み取り(OCR) ================================================================
echo "--- Begin OCR Process ---\n";
$images = glob($frameDir . "*.png");
sort($images);

foreach ($images as $index => $imagePath) {
    // タイムスタンプの計算
    $seconds = $index / $fps;
    $timestamp = sprintf('%02d:%02d.%01d', floor($seconds / 60), floor($seconds) % 60, ($seconds * 10) % 10);

    echo "Processing [$timestamp] $imagePath ... ";

    // Tesseract実行
    $tesseractCmd = "tesseract " . escapeshellarg($imagePath) . " stdout -l " . $lang . " --psm 6";
    $text = shell_exec($tesseractCmd);
    $text = trim($text);
    $text = str_replace(["\r", "\n", " "], '', $text);

    // SQLiteにテキストを保存
    if (!empty($text)) {
        $stmt = $db->prepare("INSERT INTO transcripts (timestamp, content) VALUES (?, ?)");
        $stmt->execute([$timestamp, $text]);
        echo "Success.\n";
    } else {
        echo "No text found.\n";
    }

    // 処理が終わった画像を削除
    unlink($imagePath);
}

// テキストの出力 ================================================================
echo "--- Begin Concatenating Text ---\n";

$stmt = $db->query("SELECT * FROM transcripts ORDER BY id ASC");
$fullText = "";
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    $fullText .= "[{$row['timestamp']}] {$row['content']}\n";
}

file_put_contents('transcript.txt', $fullText);

echo "--- Finished ---\n";

使い方

動画ファイルをローカルにダウンロードしてきて(権利関係に十分ご注意ください)、

$ php transcriber.php ./path/to/video.mp4

のように実行すれば大丈夫です!

利用に際し

利用・改変はご自由にどうぞ!
PHPのインストールとSQLiteの有効化、Tesseractとffmpegのインストールが必要です。

結果(以下余談)

検証に使用した動画は https://www.youtube.com/watch?v=9CvIEF5lsng です。

プログラムの出力

プログラムの出力結果の抜粋です。

[01:52.0] 在風和日施的亞甸大陸上
[01:56.0] 居住著一群以探集木天鞭和碾物維生的嘶貓一族
[02:00.0] 他們每天過著自給自足,快樂又和平的生活
[02:06.0] 但是、有一天
[02:08.0] 亞甸大陸上突然出現三個邪惡又恐怖的族群
[02:12.0] 分別是'磺龍族、麗猴族以及野狗族
[02:20.0] 他俏不斷侵略著嘶嘶們的家園
[02:22.0] 並抓走了許多喵喵
[02:24.0] 誤他們每天都活在不安與害怕之中
[02:28.0] 直到某一天、手持喵神器的三位喵史出現
[02:32.0] 他們吏退了敵人並救回被抓走的同伴
[02:36.0] 而這三位英雄分別是
[02:38.0] 深紅鐮刀的持有者一黑貓九藏
[02:40.0] 手握震晶的磺界帝王一咐磺帝
[02:44.0] 天菜妻的主人、圳花村村長一晴信
[02:48.0] 他們凝蒜了散落在世界各地的啼嘶
[02:52.0] 台敢的對抗敵人
[02:54.0] 並領巡著喵喵們重新建立家園
[02:58.0] 有了他們的守廬
[03:00.0] 喵喵們很快就底復了以往和平的生活
[03:06.0] 就是流傳在亞甸大陸上、,有關我們喵喵一族的歷史

手での書き起こし(比較用)

在風和日麗的亞甸大陸上
居住著一群以採集木天蓼和礦物維生的喵喵一族
他們每天過著自給自足,快樂又和平的生活
但是,有一天...
亞甸大陸上突然出現三個邪惡又恐怖的族群
分別是,魔龍族、魔猴族以及野狗族
他們不斷侵略著喵喵們的家園
並抓走了許多喵喵
讓他們每天都活在不安與害怕之中
直到某一天,手持喵神器的三位喵喵出現
他們擊退了敵人並救回被抓走的同伴
而這三位英雄分別是
深紅鐮刀的持有者―黑貓九藏
手握雷晶的魔界帝王―喵魔帝
天叢雲的主人,櫻花村村長―晴信
他們凝聚了散落在世界各地的喵喵
勇敢的對抗敵人
並領導者喵喵們重新建立家園
有了他們的守護
喵喵們很快就恢復了一往和平的生活
而這單段故事
就是流傳在亞甸大路上,有關我們喵喵一族的歷史

OCRそれ自体の制度は高くありませんが、目的は達成できました!

最後に

APIとつなげれば、精度高く読み取れるかもしれないですし、
自動翻訳もできそうですね!

プログラミングも、外国語も、どちらも勉強頑張りましょう!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?