YouTubeの動画を文字起こしする手順とスクリプト (yt-dlp + whisper.cpp)

たまには純粋なハウツーでも書くかと思った。といっても今までの記事のまとめみたいなもんだけど。

まぁこれをされると動画作成者はつらいかもしれんのだが、そうは言ってもこちらの人生にも限りがある。音声だけでいいものは音声でいいのだし、もっといえば正直文字で読みたい。倍速再生だのなんだと言っても、文字より高いタイパなどない。コピーされるからテキストにいかないのはわかるけどさ。このブログもコピーされまくり学習されまくりbot来訪しまくりだよ。

文字起こししたものは、LLMで読みやすくなるように見だしをつけたり、書き言葉になおしたり、成功率高いわけじゃないけど対談ものなら「話者」を付与するとかもさせられる。なんならTTSで再び音声化もできる(意味不明)。

目次

全体のやること

やることは結局以下となる。

  1. YouTubeから動画をyt-dlpでmp3としてダウンロードする
  2. mp3をwhisper.cppを使って文字起こしする

つまりこれらのソフトウェアを使える環境が必要。持続性に関してはほぼyt-dlpがいつまで通用するのが問題だと思う。

環境

  • コマンド実行として基本的にUNIXライクな環境
    • Windowsもできるがちょっとたるい
  • whisper.cppを動かせる程度のマシン
    • そんなに性能いらないはず。AppleSiliconなMacで十分と思う
      • 時間かけてもいいなら割とそこらへんのPCでいいかもしれん

自分の環境

  1. M2 Pro Mac mini
    • 12CPU, 19GPU
    • 32GB RAM
  2. GMKtec EVO-X2
    • Ryzen AI Max+ 395
    • 128GB RAM
    • Windows 11
      • CPUだけならWSL2で構築すれば楽だけど、GPU使うならネイティブの環境でやったほうが楽じゃないかな

手順という名のリンク集

yt-dlpで落とす

じゃあ具体的に手順なんだけれど、以前AIに書かせた手順書を投げっぱなしジャーマン。

動画ダウンロードの定番──yt-dlpという万能ツール

さすがにこれだけだとなんなので、コード例。まぁほとんどこれだけでよいので。

yt-dlp -x --audio-format mp3 'https://www.youtube.com/watch?v=ysG84McAKUQ'

これによって総務省の林総務大臣の記者会見が聞けるぞ。

yt-dlpはちょこちょこと仕様が変わる……というよりプラットフォームの仕様が変わるのでそれに併せてソフトウェアも変わるというべきだが、いつまで続くかなぁ。

whisper.cppで文字起こしする

ここからさらに各環境における手順リンクに飛べる。まるで役所のようだ。そしてこの記事では、だいたいどれくらいの速度でやれるかも書いているよ。

(おまけ) 一括で処理するbashスクリプト

URLを指定して、文字起こししたtxtに変換するまでの処理のスクリプト。だいたいAIが書いた。

以下のコードについて、必要なところを改変する。

#!/bin/bash
# 必要なもの
# - ffmpeg
# - yt-dlp (URL モード用)
# - whisper-cli をインストールして、whisper_dir を設定

set -euo pipefail

original_cwd="${PWD}"

usage() {
  echo "Usage: $(basename "$0") [-u URL] [audio-file]" >&2
  exit 1
}

url=""
while getopts ":u:h" opt; do
  case "${opt}" in
    u)
      url="${OPTARG}"
      ;;
    h)
      usage
      ;;
    \?)
      echo "Unknown option: -${OPTARG}" >&2
      usage
      ;;
    :)
      echo "Option -${OPTARG} requires an argument." >&2
      usage
      ;;
  esac
done
shift $((OPTIND - 1))

input_path=""

if [[ -n "${url}" ]]; then
  if [[ $# -ne 0 ]]; then
    echo "Do not mix -u with a positional audio file." >&2
    usage
  fi
else
  if [[ $# -ne 1 ]]; then
    usage
  fi
  input_path="$1"
fi

wav_file=""
tmp_dir=""

cleanup() {
  if [[ -n "${wav_file:-}" ]]; then
    rm -f -- "${wav_file}"
  fi
  if [[ -n "${tmp_dir:-}" ]]; then
    rm -rf -- "${tmp_dir}"
  fi
}
trap cleanup EXIT

if [[ -n "${url}" ]]; then
  if ! command -v yt-dlp >/dev/null 2>&1; then
    echo "yt-dlp not found in PATH." >&2
    exit 1
  fi
  tmp_dir="$(mktemp -d)"
  download_template="${tmp_dir}/%(title)s.%(id)s.%(ext)s"
  yt-dlp --no-playlist --extract-audio --audio-format mp3 --audio-quality 0 \
    -o "${download_template}" "${url}"
  input_path="$(find "${tmp_dir}" -maxdepth 1 -type f -name '*.mp3' -print -quit)"
  if [[ -z "${input_path}" ]]; then
    echo "Failed to locate downloaded audio file." >&2
    exit 1
  fi
fi

expand_user() {
  if [[ $1 == "~" || $1 == ~/* ]]; then
    printf '%s\n' "${HOME}${1#\~}"
  else
    printf '%s\n' "$1"
  fi
}

input_path="$(expand_user "${input_path}")"

if [[ "${input_path}" == /* ]]; then
  i_aud_file="${input_path}"
else
  input_dir="$(dirname -- "${input_path}")"
  input_base="$(basename -- "${input_path}")"
  i_aud_file="$(cd "${input_dir}" && pwd)/${input_base}"
fi

wav_file="${i_aud_file%.*}.wav"

if [[ -n "${url}" ]]; then
  output_prefix="${original_cwd}/$(basename -- "${i_aud_file%.*}")"
else
  output_prefix="${i_aud_file%.*}"
fi

whisper_dir="${HOME}/ghq/github.com/ggml-org/whisper.cpp"
whisper_cmd="./build/bin/whisper-cli"
whisper_model="./models/ggml-large-v3.bin"

ffmpeg -i "${i_aud_file}" -ar 16000 -ac 1 -c:a pcm_s16le "${wav_file}"
cd "${whisper_dir}"
"${whisper_cmd}" -m "${whisper_model}" -l ja -f "${wav_file}" --output-txt --output-file "${output_prefix}"

echo "Transcription saved to ${output_prefix}.txt"

改変ポイント

  • whisper_dirのパス
  • 112行目の ja は日本語設定なのでここんところオートにするかどうかはモノ次第

使い方。ファイルを保存したい場所でスクリプト実行する。

./audio2txt.sh -u https://www.youtube.com/watch?v=ysG84McAKUQ

カレントディレクトリにファイルを出力する。

-uをつけない場合は、mp3ファイルを指定することで、yt-dlpの処理をスキップして音声を直接文字起こしする。

所感

ハッキリ言ってyt-dlpがいつまで使えるかにかかっている。頑張ってyt-dlpコミュニティ🥺

youtube-dlからお世話になっているけれど、あまり広がり過ぎると潰される圧力も高まるし、難しいところだ。しかしそうは言っても、Webの情報がYouTubeに吸われているような構造があって、本来ならばテキストで表現されるべきものまで全部YouTubeにいってしまっているような危機感がある。この構造を作ったのは他ならぬGoogleはじめビッグテックだから、個人的には抵抗したい。

まーそれとは別に、音声って不思議なもんで、書き言葉とは根本から違うらしく、スタイルだけ書き言葉になおしても、そのときに死ぬ何かはあるように思う。なのでまぁ聞きたい言葉は、聞けるなら聞いたほうがいいんじゃないかな。

この記事をいいなと思っていただけた方、よければ高評価・チャンネル登録……はないので、コメント・SNSでシェア・ブックマーク、RSSフィード登録を、よろしくお願い致します。

コメント

コメントする

目次