Skip to content

Instantly share code, notes, and snippets.

@tam17aki
Last active September 2, 2021 16:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tam17aki/aaa273e868a10ffc7857befc14d52a65 to your computer and use it in GitHub Desktop.
Save tam17aki/aaa273e868a10ffc7857befc14d52a65 to your computer and use it in GitHub Desktop.
# coding: UTF-8
import subprocess
import numpy as np
import pyopenjtalk
import speech_recognition as sr
import urllib3
from bs4 import BeautifulSoup
from scipy.io import wavfile
# 合成した音声ファイルの一時格納場所
OUT_WAV = "/tmp/tts.wav"
# 地域名と地域コードをまとめた辞書テーブル
#
# 例
# YAHOO_DICT["愛知"]ならば
# ("名古屋市", 5110, "https://weather.yahoo.co.jp/weather/jp/23/")
# という「タプル」が得られる
YAHOO_DICT = {
"愛知": ("名古屋市", 5110, "https://weather.yahoo.co.jp/weather/jp/23/"),
"岐阜": ("岐阜市", 5210, "https://weather.yahoo.co.jp/weather/jp/21/"),
"三重": ("津市", 5210, "https://weather.yahoo.co.jp/weather/jp/24/"),
}
def speak_text(text):
"""音声合成をする関数"""
# 音声合成(テキストデータ→音声データ)
wav, sr = pyopenjtalk.tts(text)
# wavファイルに保存
wavfile.write(OUT_WAV, sr, wav.astype(np.int16))
# 保存したwavファイルを再生
subprocess.run("afplay " + OUT_WAV, shell=True)
def speak_weather(query, day=None):
"""Yahoo天気予報をスクレイピングして音声合成により喋らせる関数
取得したHTMLをパースするコードは以下を参考にした
https://www.ishilog.com/python-scraping-yahoo-weather/
"""
http = urllib3.PoolManager()
place = YAHOO_DICT[query][0] # 地域名
areacode = YAHOO_DICT[query][1] # 地域コード
url = YAHOO_DICT[query][2] + str(areacode) + ".html"
# HTMLをパースして解析
instance = http.request("GET", url)
soup = BeautifulSoup(instance.data, "html.parser")
# 地域の予報部分を抽出
rs = soup.find(class_="forecastCity")
rs = [i.strip() for i in rs.text.splitlines()]
rs = [i for i in rs if i != ""]
# テキスト決定
if day == "今日":
text = "今日の" + place + "の天気は" + rs[1] + "です。"
elif day == "明日":
text = "明日の" + place + "の天気は" + rs[19] + "です。"
else:
text = (
rs[0] + "の" + place + "の天気は" + rs[1] + "、"
"明日の" + place + "の天気は" + rs[19] + "です。"
)
# テキスト表示
print(text)
# 音声合成
speak_text(text)
if __name__ == "__main__":
while True:
# マイクからの音声入力
r = sr.Recognizer()
with sr.Microphone() as source:
print("話しかけてください!(Ok Google)")
audio = r.listen(source) # 音声取得
try:
# 日本語でGoogle音声認識
# textには音声認識結果が文字列として入っている
text = r.recognize_google(audio, language="ja-JP")
except sr.UnknownValueError:
print("Google音声認識は音声を理解できませんでした。")
except sr.RequestError as e:
print("Google音声認識からの結果を" "要求できませんでした;" " {0}".format(e))
else:
# 音声認識結果を表示
print("音声認識結果:{0}".format(text))
day = None
if "Ok" in text and "Google" in text: # wake word "Ok Google"
if "天気予報" in text or "天気" in text:
if "今日" in text:
day = "今日"
elif "明日" in text:
day = "明日"
if "名古屋" in text or "愛知" in text:
speak_weather("愛知", day)
elif "岐阜" in text:
speak_weather("岐阜", day)
elif "三重" in text:
speak_weather("三重", day)
else:
speak_text("東海三県を指定してください。")
elif "ありがとう" in text:
print("こちらこそ、ありがとうございます。")
speak_text("こちらこそ、ありがとうございます。")
break # while 脱出 -> プログラム終了
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment