作っているアプリで多言語で、単語の音声読み上げが必要だったのでPollyを使うことにしました。
Pollyはテキストを指定すると多言語でテキストを読み上げたり、その音声ファイルを取得できたりします。
今回は以下の手順で最終的に音声ファイルを作成します。
- MacOSでの環境構築
- 1ファイルの変換
- 多数のファイルを同時に変換
MacOSでの環境構築
awscliなど各種導入します
brew install awscli
brew install sox # 音声の正規化用
brew install vorbis-tools # wavからoggに変換
1ファイルの変換
例えばHello
という単語を発音させたファイルをPollyから取得し、変換するには以下のようにします。
# PollyからHelloをPCMでローカルに出力
aws polly synthesize-speech \
--output-format pcm --voice-id Salli --sample-rate 16000 \
--text "Hello" \
--region us-west-2 \
Hello.raw
# Wavに変換。Pollyは音声が小さいので正規化もしています。
sox -r 16k -e signed -b 16 -c 1 Hello.raw Hello.wav norm
# Oggに変換
oggenc Hello.wav -o Hello.ogg
複数言語、複数テキストを効率的に変換
text.csv
を作ってそれを、convert.rb
で変換します。convert.rbの$awscli_profileは各自適切なものにします。
filename,jajp,enus,engb
Dog,いぬ,Dog,Dog
Cat,ねこ,Cat,Cat
require 'csv'
require 'fileutils'
require 'parallel'
$language_voice = {
jajp: 'Mizuki',
enus: 'Salli',
engb: 'Emma',
}
$tmp_dir = 'tmp'
$out_dir = 'out'
$input_file = 'text.csv'
$awscli_profile = 'profile'
def convert(file, lang, text)
tmp_dir_path = "#{$tmp_dir}/#{lang.to_s}"
out_dir_path = "#{$out_dir}/#{lang.to_s}"
[tmp_dir_path, out_dir_path].each do |dir|
FileUtils::mkdir_p dir
end
voice = $language_voice[lang]
command = "aws polly synthesize-speech \\
--output-format pcm --voice-id #{voice} --sample-rate 16000 \\
--text '#{text}' \\
--profile #{$awscli_profile} \\
--region us-west-2 \\
#{tmp_dir_path}/#{file}.raw"
system(command)
command = "sox -r 16k -e signed -b 16 -c 1 #{tmp_dir_path}/#{file}.raw #{tmp_dir_path}/#{file}.wav norm"
system(command)
command = "oggenc #{tmp_dir_path}/#{file}.wav -o #{out_dir_path}/#{file}.ogg"
system(command)
end
csv = CSV.table($input_file)
[$tmp_dir, $out_dir].each do |dir|
FileUtils.rm_rf dir
FileUtils::mkdir_p dir
end
Parallel.each(csv.each_entry, in_processes: 20) do |row|
filename = row[0]
1.upto(row.size) do |i|
next if row[i].nil?
p "#{filename} #{row[i]} #{csv.headers[i]}"
convert(filename, csv.headers[i], row[i])
end
end
parallelは標準では、入っていないのでbundle installなどでいれておきます。
bundlerの場合は、bundle exec ruby convert.rb
で実行するとout以下にファイルができます。