Pythonでコマンドラインの実行
あとはコマンドラインをpythonで実行するメソッドが必要
curl -s -X POST "192.168.1.69:50021/audio_query?speaker=1" --get --data-urlencode text@weather.txt > query.json
でJSONファイルを作成
curl -s -H "Content-Type: application/json" -X POST -d @query.json "192.168.1.69:50021/synthesis?speaker=1" > test_audio.wav
で音声ファイルを作成
これを
Pythonで行うようにする
なおcurl の動作をrequest で行えるらしい
pip install requests simpleaudio
でインストール
Chatgpt で
curl -s -X POST "192.168.1.69:50021/audio_query?speaker=1" --get --data-urlencode text@weather.txt > query.json でJSONファイルを作成 curl -s -H "Content-Type: application/json" -X POST -d @query.json "192.168.1.69:50021/synthesis?speaker=1" > test_audio.wav で音声ファイルを作成 これらを python で行い 作成した音声ファイルを再生したい
で調べる
帰ってきた答えは
requests ライブラリを使用して、テキストファイルからJSONファイルを作成し、その後音声ファイルを作成します。次に、pydub や simpleaudio のようなライブラリを使用して音声ファイルを再生
とのこと
生成されたコードは
import requests import json import simpleaudio as sa # テキストファイルを読み込む with open('weather.txt', 'r') as file: text = file.read() # 最初のPOSTリクエストを行い、JSONを取得 response = requests.post( "http://192.168.1.69:50021/audio_query?speaker=1", data={'text': text} ) json_data = response.json() # JSONデータをファイルに保存 with open('query.json', 'w') as json_file: json.dump(json_data, json_file) # 第二のPOSTリクエストを行い、音声データを取得 response = requests.post( "http://192.168.1.69:50021/synthesis?speaker=1", json=json_data ) # 取得した音声データをWAVファイルとして保存 with open('test_audio.wav', 'wb') as audio_file: audio_file.write(response.content) # WAVファイルを読み込み、再生する wave_obj = sa.WaveObject.from_wave_file('test_audio.wav') play_obj = wave_obj.play() play_obj.wait_done() # 再生が終わるまで待機
これを実験で実行
しかしエラーとなる
原因を調べたら
ChatGPT このエラーメッセージは、simpleaudio モジュールがあなたのシステムのアーキテクチャと互換性がないことを示しています。エラーによると、インストールされたsimpleaudioはx86_64アーキテクチャ用ですが、あなたのシステムはarm64アーキテクチャを必要
とあるため
pygame や pydub などを使う必要がある
pip install requests pygame
の後に
import requests import json import pygame # テキストファイルの内容を読み込む with open('weather.txt', 'r') as file: text = file.read() # POSTリクエストでJSONデータを取得 response = requests.post( "http://192.168.1.69:50021/audio_query?speaker=1", data={'text': text} ) json_data = response.json() # JSONデータをファイルに保存 with open('query.json', 'w') as json_file: json.dump(json_data, json_file) # JSONファイルを読み込む with open('query.json', 'r') as json_file: json_payload = json.load(json_file) # POSTリクエストで音声ファイルを取得 response = requests.post( "http://192.168.1.69:50021/synthesis?speaker=1", json=json_payload ) # 音声データをファイルに保存 with open('test_audio.wav', 'wb') as audio_file: audio_file.write(response.content) # Pygameの初期化 pygame.init() pygame.mixer.init() # WAVファイルを読み込む sound = pygame.mixer.Sound("test_audio.wav") # 再生 sound.play() # 再生が終了するまで待機 while pygame.mixer.get_busy(): pygame.time.Clock().tick(10)
で実行したが
pygame 2.5.2 (SDL 2.28.3, Python 3.10.6) Hello from the pygame community. https://www.pygame.org/contribute.html Traceback (most recent call last): File "/Users/snowpool/aw10s/weather/weather_audio.py", line 39, in <module> sound = pygame.mixer.Sound("test_audio.wav") pygame.error: Unrecognized audio format
となる
とりあえず問題を分割
音声の再生ができるかテスト
cp ../test_audio.wav .
あとは
import pygame # Pygameの初期化 pygame.init() pygame.mixer.init() # WAVファイルを読み込む sound = pygame.mixer.Sound("test_audio.wav") # 再生 sound.play() # 再生が終了するまで待機 while pygame.mixer.get_busy(): pygame.time.Clock().tick(10)
で音声が再生されるのを確認
となると問題は音声ファイルの作成プロセス
import requests import json # テキストファイルを読み込む with open('weather.txt', 'r') as file: text = file.read() # 最初のPOSTリクエストを行い、JSONを取得 response = requests.post( "http://192.168.1.69:50021/audio_query?speaker=1", data={'text': text} ) json_data = response.json() # JSONデータをファイルに保存 with open('query.json', 'w') as json_file: json.dump(json_data, json_file) # 第二のPOSTリクエストを行い、音声データを取得 response = requests.post( "http://192.168.1.69:50021/synthesis?speaker=1", json=json_data ) # 取得した音声データをWAVファイルとして保存 with open('test_audio.wav', 'wb') as audio_file: audio_file.write(response.content)
で作成したファイルは音声が再生されない
作成に必要なJSONファイルを見てみると
失敗の方は
{"detail": [{"loc": ["query", "text"], "msg": "field required", "type": "value_error.missing"}]}
成功は
{"accent_phrases":[{"moras":[{"text":"キョ","consonant":"ky","consonant_length":0.12866447865962982,"vowel":"o","vowel_length":0.0973580852150917,"pitch":5.962612628936768},{"text":"オ","consonant":null,"consonant_length":null,"vowel":"o","vowel_length":0.09024209529161453,"pitch":6.068655967712402},{"text":"ノ","consonant":"n","consonant_length":0.05692561715841293,"vowel":"o","vowel_length":0.11087840050458908,"pitch":5.8726630210876465}],"accent":1,"pause_mora":null,"is_interrogative":false},{"moras":[{"text":"テ","consonant":"t","consonant_length":0.0718907043337822,"vowel":"e","vowel_length":0.14058615267276764,"pitch":5.855612277984619},{"text":"ン","consonant":null,"consonant_length":null,"vowel":"N","vowel_length":0.08981689810752869,"pitch":5.842429161071777},{"text":"キ","consonant":"k","consonant_length":0.07256065309047699,"vowel":"i","vowel_length":0.07487940043210983,"pitch":5.817480087280273},{"text":"ワ","consonant":"w","consonant_length":0.057370081543922424,"vowel":"a","vowel_length":0.12027011066675186,"pitch":5.624467849731445}],"accent":1,"pause_mora":null,"is_interrogative":false},{"moras":[{"text":"ク","consonant":"k","consonant_length":0.07742901891469955,"vowel":"u","vowel_length":0.0734512135386467,"pitch":5.836529731750488},{"text":"モ","consonant":"m","consonant_length":0.060555391013622284,"vowel":"o","vowel_length":0.18545563519001007,"pitch":5.841731071472168}],"accent":1,"pause_mora":{"text":"、","consonant":null,"consonant_length":null,"vowel":"pau","vowel_length":0.33395129442214966,"pitch":0.0},"is_interrogative":false},{"moras":[{"text":"ヨ","consonant":"y","consonant_length":0.10122014582157135,"vowel":"o","vowel_length":0.08855406194925308,"pitch":5.50715970993042},{"text":"ソ","consonant":"s","consonant_length":0.09714090079069138,"vowel":"o","vowel_length":0.09897967427968979,"pitch":5.924524784088135},{"text":"オ","consonant":null,"consonant_length":null,"vowel":"o","vowel_length":0.10465160012245178,"pitch":6.014603614807129},{"text":"サ","consonant":"s","consonant_length":0.09610642492771149,"vowel":"a","vowel_length":0.11944571882486343,"pitch":6.102450370788574},{"text":"イ","consonant":null,"consonant_length":null,"vowel":"i","vowel_length":0.08921179920434952,"pitch":6.081024169921875},{"text":"コ","consonant":"k","consonant_length":0.07877751439809799,"vowel":"o","vowel_length":0.08582849055528641,"pitch":6.140597343444824},{"text":"オ","consonant":null,"consonant_length":null,"vowel":"o","vowel_length":0.11994349211454391,"pitch":6.1246795654296875},{"text":"キ","consonant":"k","consonant_length":0.08878674358129501,"vowel":"i","vowel_length":0.09810564666986465,"pitch":6.173953533172607},{"text":"オ","consonant":null,"consonant_length":null,"vowel":"o","vowel_length":0.16754235327243805,"pitch":6.181836128234863},{"text":"ン","consonant":null,"consonant_length":null,"vowel":"N","vowel_length":0.06746162474155426,"pitch":6.051656723022461},{"text":"ワ","consonant":"w","consonant_length":0.04867963492870331,"vowel":"a","vowel_length":0.1127525344491005,"pitch":5.779387950897217}],"accent":8,"pause_mora":null,"is_interrogative":false},{"moras":[{"text":"ジュ","consonant":"j","consonant_length":0.11186956614255905,"vowel":"u","vowel_length":0.10070556402206421,"pitch":5.609426498413086},{"text":"ウ","consonant":null,"consonant_length":null,"vowel":"u","vowel_length":0.08927937597036362,"pitch":5.8536553382873535}],"accent":2,"pause_mora":null,"is_interrogative":false},{"moras":[{"text":"ゴ","consonant":"g","consonant_length":0.06749280542135239,"vowel":"o","vowel_length":0.09443604201078415,"pitch":6.002788543701172},{"text":"オ","consonant":null,"consonant_length":null,"vowel":"o","vowel_length":0.12283030897378922,"pitch":6.167281150817871},{"text":"テ","consonant":"t","consonant_length":0.07367654889822006,"vowel":"e","vowel_length":0.14059318602085114,"pitch":6.100039958953857},{"text":"ン","consonant":null,"consonant_length":null,"vowel":"N","vowel_length":0.08243037015199661,"pitch":5.868035316467285}],"accent":1,"pause_mora":null,"is_interrogative":false},{"moras":[{"text":"サ","consonant":"s","consonant_length":0.08632750064134598,"vowel":"a","vowel_length":0.1564868539571762,"pitch":5.76937198638916},{"text":"ン","consonant":null,"consonant_length":null,"vowel":"N","vowel_length":0.0757487341761589,"pitch":5.765336036682129}],"accent":2,"pause_mora":null,"is_interrogative":false},{"moras":[{"text":"ゴ","consonant":"g","consonant_length":0.05643042176961899,"vowel":"o","vowel_length":0.09696970134973526,"pitch":5.819827079772949},{"text":"オ","consonant":null,"consonant_length":null,"vowel":"o","vowel_length":0.10339736193418503,"pitch":5.959120273590088},{"text":"ド","consonant":"d","consonant_length":0.06090632826089859,"vowel":"o","vowel_length":0.17854683101177216,"pitch":5.801456451416016}],"accent":2,"pause_mora":{"text":"、","consonant":null,"consonant_length":null,"vowel":"pau","vowel_length":0.3034582734107971,"pitch":0.0},"is_interrogative":false},{"moras":[{"text":"ヨ","consonant":"y","consonant_length":0.09282273054122925,"vowel":"o","vowel_length":0.08764959871768951,"pitch":5.5444231033325195},{"text":"ソ","consonant":"s","consonant_length":0.09865055978298187,"vowel":"o","vowel_length":0.09965776652097702,"pitch":5.934866905212402},{"text":"オ","consonant":null,"consonant_length":null,"vowel":"o","vowel_length":0.10340947657823563,"pitch":6.015321731567383},{"text":"サ","consonant":"s","consonant_length":0.09463881701231003,"vowel":"a","vowel_length":0.11840283870697021,"pitch":6.101940155029297},{"text":"イ","consonant":null,"consonant_length":null,"vowel":"i","vowel_length":0.08852870017290115,"pitch":6.076019287109375},{"text":"テ","consonant":"t","consonant_length":0.0689489021897316,"vowel":"e","vowel_length":0.09846750646829605,"pitch":6.127346038818359},{"text":"エ","consonant":null,"consonant_length":null,"vowel":"e","vowel_length":0.1237698420882225,"pitch":6.114901542663574},{"text":"キ","consonant":"k","consonant_length":0.08733474463224411,"vowel":"i","vowel_length":0.0968116894364357,"pitch":6.151494026184082},{"text":"オ","consonant":null,"consonant_length":null,"vowel":"o","vowel_length":0.1778039187192917,"pitch":6.152987480163574},{"text":"ン","consonant":null,"consonant_length":null,"vowel":"N","vowel_length":0.064981609582901,"pitch":6.005949974060059},{"text":"ワ","consonant":"w","consonant_length":0.04751142859458923,"vowel":"a","vowel_length":0.09467842429876328,"pitch":5.725627899169922}],"accent":8,"pause_mora":null,"is_interrogative":false},{"moras":[{"text":"ロ","consonant":"r","consonant_length":0.0632673129439354,"vowel":"o","vowel_length":0.10540910810232162,"pitch":5.67587947845459},{"text":"ク","consonant":"k","consonant_length":0.06531907618045807,"vowel":"U","vowel_length":0.05817136913537979,"pitch":0.0},{"text":"テ","consonant":"t","consonant_length":0.07730791717767715,"vowel":"e","vowel_length":0.16715875267982483,"pitch":6.10499382019043},{"text":"ン","consonant":null,"consonant_length":null,"vowel":"N","vowel_length":0.06785128265619278,"pitch":5.860898494720459}],"accent":1,"pause_mora":null,"is_interrogative":false},{"moras":[{"text":"ロ","consonant":"r","consonant_length":0.03526639938354492,"vowel":"o","vowel_length":0.11113513261079788,"pitch":5.707563877105713},{"text":"ク","consonant":"k","consonant_length":0.07907760888338089,"vowel":"u","vowel_length":0.07053706794977188,"pitch":5.830077648162842}],"accent":2,"pause_mora":null,"is_interrogative":false},{"moras":[{"text":"ゴ","consonant":"g","consonant_length":0.072600357234478,"vowel":"o","vowel_length":0.09719936549663544,"pitch":5.857402324676514},{"text":"オ","consonant":null,"consonant_length":null,"vowel":"o","vowel_length":0.09454251080751419,"pitch":6.060022354125977},{"text":"ド","consonant":"d","consonant_length":0.05659743398427963,"vowel":"o","vowel_length":0.08684452623128891,"pitch":6.083237171173096},{"text":"デ","consonant":"d","consonant_length":0.05277804285287857,"vowel":"e","vowel_length":0.14346836507320404,"pitch":5.951061248779297},{"text":"ス","consonant":"s","consonant_length":0.07407647371292114,"vowel":"U","vowel_length":0.12432015687227249,"pitch":0.0}],"accent":2,"pause_mora":null,"is_interrogative":false}],"speedScale":1.0,"pitchScale":0.0,"intonationScale":1.0,"volumeScale":1.0,"prePhonemeLength":0.1,"postPhonemeLength":0.1,"outputSamplingRate":24000,"outputStereo":false,"kana":"キョ'オノ/テ'ンキワ/ク'モ、ヨソオサイコオキ'オンワ/ジュウ'/ゴ'オテン/サン'/ゴオ'ド、ヨソオサイテエキ'オンワ/ロ'_クテン/ロク'/ゴオ'ドデ_ス"}
となる
つまりJSON作成が失敗している
Request による生成を断念
代わりに subprocess によるLinux コマンドを実行する方法に買える
import subprocess # curl コマンドを定義 command = [ "curl", "-s", "-X", "POST", "192.168.1.69:50021/audio_query?speaker=1", "--get", "--data-urlencode", "text@weather.txt" ] # コマンドを実行し、出力を query.json にリダイレクト with open('query.json', 'w') as file: subprocess.run(command, stdout=file)
でサブプロセスを使う方法にすると
JSONファイルの作成が成功
これを
curl -s -H "Content-Type: application/json" -X POST -d @query.json "192.168.1.69:50021/synthesis?speaker=1" > test_audio.wav
とすると音声ファイルができているのを確認
次に一緒に音声ファイル作成までをpython でやるようにする
import subprocess # 最初のcurlコマンド(JSONファイルの作成) command_json = [ "curl", "-s", "-X", "POST", "192.168.1.69:50021/audio_query?speaker=1", "--get", "--data-urlencode", "text@weather.txt" ] # 第二のcurlコマンド(音声ファイルの作成) command_audio = [ "curl", "-s", "-H", "Content-Type: application/json", "-X", "POST", "-d", "@query.json", "192.168.1.69:50021/synthesis?speaker=1" ] # 最初のコマンドを実行してJSONファイルを作成 with open('query.json', 'w') as file: subprocess.run(command_json, stdout=file) # 第二のコマンドを実行して音声ファイルを作成 with open('test_audio.wav', 'wb') as file: subprocess.run(command_audio, stdout=file)
これで音声ファイルができているのを確認できたので
次に
これをpygame. で再生する
import subprocess import pygame import time # JSONファイルを作成するためのcurlコマンド command_json = [ "curl", "-s", "-X", "POST", "192.168.1.69:50021/audio_query?speaker=1", "--get", "--data-urlencode", "text@weather.txt" ] # 音声ファイルを作成するためのcurlコマンド command_audio = [ "curl", "-s", "-H", "Content-Type: application/json", "-X", "POST", "-d", "@query.json", "192.168.1.69:50021/synthesis?speaker=1" ] # 最初のコマンドを実行してJSONファイルを作成 with open('query.json', 'w') as file: subprocess.run(command_json, stdout=file) # 第二のコマンドを実行して音声ファイルを作成 with open('test_audio.wav', 'wb') as file: subprocess.run(command_audio, stdout=file) # Pygameの初期化 pygame.init() pygame.mixer.init() # WAVファイルを読み込む sound = pygame.mixer.Sound("test_audio.wav") # 再生 sound.play() # 再生が終了するまで待機 while pygame.mixer.get_busy(): time.sleep(0.1)
これでようやくcurl でファイルを作成し
Pygame で音声再生ができるようになった
次はテキストファイルではなく
Weather map api へアクセスし
その結果をテキストファイルへ保存
それを変換する
もしくはそのまま処理するようにする