Skip to content

Instantly share code, notes, and snippets.

@masakielastic
Last active July 2, 2025 13:17
Show Gist options
  • Save masakielastic/e5eeb54250626a436ad074f9248a0aa9 to your computer and use it in GitHub Desktop.
Save masakielastic/e5eeb54250626a436ad074f9248a0aa9 to your computer and use it in GitHub Desktop.
VOICEVOX HTTP API から音声を生成するコマンド

VOICEVOX HTTP API から音声を生成するコマンド

speak

chmod +x speak
./speak "こんにちは、音声合成の世界へようこそ" hello.wav
SPEAKER=3 speak "ありがとう" thanks.wav

list_speakers

chmod +x list_speakers
./list_speakers ずんだもん

BGM と同時に音声を再生する

speak おはよう 0.wav
speak こんにちは 1.wav
speak こんばんは 2.wav
timeout 10 paplay bgm.wav & \
paplay 0.wav; \
sleep 1; \
paplay 1.wav; \
sleep 1; \
paplay 2.wav

コマンドツールにしたもの

./play_with_bgm.sh ./voice/

文ごとに音声ファイルを生成するコマンド

echo "おはよう。こんにちは。こんばんは?" > test.txt
./generate_speech.sh test.txt output

指定したフォルダの音声ファイルを再生するコマンド

chmod +x play_all
./play_all output            # ffplay で再生
./play_all output aplay      # aplay に切り替え
#!/bin/bash
# speak - VOICEVOX で音声合成する CLI ツール
set -e
# チェック: 引数
if [ "$#" -lt 2 ]; then
echo "使い方: speak \"テキスト\" 出力ファイル.wav"
exit 1
fi
TEXT="$1"
OUTPUT="$2"
SPEAKER="${SPEAKER:-1}" # SPEAKER=3 のように環境変数で切り替え可能
# 音声合成パイプライン
echo "$TEXT" | \
xargs -0 -I{} curl -s -G -X POST "http://localhost:50021/audio_query" \
--data-urlencode "text={}" \
--data-urlencode "speaker=${SPEAKER}" | \
curl -s -X POST "http://localhost:50021/synthesis?speaker=${SPEAKER}" \
-H "Content-Type: application/json" \
--data-binary @- \
-o "$OUTPUT"
echo "✅ $OUTPUT を生成しました(text: \"$TEXT\")"
#!/bin/bash
# list_speakers - VOICEVOX の話者一覧を表示するツール(検索機能付き)
set -e
API_URL="http://localhost:50021/speakers"
if ! command -v jq >/dev/null; then
echo "❌ jq が必要です。sudo apt install jq などでインストールしてください。" >&2
exit 1
fi
# 全データ取得
json=$(curl -s "$API_URL")
# 検索語(引数)あり:フィルタ
if [ $# -gt 0 ]; then
QUERY="$1"
echo "$json" | jq -r --arg query "$QUERY" '
.[] | select(.name | test($query)) | .name as $name |
.styles[] | "\($name) / \(.name) : \(.id)"
'
else
# 検索語なし:全件表示
echo "$json" | jq -r '
.[] | .name as $name |
.styles[] | "\($name) / \(.name) : \(.id)"
'
fi
#!/bin/bash
set -e
# ✅ 引数チェック
if [ "$#" -ne 1 ]; then
echo "使い方: $0 <音声ファイルのあるフォルダ>"
exit 1
fi
VOICE_DIR="$1"
# ✅ フォルダが存在するかチェック
if [ ! -d "$VOICE_DIR" ]; then
echo "❌ 指定されたフォルダが存在しません: $VOICE_DIR"
exit 1
fi
# ✅ .wav ファイルの一覧を取得(昇順ソート)
FILES=($(find "$VOICE_DIR" -maxdepth 1 -type f -name '*.wav' | sort))
# ✅ 再生対象がない場合
if [ ${#FILES[@]} -eq 0 ]; then
echo "❌ フォルダに .wav ファイルが見つかりません: $VOICE_DIR"
exit 1
fi
# ✅ 合計再生時間を計算
total=0
for f in "${FILES[@]}"; do
dur=$(ffprobe -v error -show_entries format=duration \
-of default=noprint_wrappers=1:nokey=1 "$f")
total=$(echo "$total + $dur" | bc)
done
# ✅ +1秒の余裕を追加
DURATION=$(printf "%.0f\n" "$(echo "$total + 1" | bc)")
echo "▶ BGM 再生時間: ${DURATION} 秒"
echo "▶ 再生対象ファイル数: ${#FILES[@]}"
# ✅ BGM をバックグラウンド再生
timeout "$DURATION" paplay bgm.wav &
# ✅ 台詞を順に再生
for f in "${FILES[@]}"; do
echo "▶ 再生: $f"
paplay "$f"
sleep 0.5
done
#!/bin/bash
INPUT_FILE="$1"
OUTPUT_DIR="$2"
SPEAK_CMD="./speak"
if [ ! -f "$INPUT_FILE" ]; then
echo "❌ 入力ファイルが存在しません: $INPUT_FILE"
exit 1
fi
if [ ! -x "$SPEAK_CMD" ]; then
echo "❌ speak コマンドが実行できません: $SPEAK_CMD"
exit 1
fi
mkdir -p "$OUTPUT_DIR"
# 非破壊的に sd で文末区切りを改行に変換し、空行を除去
mapfile -t SENTENCES < <(cat "$INPUT_FILE" | sd '([。!?])' '$1\n' | grep -v '^\s*$')
i=1
for sentence in "${SENTENCES[@]}"; do
trimmed=$(echo "$sentence" | xargs) # ASCII空白の前後を除去(UTF-8安全)
[ -z "$trimmed" ] && continue
filename=$(printf "%s/%04d.wav" "$OUTPUT_DIR" "$i")
echo "🗣️ $trimmed → $filename"
"$SPEAK_CMD" "$trimmed" "$filename"
i=$((i + 1))
sleep 0.5
done
#!/bin/bash
DIR="$1"
PLAYER="${2:-ffplay}" # デフォルトは ffplay
if [ ! -d "$DIR" ]; then
echo "❌ ディレクトリが存在しません: $DIR"
exit 1
fi
# 対応プレイヤーの存在確認
if ! command -v "$PLAYER" > /dev/null 2>&1; then
echo "❌ プレイヤー '$PLAYER' が見つかりません"
exit 1
fi
# .wav の再生(昇順)
for file in "$DIR"/*.wav; do
[ -e "$file" ] || continue
echo "▶️ 再生中: $file"
if [ "$PLAYER" = "ffplay" ]; then
ffplay -nodisp -autoexit "$file" >/dev/null 2>&1
elif [ "$PLAYER" = "aplay" ]; then
aplay "$file"
elif [ "$PLAYER" = "play" ]; then
play "$file"
else
echo "❌ 未対応のプレイヤー: $PLAYER"
exit 1
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment