前回に引き続き、HOYAサービス株式会社様が公開されている「VoiceText Web API」をVBAマクロから使ってみる話です。
このAPIの使い方は前回の記事通りで、基本的にAPIのURLにパラメーターを付けてリクエストを送るだけです。非常に簡単です。
ただ、前回載せたコードは単に動作確認するためのコードなので、今回は使いやすいように引数でパラメーターを指定できるようにしたいと思います。
・・・というわけで、書いたコードが下記になります。
Option Explicit Private Declare Function mciSendString Lib "winmm" Alias "mciSendStringA" ( _ ByVal lpstrCommand As String, _ ByVal lpstrReturnString As String, _ ByVal uReturnLength As Long, _ ByVal hwndCallback As Long) As Long Public Sub Sample() PlayVoiceText "あいうえお", "haruka", "happiness", 2, 50, 200, 50 PlayVoiceText "かきくけこ", "show", , , 150, 400, 200 PlayVoiceText "さしすせそ", "hikari", "sadness", 1, 140, 300, 80 End Sub Public Sub PlayVoiceText(ByVal txt As String, _ ByVal speaker As String, _ Optional ByVal emotion As String = "", _ Optional ByVal emotion_level As Long = 1, _ Optional ByVal pitch As Long = 100, _ Optional ByVal speed As Long = 100, _ Optional ByVal volume As Long = 100) 'VoiceText Web APIを使ってテキスト読み上げ Dim url As String Dim dat As Variant Dim body() As Byte Dim pathTempFolder As String Dim pathWavFile As String Const adTypeBinary = 1 Const API_KEY As String = "(APIキー)" 'コードを動かす際はここに受け取ったAPIキーを記載します。 'パラメーターチェック txt = DelBreak(txt) If Len(txt) < 1 Then MsgBox "読み上げるテキストを指定してください。", vbExclamation + vbSystemModal Exit Sub End If If Len(txt) > 200 Then MsgBox "読み上げるテキストは200文字以内にしてください。", vbExclamation + vbSystemModal Exit Sub End If speaker = LCase(speaker) Select Case speaker Case "show", "haruka", "hikari", "takeru" Case Else MsgBox "「speaker」には" & vbCrLf & vbCrLf & _ "show" & vbCrLf & _ "haruka" & vbCrLf & _ "hikari" & vbCrLf & _ "takeru" & vbCrLf & vbCrLf & _ "以外を指定しないでください。", vbExclamation + vbSystemModal Exit Sub End Select '[emotion]を指定できるのは[show]以外 If speaker <> "show" Then emotion = LCase(emotion) If Len(emotion) > 0 Then Select Case emotion Case "happiness", "anger", "sadness" Case Else MsgBox "「emotion」には" & vbCrLf & vbCrLf & _ "happiness" & vbCrLf & _ "anger" & vbCrLf & _ "sadness" & vbCrLf & vbCrLf & _ "以外を指定しないでください。", vbExclamation + vbSystemModal Exit Sub End Select Select Case emotion_level Case 1, 2 Case Else MsgBox "「emotion_level」には" & vbCrLf & vbCrLf & _ "1" & vbCrLf & _ "2" & vbCrLf & vbCrLf & _ "以外を指定しないでください。", vbExclamation + vbSystemModal Exit Sub End Select End If End If Select Case pitch Case 50 To 200 Case Else MsgBox "「pitch」に指定できる数値の範囲は" & vbCrLf & vbCrLf & _ "50 - 200" & vbCrLf & vbCrLf & _ "です。", vbExclamation + vbSystemModal Exit Sub End Select Select Case speed Case 50 To 400 Case Else MsgBox "「speed」に指定できる数値の範囲は" & vbCrLf & vbCrLf & _ "50 - 400" & vbCrLf & vbCrLf & _ "です。", vbExclamation + vbSystemModal Exit Sub End Select Select Case volume Case 50 To 200 Case Else MsgBox "「volume」に指定できる数値の範囲は" & vbCrLf & vbCrLf & _ "50 - 200" & vbCrLf & vbCrLf & _ "です。", vbExclamation + vbSystemModal Exit Sub End Select 'パラメーター設定 url = "https://api.voicetext.jp/v1/tts" dat = "text=" & EncodeURL(txt) & "&speaker=" & speaker If speaker <> "show" Then If Len(emotion) > 0 Then dat = dat & "&emotion=" & emotion dat = dat & "&emotion_level=" & emotion_level End If End If dat = dat & "&pitch=" & pitch dat = dat & "&speed=" & speed dat = dat & "&volume=" & volume 'Debug.Print dat '確認用 'wavファイルパス設定 pathTempFolder = GetTempFolderPath If Len(Trim(pathTempFolder)) < 1 Then Exit Sub pathTempFolder = AddPathSeparator(pathTempFolder) pathWavFile = pathTempFolder & "VtwaFile.wav" 'wavファイルを事前に削除 If ChkExistsFile(pathWavFile) = True Then DelFile pathWavFile On Error GoTo Err: With CreateObject("WinHttp.WinHttpRequest.5.1") .Open "POST", url, False .SetRequestHeader "Authorization", "Basic " & EncodeBase64Str(API_KEY & ":") .SetRequestHeader "Content-Type", "application/x-www-form-urlencoded;charset=UTF-8" .Send dat Select Case .Status Case 200 body = .responseBody With CreateObject("ADODB.Stream") .Type = adTypeBinary .Open .Write body .SaveToFile pathWavFile .Close End With If ChkExistsFile(pathWavFile) = True Then 'wavファイル再生 mciSendString "Open " & Chr(34) & pathWavFile & Chr(34), "", 0, 0 mciSendString "Play " & Chr(34) & pathWavFile & Chr(34) & " wait", "", 0, 0 mciSendString "Close " & Chr(34) & pathWavFile & Chr(34), "", 0, 0 DelFile pathWavFile 'wavファイル削除 'Debug.Print "処理が終了しました。" '確認用 End If Case Else MsgBox "処理が失敗しました。" & vbCrLf & vbCrLf & .ResponseText, vbExclamation + vbSystemModal Exit Sub End Select End With On Error GoTo 0 Exit Sub Err: MsgBox "エラーが発生しました。" & vbCrLf & _ "エラー番号:" & Err.Number & vbCrLf & _ "エラー内容:" & Err.Description, vbCritical + vbSystemModal End Sub Private Sub DelFile(ByVal FilePath As String) 'ファイル削除 CreateObject("Scripting.FileSystemObject").DeleteFile FilePath, True End Sub Private Function GetTempFolderPath() As String 'Tempフォルダのパス取得 Dim ret As String ret = "" '初期化 On Error Resume Next ret = CreateObject("Scripting.FileSystemObject").GetSpecialFolder(2) On Error GoTo 0 GetTempFolderPath = ret End Function Private Function AddPathSeparator(ByVal str As String) As String 'パスの区切り文字追加 If Right(str, 1) <> ChrW(92) Then str = str & ChrW(92) AddPathSeparator = str End Function Private Function ChkExistsFile(ByVal FilePath As String) As Boolean 'ファイルの存在確認 Dim ret As Boolean ret = False '初期化 With CreateObject("Scripting.FileSystemObject") ret = .FileExists(FilePath) End With ChkExistsFile = ret End Function Private Function DelBreak(ByVal str As String) As String '改行削除 Dim ret As String ret = "" '初期化 ret = Replace(str, vbNewLine, "") ret = Replace(ret, vbCr, "") ret = Replace(ret, vbLf, "") DelBreak = ret End Function Private Function EncodeURL(ByVal str As String) As String 'URLエンコード With CreateObject("ScriptControl") .Language = "JScript" EncodeURL = .CodeObject.encodeURIComponent(str) End With End Function Private Function EncodeBase64Str(ByVal str As String) As String '文字列をBase64エンコード Dim ret As String Dim d() As Byte Const adTypeBinary = 1 Const adTypeText = 2 ret = "" '初期化 On Error Resume Next With CreateObject("ADODB.Stream") .Open .Type = adTypeText .Charset = "UTF-8" .WriteText str .Position = 0 .Type = adTypeBinary .Position = 3 d = .Read() .Close End With With CreateObject("MSXML2.DOMDocument").createElement("base64") .DataType = "bin.base64" .nodeTypedValue = d ret = .Text End With On Error GoTo 0 EncodeBase64Str = ret End Function
冗長なコードになってしまいましたが、やっていることは引数として受け取ったパラメーターをリクエストにくっつけて、受け取ったwavファイルをmciSendStringで再生しているだけです。
今回のコードも、そのままでは64ビット版のOfficeで動作しませんので、64ビット版Officeをお使いの方は注意してください。
(コード中、DirやKillを使っていないのは、単にVBScriptに移植しやすいようにしているだけです。)
何はともあれ、これでVBAからVoiceText Web APIが使いやすくなりました。
コードを追加すれば、Wordでショウ君に選択範囲を読み上げてもらったり、Excelの選択セルの内容をショウ君に読み上げてもらったりすることができます。
200文字という制限はありますが、十分にVoiceTextの性能の素晴らしさを実感することができます。
2014年8月時点ではまだβ版ということで、今後サービスの停止や有料化することも考えられますが、今はまだ遊べます試用できますので、興味がある方は是非一度お試しください。
この記事へのコメントはありません。