LINEBOT+Open Jtalkで初音ミクに全力人力でしゃべらせてみた

逃げ恥を見ていて、ガッキーがペッパー君と楽しそうに話しているのを見て、ロボット欲しいなと思ったけれども、小遣いでは買えそうにないので、代わりになるものを作ってみた。

構想

入力した内容をそのまま話させる。INはなんでも良いが、一般人でもイメージしやすいようにLINEがベター。

LINEからの入力はSSL証明書が用意されたサーバが必要で、普段はVPSAWSに無料のLetsEncryptを設定して対応しているが、今回はその方法ではうまくいかない。 なぜならサーバから音声を出したいので、ローカルでサーバを運用する必要があるからだ。

環境は ノートPC(windows10)にのせたvirtualbox+vagrantで行うこととした。

キーワード

ググってみたところ、入力した文字を音声化するのとローカルサーバをSSLで外部公開できるライブラリが見つかった。 - Open Jtalk(入力した日本語を音声化する) - ngrok(ローカル環境をテンポラリで外部公開する)

Open Jtalk環境構築

centosにOpen Jtalkをインストールする。Oopen Jtalkを利用するには当該ライブラリ以外にhts_engine APIと辞書ファイル、音声ファイルが必要となってくるのでインストールする。

hts_engine APIのインストール

$wget http://downloads.sourceforge.net/hts-engine/hts_engine_API-1.09.tar.gz
...
$tar zxvf hts_engine_API-1.09.tar.gz
...
$cd hts_engine_API-1.09
$./configure
...
config.status: creating Makefile
$make
...
$make install
...
$which hts_engine
usr/local/bin/hts_engine

Open Jtalkのインストール

$wget http://downloads.sourceforge.net/open-jtalk/open_jtalk-1.09.tar.gz
...
$tar zxvf open_jtalk-1.09.tar.gz
...
$cd open_jtalk-1.09
$./configure
...
config.status: creating Makefile
$make
...
$make install
...
$which open_jtalk
/usr/local/bin/open_jtalk

辞書のインストール

Open Jtalkで使う辞書のインストールを行う。

$mkdir /usr/local/share/open_jtalk
$wget http://sourceforge.net/projects/open-jtalk/files/Dictionary/open_jtalk_dic-1.07/open_jtalk_dic_utf_8-1.07.tar.gz
...
$tar zxvf open_jtalk_dic_utf_8-1.07.tar.gz
...
$su -
$mv open_jtalk_dic_utf_8-1.07 /usr/local/share/open_jtalk/

初音ミク音声をOpen Jtalkで

Open Jtalkでは音声サンプルがいくつか用意されているが、今回はそれらを利用せず、個人が作っている初音ミクの音声を利用させていただく。 .htsvoice形式までの作り方はいかが参考になる。

Open JTalkで初音ミクの声でおしゃべりさせる@Mac/Linux/Raspberry Pi - karaage. [からあげ]
Voice.htsvoice...

上記でできたhtsvoiceファイルを音声ファイルとして適当な場所に保存する。

$mkdir /usr/local/share/hts_voice/miku
$mv Voice.htsvoice /usr/local/share/hts_voice/miku/miku.htsvoice

以上でOpen Jtalkの環境ができたのでテストをしてみよう。

Open Jtalkのテスト

$echo '今日は晴れです' | /usr/bin/tr -d '\n' | open_jtalk \
        -m /usr/local/share/hts_voice/miku/miku.htsvoice \
        -ow /tmp/output.wav -x /usr/local/share/open_jtalk/open_jtalk_dic_utf_8-1.09

$sudo aplay /tmp/output.wav

無事PCから音声が流れたらOKだ。出ない場合は僕も引っかかったがvirtualboxの設定でオーディオが無効になっている可能性があるので、一度vagrantを落としてオーディオを有効にしてから試してほしい。

プログラム

LINEからメッセージを受信して、Open Jtalkを話すプログラムを書いてみよう。 今回はPHPを選択する。LINEが提供するSDKからLINEBotTinyを利用する。

<?php

require_once('./LINEBotTiny.php');

$channelAccessToken = 'YOUR_ACCESS_TOKEN';
$channelSecret = 'YOUR_SECRET';

$client = new LINEBotTiny($channelAccessToken, $channelSecret);

foreach ($client->parseEvents() as $event) {
    switch ($event['type']) {
        case 'message':
            $message = $event['message'];

            switch ($message['type']) {
                case 'text':
                    $client->replyMessage(array(
                        'replyToken' => $event['replyToken'],
                        'messages' => array(
                            array(
                                'type' => 'text',
                                'text' => 'きちんと話したよ'
                            )
                        )
                    ));

                    // DB
                    $mongo = new Mongo();

                    $db = $mongo->selectDB("mikubot");

                    $coll = $db->selectCollection("messages");

                    $coll->insert( (array('message' => $message['text'], 'ts' => new MongoDate() )) );

                    // open_jtalk
                    exec("sudo /usr/local/bin/line_talk \"". $message['text']. "\"");

                    break;
                default:
                    error_log("Unsupporeted message type: " . $message['type']);
                    break;
            }
            break;
        default:
            error_log("Unsupporeted event type: " . $event['type']);
            break;
    }
};
?>

基本はecho_bot.phpを真似しただけだが、このPHPでは追加で2つの要素が入っているので追記しておく。 一つ目はmongdbに話したい内容をためることにした。今はLINEから入力した内容のみを話す人力知能だけれども、いつか人工知能になってくれることを祈って。 二つ目はexecの部分だ。 line_talk コマンドの中身を書いておく。

$ cat line_talk                                                                                                                  
/bin/sh

echo $1 | /usr/bin/tr -d '\n' | open_jtalk \
        -m /usr/local/share/hts_voice/miku/miku.htsvoice \
        -ow /tmp/output.wav -x /usr/local/share/open_jtalk/open_jtalk_dic_utf_8-1.09/

sudo aplay /tmp/output.wav

上記PHPapacheなり、nginxなり、php -S localhost:8080なりでローカルサーバをたてて配置する。 このときhttpsの設定は必要なくhttpの事だけ考えてよい。

LINE Messaging APIvagrantから利用する

LINE Messaging APIの設定

初めてだと少しわかりづらいがQiitaなどに沢山情報が落ちているので検索してみよう。

ngrokの設定

ngrokをインストールする。

$npm i -g ngrok

ngrokの起動

$nngrok http 80
ngrok by @inconshreveable                                                                                                                     (Ctrl+C to quit)
                                                                                                                                                              
Session Status                online                                                                                                                          
Version                       2.1.18                                                                                                                          
Region                        United States (us)                                                                                                              
Web Interface                 http://127.0.0.1:4040                                                                                                           
Forwarding                    http://xxxxxxx.ngrok.io -> localhost:80                                                                                        
Forwarding                    https://xxxxxxx.ngrok.io -> localhost:80  

https://xxxxxxx.ngrok.io をコピー。

webhook

LINE Messaging API のWebhook URLにhttps://xxxxxxx.ngrok.io/XXXX/callback.php を設定する。

動作

じんりきみーくの完成。