とある記事にこう書かれていました。
いまTwitterを見ているんですけど、このつぶやきって実際は「本当のつぶやき」じゃないですよね?
なのに、つぶやき、つぶやきって……
俺の知っている人たち、みんな文章をつくって投稿してるんですよね。
やっぱり本当のつぶやきじゃないですよね?
「確かにそうだ!」と非常に感心しました。
なのでこの記事を参考に、ひとりごとをマイクで拾って自動ツイートするシステムを開発してみました。
できたもの
こんな感じにひとりごとが自動ツイートされます
とりあえずこれで完成 かなー
— ジョーのリアルなつぶやき (@RealTweet_Joe) August 24, 2019
あーこれすごいいいな
— ジョーのリアルなつぶやき (@RealTweet_Joe) August 24, 2019
システム概要
具体的には、
- Google Chrome + Web Speech API
- Ruby on Rails
- Twitter API
をそれぞれ使っています。
Web Speech APIの実装方法
下記記事を参考に実装しましたが、非常に簡単でした!
Webページでブラウザの音声認識機能を使おう
最低限の機能を試すには下記でokです。
<script>
SpeechRecognition = webkitSpeechRecognition || SpeechRecognition;
const recognition = new SpeechRecognition();
recognition.onresult = (event) => {
alert(event.results[0][0].transcript);
}
recognition.start();
</script>
私の場合は「Webサイト表示時にマイクonしたい」「マイクが勝手に切れたら再度onしたい」「start/stopボタンが欲しい」「テキスト化の状況を見たい」という条件があったので下記のようにしました。
<button id="switch-btn">stop</button>
<div id="result-div"></div>
<script>
const switchBtn = document.querySelector('#switch-btn');
const resultDiv = document.querySelector('#result-div');
SpeechRecognition = webkitSpeechRecognition || SpeechRecognition;
let recognition = new SpeechRecognition();
recognition.lang = 'ja-JP';
recognition.interimResults = true;
recognition.continuous = true;
let finalTranscript = ''; // 確定した(黒の)認識結果
recognition.onresult = (event) => {
resultDiv.innerHTML = '';
let interimTranscript = ''; // 暫定(灰色)の認識結果
for (let i = event.resultIndex; i < event.results.length; i++) {
let transcript = event.results[i][0].transcript;
if (event.results[i].isFinal) {
finalTranscript += transcript;
resultDiv.innerHTML = finalTranscript;
finalTranscript = '';
} else {
interimTranscript = transcript;
resultDiv.innerHTML = '<i style="color:#ddd;">' + interimTranscript + '</i>';
}
}
}
let recordActive = true;
recognition.start();
switchBtn.onclick = () => {
if (!recordActive) {
recognition.start();
switchBtn.innerHTML = 'stop';
resultDiv.innerHTML = '';
recordActive = true;
} else {
recognition.stop();
switchBtn.innerHTML = 'start';
recordActive = false;
}
}
function checkNotAutoFinished() {
if (recordActive) {
recognition.start();
resultDiv.innerHTML = '';
}
}
setInterval('checkNotAutoFinished()', 60000); // stopボタンが押されていなければ、1分ごとにリスタート
</script>
Twitter APIの実装方法
jQueryによるAjax通信を用いました。
具体的にはhttps://developer.twitter.com/ でAPI登録後、上記コードの中で
$.ajax({url: '/home/update', type: "GET", data:{text:finalTranscript}});
とし、対応するコントローラーでは
class HomeController < ApplicationController
before_action :set_twitter_client
def update
text = params.require(:text)
begin
@twitter.update(text)
rescue => e
error = e
end
render plain: error || "Twitter.update"
end
helper_method :update
private
def set_twitter_client
@twitter = Twitter::REST::Client.new do |config|
config.consumer_key = "APIから取得"
config.consumer_secret = "同上"
config.access_token = "同上"
config.access_token_secret = "同上"
end
end
end
とする事で実装可能です。
使い方
あとはWebサイトを開いたままにして作業していれば、自動でツイートが行われます。
なんかできそう
— ジョーのリアルなつぶやき (@RealTweet_Joe) August 24, 2019
理科1700年に聞かせんのやりたい
— ジョーのリアルなつぶやき (@RealTweet_Joe) August 24, 2019
ほっともっと
— ジョーのリアルなつぶやき (@RealTweet_Joe) August 25, 2019
米どころ
— ジョーのリアルなつぶやき (@RealTweet_Joe) August 25, 2019
…**精度はそれなり**でした。