たまには純粋なハウツーでも書くかと思った。といっても今までの記事のまとめみたいなもんだけど。
まぁこれをされると動画作成者はつらいかもしれんのだが、そうは言ってもこちらの人生にも限りがある。音声だけでいいものは音声でいいのだし、もっといえば正直文字で読みたい。倍速再生だのなんだと言っても、文字より高いタイパなどない。コピーされるからテキストにいかないのはわかるけどさ。このブログもコピーされまくり学習されまくりbot来訪しまくりだよ。
文字起こししたものは、LLMで読みやすくなるように見だしをつけたり、書き言葉になおしたり、成功率高いわけじゃないけど対談ものなら「話者」を付与するとかもさせられる。なんならTTSで再び音声化もできる(意味不明)。
全体のやること
やることは結局以下となる。
- YouTubeから動画を
yt-dlpでmp3としてダウンロードする - mp3を
whisper.cppを使って文字起こしする
つまりこれらのソフトウェアを使える環境が必要。持続性に関してはほぼyt-dlpがいつまで通用するのが問題だと思う。
環境
- コマンド実行として基本的にUNIXライクな環境
- Windowsもできるがちょっとたるい
- whisper.cppを動かせる程度のマシン
- そんなに性能いらないはず。AppleSiliconなMacで十分と思う
- 時間かけてもいいなら割とそこらへんのPCでいいかもしれん
- そんなに性能いらないはず。AppleSiliconなMacで十分と思う
自分の環境
- M2 Pro Mac mini
- 12CPU, 19GPU
- 32GB RAM
- GMKtec EVO-X2
- Ryzen AI Max+ 395
- 128GB RAM
- Windows 11
- CPUだけならWSL2で構築すれば楽だけど、GPU使うならネイティブの環境でやったほうが楽じゃないかな
手順という名のリンク集
yt-dlpで落とす
じゃあ具体的に手順なんだけれど、以前AIに書かせた手順書を投げっぱなしジャーマン。
さすがにこれだけだとなんなので、コード例。まぁほとんどこれだけでよいので。
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はじめビッグテックだから、個人的には抵抗したい。
まーそれとは別に、音声って不思議なもんで、書き言葉とは根本から違うらしく、スタイルだけ書き言葉になおしても、そのときに死ぬ何かはあるように思う。なのでまぁ聞きたい言葉は、聞けるなら聞いたほうがいいんじゃないかな。

コメント