【Linux】VOICEVOXで、しゃべってもらうスクリプト、複数行対応【Ubuntu】

VOICEVOXをいじってるので、テキストで渡して、音声化するスクリプトを作ってみた。

#!/bin/bash

# /opt/voicevox_nogui/run、ffmpeg が入っていること
# 使い方
# ./textToVoice.sh ./test.txt

# Voicevoxキャラクタ番号を指定(29 はナンバーセブン
CharacterNum=29

OutputDir="${HOME}/Desktop"

SCRIPT_DIR=$(cd $(dirname $0); pwd)
cd "${SCRIPT_DIR}"

readPath=$1
if [ ! -f "${readPath}" ]; then
	echo "${readPath}"
	echo "  が見つかりません。"
	exit
fi

function Start () {
	killall -9 -q run
	sleep 1
	nice -n 20 \
		'/opt/voicevox_nogui/run' &> /dev/null &

	# 動作チェック 60秒起動を待つ
	echo '# start process'
	for i in {1..30} ; do
		ver=`curl -s -X GET "127.0.0.1:50021/version"`
		if [ -n "${ver}" ]
		then
			echo "  Ver ${ver} Start!"
			return 0
			break
		fi
		sleep 2
	done
	return 1
}

function setData () {
	mkdir -p '/tmp/textToVoicevox'
	Sentence=${1}
	echo "${Sentence}" > '/tmp/textToVoicevox/text.txt'
}

function text2Wav () {
	SpeakerNo=${1}
	FileName=${2}

	echo "# voice generation -> ${FileName}"
	Line=`cat '/tmp/textToVoicevox/text.txt'`
	echo -e "  ${Line}"

	nice -n 20 curl -s \
	    -X POST "localhost:50021/audio_query?speaker=${SpeakerNo}" \
    	--get --data-urlencode 'text@/tmp/textToVoicevox/text.txt' > \
    	'/tmp/textToVoicevox/query.json'

	nice -n 20 curl -s \
    	-H "Content-Type: application/json" \
	    -X POST -d @/tmp/textToVoicevox/query.json \
    	"localhost:50021/synthesis?speaker=${SpeakerNo}" \
	    > "/tmp/textToVoicevox/${FileName}"
}

function voiceGeneration () {
	echo '# combine audio'
	for ((i=0; i<$count; i++))
	do
		wavPath="/tmp/textToVoicevox/${i}.wav"
		if [ -f "${wavPath}" ]; then
			echo "${wavPath}"
		fi
	done

	((count--))
	outputPath='/tmp/textToVoicevox/_out.wav'
	eval sox /tmp/textToVoicevox/{0..$count}.wav "${outputPath}"
	nice -n 20 ffmpeg -y -hide_banner -i "${outputPath}" \
		-vn -ar 44100 -ac 2 -b:a 192k "${outputPath%.wav}.mp3" 2> /dev/null
}

function Etc.. () {
	MovePath=`basename ${readPath}`
	mv "${outputPath%.wav}.mp3" "${OutputDir}/${MovePath%.*}.mp3"

	echo '# completion!'
}

### 実行部分 ### ###
# Start
Start
if [ $? ]; then
	# 文章読み込み
	count=0
	while read line
	do
		if [ -n "$line" ]; then
			# SetData
			setData "${line}"
			# TextToWav
			text2Wav "${CharacterNum}" "${count}.wav"
			((count++))
		fi
	done < "${readPath}"

	killall -q run
	# 音声結合
	voiceGeneration
	# 後処理
	Etc..
fi

#

使い方

上のコードをコピーしてもいいけど、Zipファイルも上げておく。

その中の、textToVoice.shに実行権限を与えて、下記のように実行する。

./textToVoice.sh ./test.txt

デフォルトでは、キャラクタは29のナンバーセブン、保存場所は${HOME}/Desktopになっているので、変えたければ、任意に、変える。
あとは、読ませたいテキストパスと、テキストの内容を変更する、と。

出力される音声ファイルは、テキストファイルの名前で、保存場所で指定したフォルダに、作成される。
下のようになっていたら、成功です。

仕様状況

・VOICEVOXを起動するために、メモリを1GBくらい使う。
・何らかの状況で、途中で終了した場合、killall run をして、VOICEVOXの実行ファイルを終了させる。
・/tmp フォルダに過程のファイルを作るので、不要なら削除すること。
・ファイル名に、 ’ や [ ] \ # とかの特殊文字が入っていると、困る。やめて欲しい。
・2行、25文字読ませるのに、自分のパソコンだと、3分弱かかる。
VOICEVOXとGPUで検索すると、GPU版では不安定になるようなので、CPU版でしか、試してないけど。

以上。