Python SDK
1 概要
音声対話サービスのためのPython SDKです。
対応しているサービス 一発話認識、リアルタイム音声認識。
取扱説明書をよくお読みください 。
1.1 SDKファイルの説明
| ファイル/ディレクトリ | 説明 |
|---|---|
| speech_rec | SDK関連ファイル |
| demo | コード例 |
| ├─ transcriber_demo.py | リアルタイム音声認識サンプルコード |
| ├─ recognizer_demo.py | 一発話認識例コード |
| ├─ demo.wav | 中国語(北京語)サンプル音声(WAV形式) |
| ├─ demo.mp3 | 中国語(北京語)サンプル音声(MP3形式) |
| setup.py | インストールファイル |
| README-JA.md | 日本語説明文書 |
| README-EN.md | 英語説明文書 |
注意:SDKで提供されるテスト音声の認識結果は一定です。デフォルトで使用される音声はMP3形式です。入力された音声がWAVやその他の形式の場合、MP3形式に変換されます。
2 動作環境
Python3.4以降、ffmpeg。
Pythonの実行環境を別に作成することをお勧めします。そうしないとバージョンの衝突が発生する可能性があります。
3 設置方法
1.Pythonパッケージ管理ツールsetuptoolsがインストールされていることを確認する。インストールされていない場合は、インストールしてください:
$ pip install setuptools
2.SDKを解凍し、フォルダ(setup.pyファイルがあるフォルダ)に移動し、SDKディレクトリで以下のコマンドを実行します:
Install
$ python setup.py install Note: - The above pip and python commands correspond to Python3.
- If the following information is displayed, the installation is successful: Finished processing dependencies for speech-python-rec-sdk==1.0.0.8
- After installation, the build, dist, and speech_python_rec_sdk.egg-info files are generated.
3.demoのファイルの具体的なパラメーターを修正する:
recognizer_demo.py and transcriber_demo.py are execution files for one-sentence recognition and real-time speech recognition, respectively.
//Enter the appID that you get when you purchase a service in the platform app_id = '#####'
//Enter appSecret, which you get when you purchase a service in the platform app_secret = '#####'
//Enter the path of the voice file to be identified. Change it to the path of the customized audio file audio_path = '####'
//Input language, format see platform documentation center-Speech recognition-Development Guide lang_type = 'ja-JP'
4.recognizer_demo.pyまたはtranscriber_demo.pyを実行して音声を認識します。トークンの認識に失敗したり、有効期限が切れたりした場合は、ローカルのSpeechRecognizer_token.txtファイルまたはSpeechTranscriber_token.txtファイルを削除して再度お試しください。それでも期限切れの場合は、技術スタッフまでご連絡ください。
To run the command in the demo directory, set parameters such as app_id corresponding to python files in the demo.
$ python recognizer_demo.py $ python transcriber_demo.py #After the successful run, the SpeechRecognizer_token.txt or SpeechTranscriber_token.txt files are generated in the path where the demo is running.
注意: 「timestamp timeout 」または 「timestamp is greater than current time 」と表示された場合、ローカル時間とサーバー時間が一致していません。エラーメッセージの時差に応じて、
speech-python-recファイルの_token.pyファイルを修正し、timestamp = int(t)の行コードを適切に修正します。
timestamp = int(t)+1または2,3,4など、またはtimestamp = int(t)-1または2,3,4など。
- After _token.py is modified, the modification takes effect only after it is created again. The specific steps are as follows:
Delete build, dist, and speech_python_rec_sdk.egg-info files created and generated in the SDK directory.
To uninstall and reinstall the SDK, run $pip uninstall speech-python-rec-sdk and repeat steps 2,3,4.
4 パラメータの説明
4.1 リアルタイム音声認識デモ
speech_rec/demo/transcriber_demo.py これはリアルタイムの音声認識デモで、直接実行することができる。
4.1.1 キー・インターフェースの説明
リアルタイム音声認識SDKは主にTranscriberクラスを使用して完成され、Tokenクラスを使用してコード呼び出しのステップを完了することが許可されています:
SpeechClientクラスのget_token()メソッドを呼び出してトークンを取得する。SpeechTranscriberのインスタンスを作成する。Callbackインスタンスを作成する。- パラメータを設定するには、
SpeechTranscriberインスタンスのset_token()メソッドを呼び出します。 SpeechTranscriberインスタンスのstart()メソッドを呼び出して、サーバーに接続する。- I音声を送信するために
SpeechTranscriberインスタンスのsend()メソッドを呼び出します。 SpeechTranscriberインスタンスのstop()メソッドを呼び出して、送信を停止する。SpeechTranscriberインスタンスのclose()メソッドを呼び出して、サーバーとの接続を切断する。
4.1.2 パラメータの説明
| パラメータ | タイプ | 必須 | 説明 | デフォルト値 |
|---|---|---|---|---|
| lang_type | String | はい | 言語オプション | 必須 |
| format | String | いいえ | 音声エンコード形式 | pcm |
| sample_rate | Integer | いいえ | 音声サンプルレート sample_rate=「8000」の場合 fieldパラメータ・フィールドが必須で、かつfield=「call-center」 | 16000 |
| enable_intermediate_result | Boolean | いいえ | 中間認識結果を返すかどうか | true |
| enable_punctuation_prediction | Boolean | いいえ | 後処理で句読点を追加するかどうか | true |
| enable_inverse_text_normalization | Boolean | いいえ | 後処理でITNを実行するかどうか | true |
| max_sentence_silence | Integer | いいえ | 音声センテンスの静寂検出しきい値、静寂時間がこのしきい値を超えるとセンテンスが切り替えられます。有効なパラメータ範囲は200~1200で、単位はミリ秒です | sample_rate=16000:800 sample_rate=8000:250 |
| enable_words | Boolean | いいえ | 単語情報を返すかどうか | false |
| enable_intermediate_words | Boolean | いいえ | 中間結果の単語情報を返すかどうか | false |
| enable_modal_particle_filter | Boolean | いいえ | 語気詞フィルタを有効にするかどうか | true |
| hotwords_list | List<String> | いいえ | 一度限り有効な単語リスト、本接続中のみ有効ですhotwords_id と同時に存在する場合は、hotwords_list が優先されます。一度に最大 100 個まで提供可能です | 無し |
| hotwords_id | String | いいえ | 単語ID | 無し |
| hotwords_weight | Float | いいえ | 単語ウェイト、値の範囲[0.1, 1.0] | 0.4 |
| correction_words_id | String | いいえ | 強制置換単語庫ID 複数の強制置換単語庫IDを使用することができ、各IDは縦線 |で区切られます;all は全ての強制置換単語庫IDを使用することを意味します | 無し |
| forbidden_words_id | String | いいえ | NG単語ID 複数のNG単語IDを使用することができ、各IDは縦線 |で区切られます;all は全てのNG単語IDを使用することを意味します | 無し |
| field | String | いいえ | 分野 一般:general (サポートサンプルレート16000Hz) コールセンター:call-center (サポートサンプルレート8000Hz) | 無し |
| audio_url | String | いいえ | 戻り音声のフォーマット(プラットフォームでは30日間のみ保存) mp3:mp3形式の音声リンクを返す pcm:pcm形式の音声リンクを返す wav:wav形式の音声リンクを返す | 無し |
| connect_timeout | Integer | いいえ | 接続タイムアウト(秒)、範囲:5-60 | 10 |
| gain | Integer | いいえ | 振幅増幅係数を表し、範囲[1, 20] 1は拡大しないことを示し、2は元の振幅の2倍(拡大1倍)を示し、以下同様 | sample_rate=16000:1 sample_rate=8000:2 |
| user_id | String | いいえ | ユーザーが定義した情報で、応答メッセージにそのまま返され、最大36文字までです | 無し |
| enable_lang_label | Boolean | いいえ | 言語を切り替える際に、認識結果に言語ラベルを返す:現在は日英混合、中英混合言語のみ対応しています。注意:この機能を有効にすると、言語切り替え時に応答の遅延が発生します | false |
| paragraph_condition | Integer | いいえ | 同じ speakerid 内で設定された文字数に達したら、次の文で新しい段落番号を返す:範囲[100, 2000]、範囲外の値はこの機能を無効化します | 0 |
| enable_save_log | Boolean | いいえ | 音声データと認識結果のログを提供して、弊社が製品とサービスの質を向上させるために使用することは可能ですか | true |
4.1.3 リアルタイム音声認識サンプルコード
完全なコードはSDKのspeech_python_rec/demo/transcriber_demo.pyファイルを参照してください。
# -*- coding: utf-8 -*-
import json
import os.path
import time
import threading
import traceback
import speech_rec
from speech_rec.callbacks import SpeechTranscriberCallback
from speech_rec.parameters import DefaultParameters, Parameters
token = None
expire_time = 7 # Expiration time
info_list = [[], [], False]
class MyCallback(SpeechTranscriberCallback):
"""
The parameters of the constructor are not required. You can add them as needed
The name parameter in the example can be used as the audio file name to be recognized for distinguishing in multithreading
"""
def __init__(self, name='default'):
self._name = name
def started(self, message):
self.print_message(message)
def result_changed(self, message):
self.print_message(message)
def sentence_begin(self, message):
self.print_message(message)
def sentence_end(self, message):
global info_list
channel = message['header']['user_id']
begin_time = message['payload']['begin_time']
end_time = message['payload']['time']
result = message['payload']['result']
if channel == "left" or channel == "right":
if channel == "left":
if result:
info_list[0].append([channel, begin_time, end_time, result])
elif channel == "right":
if result:
info_list[1].append([channel, begin_time, end_time, result])
self.print_info()
else:
print(message)
def completed(self, message):
try:
print(message)
except Exception as ee:
print(ee)
traceback.print_exc()
global info_list
info_list[2] = True
def print_info(self, ):
left_list = info_list[0]
right_list = info_list[1]
if_end = info_list[2]
def format_string(data_list, list_name):
channel, begin_time, end_time, result = data_list[0]
if list_name == "left_list":
info_list[0].pop(0)
else:
info_list[1].pop(0)
return f"channel:{channel}\tbegin_time:{begin_time}\tend_time:{end_time}\tresult:{result}"
if left_list and right_list:
while True:
if not left_list and not right_list:
break
if left_list and right_list:
left_begin_time = left_list[0][1]
left_end_time = left_list[0][2]
right_begin_time = right_list[0][1]
right_end_time = right_list[0][2]
if left_begin_time == right_begin_time and left_end_time > right_end_time:
print(format_string(right_list, "right_list"))
elif left_begin_time == right_begin_time and left_end_time <= right_end_time:
print(format_string(left_list, "left_list"))
elif left_begin_time < right_begin_time:
print(format_string(left_list, "left_list"))
elif left_begin_time >= right_begin_time:
print(format_string(right_list, "right_list"))
if left_list and not right_list:
if left_end_time > right_end_time:
break
else:
print(format_string(left_list, "left_list"))
if not left_list and right_list:
if right_end_time > left_end_time:
print(format_string(right_list, "right_list"))
else:
break
elif if_end:
while left_list:
print(format_string(left_list, "left_list"))
while right_list:
print(format_string(right_list, "right_list"))
def print_message(self, message):
channel = message['header']['user_id']
if channel == "left" or channel == "right":
pass
else:
print(message)
def task_failed(self, message):
print(message)
def warning_info(self, message):
print(message)
def channel_closed(self):
print('MyCallback.OnTranslationChannelClosed')
def solution(client, app_id, app_secret, audio_path, lang_type, kwargs):
"""
Transcribe speech,single thread
:param client: SpeechClient
:param app_id: Your app_id
:param app_secret: Your app_secret
:param audio_path: Audio path
:param lang_type: Language type
"""
each_audio_format = kwargs.get("audio_format", DefaultParameters.MP3)
field_ = kwargs.get("field", DefaultParameters.FIELD)
user_id = kwargs.get("user_id", "default")
print("ccc",kwargs)
assert os.path.exists(audio_path), "Audio file path error, please check your audio path."
if judging_expire_time(app_id, app_secret, expire_time):
callback = MyCallback(audio_path)
transcriber = client.create_transcriber(callback)
transcriber.set_app_id(app_id)
transcriber.set_token(token)
# fixme You can customize the configuration according to the official website documentation
payload = {
"lang_type": lang_type,
"format": each_audio_format,
"field": field_,
"sample_rate": sample_rate,
"user_id": user_id
}
transcriber._payload.update(**payload)
try:
ret = transcriber.start()
if ret < 0:
return ret
with open(audio_path, 'rb') as f:
audio = f.read(7680)
cnt = 0
while audio:
ret = transcriber.send(audio)
# fixme: If you need to mandatory clause or set speaker id by yourself, please use the codes below
# Default, customizable and changeable
# if cnt % 768000 == 0:
# # Mandatory clause setting
# transcriber.set_mandatory_clause(True)
# transcriber._header = transcriber.get_mandatory_clause()
# transcriber.send(json.dumps({Parameters.HEADER: transcriber._header}), False)
# # Set speaker ID
# transcriber.set_speaker_id(speaker_id)
# speaker_id_info = transcriber.get_speaker_id()
# transcriber.send(json.dumps(speaker_id_info), False)
# print("Mandatory and Set speaker:",transcriber._payload)
if ret < 0:
break
cnt += 7680
time.sleep(0.24)
audio = f.read(7680)
transcriber.stop()
except Exception as e:
print(e)
finally:
transcriber.close()
else:
print("token expired")
def judging_expire_time(app_id, app_secret, extime):
global token
token_file = "SpeechTranscriber_token.txt"
new_time = time.time()
if not os.path.exists(token_file):
client.get_token(app_id, app_secret, token_file)
with open(token_file, "r", encoding="utf-8") as fr:
token_info = eval(fr.read())
old_time = token_info['time']
token = token_info['token']
flag = True
if new_time - old_time > 60 * 60 * 24 * (extime - 1):
flag, _ = client.get_token(app_id, app_secret, token_file)
if flag:
flag = True
pass
else:
for i in range(7):
flag, _ = client.get_token(app_id, app_secret, token_file)
if flag is not None:
flag = True
break
return flag
def channels_split_solution(audio_path, right_path, left_path, **kwargs):
client = kwargs.get('client')
appid = kwargs.get('app_id')
appsecret = kwargs.get('app_secret')
langtype = kwargs.get('lang_type')
remove_audio = kwargs.get('rm_audio', True)
client.auto_split_audio(audio_path, right_path, left_path)
thread_list = []
right_kwargs = kwargs.copy()
right_kwargs["user_id"] = "right"
thread_r = threading.Thread(target=solution, args=(client, appid, appsecret, right_path, langtype, right_kwargs))
thread_list.append(thread_r)
left_kwargs = kwargs.copy()
left_kwargs["user_id"] = "left"
thread_l = threading.Thread(target=solution, args=(client, appid, appsecret, left_path, langtype, left_kwargs))
thread_list.append(thread_l)
for thread in thread_list:
thread.start()
for thread in thread_list:
thread.join()
if remove_audio:
try:
os.remove(right_path)
os.remove(left_path)
except Exception as ee:
print(ee)
traceback.print_exc()
if __name__ == "__main__":
client = speech_rec.SpeechClient()
# Set the level of output log information:DEBUG、INFO、WARNING、ERROR
client.set_log_level('INFO')
# Type your app_id and app_secret
app_id = "" # your app id
app_secret = "" # your app secret
audio_path = "" # audio path
lang_type = "" # lang type
field = "" # field
sample_rate = 16000 # sample rate [int] 16000 or 8000
audio_format = "" # audio format
assert app_id and app_secret and audio_path and lang_type and field and sample_rate and audio_format, "Please check args"
channel = client.get_audio_info(audio_path)['channel']
# fixme This is just a simple example, please modify it according to your needs.
if channel == 1:
kwargs = {
"field": field,
"sample_rate": sample_rate,
"audio_format": audio_format,
"user_id": "",
}
solution(client, app_id, app_secret, audio_path, lang_type, kwargs)
elif channel == 2:
# Dual channel 8K audio solution
channels_split_solution(audio_path=audio_path,
left_path=f"left.{audio_format}",
right_path=f"right.{audio_format}",
client=client,
app_id=app_id,
app_secret=app_secret,
lang_type=lang_type,
field=field,
sample_rate=sample_rate,
audio_format=audio_format,
)