python テキストを読み上げるクラス(実体数行)と実行例

PYTHON実行中に音声出力します

(動作はwindows上のみです)

別ファイルにある{“呼び出しキー”:”テキストデータ”}の辞書データファイルを読み込んで、指定したテキストを読み上げます。

汎用化のためクラス化しましたが、音声出力の実態は(windowsの機能呼び出し宣言2行+呼び出しメソッド行)の3行です。

import win32com.client
sp = win32com.client.Dispatch(“SAPI.SpVoice”)#これを呼ぶだけ
sp.Speak(str)#一文読み上げ

コードが読みづらくなるのでデータ呼び出し部分とまとめて、別ファイルが良いかなと思ったのです。

しかし、考えてみれば、ソース中だと、#コメント代わりになるとも言えるのでソース埋め込みも悪くないですけどね。

手順

クラスから実体を作ります

  •     sp=Talk()

テキストデータを読み込みます

  • sp.set_dic(ファイル名)

読み上げます

  • 文字列変数=キー
  • sp.talk(テキスト辞書オブジェクト[キー])

読み上げのためのクラスを定義します

WINDOWSの機能win32comを使います

import win32com.client
from os import path
import json

class Talk():
    def talk(self,strs):#読み上げ機能
        speaker = win32com.client.Dispatch("SAPI.SpVoice")#これを呼ぶだけ
        speaker.Speak(strs)#一文読み上げ

    def set_dic(self,filename):#読み上げテキストを格納
        json_open = open(filename, 'r',encoding="utf-8")
        bun_dic = json.load(json_open)
        return bun_dic#jsonオブジェクトを返す

例として、ビットフライヤーのapiを叩いてデータを取得するプログラムに、ヘルプ的に音声案内を付け足します.

#音声読み上げ以外の部分の解説ページはこちらにあります
#https://tokyo559.com/page-6751/getbf/
from pprint import pprint#辞書を整形出力
import time#タイマーとか現在時刻とか
import pybitflyer#ラッパー
import json#データ形式
import requests#
import datetime#
from class_talk import Talk

sp=Talk()#音声出力の実体化

product='BTC_JPY'
#ラッパーのインスタンス化
api = pybitflyer.API(api_key='', api_secret='')#public apiなので、''でOK

def getmarkets():
    pprint(requests.get('https://api.bitflyer.com/v1/getmarkets').json())


def py_board():
    response = api.board(product_code=product)
    print(product,'midprice =',response['mid_price'])
    print('asks 件数',len(response['asks']))
    print('bids 件数',len(response['bids']))


def py_ticker(self, **params):
    response = api.ticker(product_code=product)
    pprint(response)

def py_executions(self, **params):
    response = api.executions(product_code=product)
    print('executions')
    pprint(response)#全9種類
    print(len(response))

def py_getboardstate(self, **params):
    response = api.getboardstate(product_code=product)
    print('getboardstate')
    print(response)

def py_gethealth(self, **params):
    response = api.gethealth(product_code=product)
    print('gethealth')
    print(response['status'])

def py_getchats(self, **params):
    td=datetime.datetime.now()
    td=td - datetime.timedelta(days=1) #3時間減算
    response = api.getchats(from_date=td.strftime('%Y-%m-%d'))#T%H:%M:%S'))
    print('getchats 最近の100件だけ表示')
    for i in range(1000):#response:
        print(response[i]['message'])


if __name__ == '__main__':
    bun_dic=sp.set_dic('describe.json')#別ファイルから音声テキストを読み込む
    try:
        while True:
            inp=input('''どの処理にしまましょうか
                    <<<HTTP Public API>>>
                    h:help
                    0:getmarket
                    1:py_board
                    2:py_ticker
                    3:py_executions
                    4:py_getboardstate
                    5:py_gethealth
                    6:py_getchats
                    end:END'''
                    )
            if inp=='h':
               sp.talk(bun_dic[inp])#音声出力、キーを投げてやると対応した文章が読み上げられる
            if inp=='0':
               print('0: get markets')
               sp.talk(bun_dic[inp])
               getmarkets()
            if inp=='1':
                print('1:py_board')
                sp.talk(bun_dic[inp])
                py_board()
            if inp=='2':
                print('2:py_ticker')
                sp.talk(bun_dic[inp])
                py_ticker('FX_BTC_JPY')
            if inp=='3':
                print('3:py_executions')
                sp.talk(bun_dic[inp])
                py_executions('FX_BTC_JPY')
            if inp=='4':
                print('4:py_getboardstate')
                sp.talk(bun_dic[inp])
                py_getboardstate('FX_BTC_JPY')
            if inp=='5':
                print('5:py_gethealth')
                sp.talk(bun_dic[inp])
                py_gethealth('FX_BTC_JPY')
            if inp=='6':
                print('6:py_getchats')
                sp.talk(bun_dic[inp])
                py_getchats('')
            elif inp=='end'or inp=='END'or inp=='' or inp=='100':
                print('bye--')
                sp.talk(bun_dic[inp])
                break
            else:
                pass
    except KeyboardInterrupt:
        pass

用意した音声ヘルプファイル

{
"h":"番号を入力してください、endと入力すると終了します",
"0":"ビットフライヤーが扱っている暗号資産の種類と取引の種類一覧を取得します",
"1":"板、約定されていない予約の一覧を表示します.数が膨大なので、件数のみ表示します",
"2":"ティッカー、現在の価格の感触を表示します",
"3":"約定一覧を表示します",
"4":"板の状態、取引所の板に関わるサーバーの状態",
"5":"取引所の状態、遅延しているかどうか",
"6":"チャットの履歴データ、膨大なので直近の一部のみ表示します",
"end":"これで終わります"
}

プログラムの処理の選択で”1″を入力すると”1″に対応した
“板、約定されていない予約の一覧を表示します.数が膨大なので、件数のみ表示します”
が読み上げられる。

例で挙げたプログラムはコードが長いが、読み上げに関するコード自体は短いので、かんたんに応用できると思う。

テキストファイルの準備が面倒かもしれませんが、量の多いテキストでもエクセルを使えばかんたんです。UTF-8での保存を忘れないように。

コメント

タイトルとURLをコピーしました