【第1回】REST APIとは?EXCEL VBAでVOICEVOXで喋らせる事ができる!

REST API

はじめに

「REST APIって聞いたことはあるけど、難しそう」「初心者には無理かも」と思っていませんか?
実は、REST APIを使えば、今すぐ便利な機能を実現することができます。そして驚くことに、Excel VBAでもREST APIを活用できるのです!

この記事では、REST APIの基本を解説しつつ、Excel VBAを使った音声合成のサンプルコードをご紹介します。便利さを実感しながら、REST APIの世界を覗いてみましょう!

REST APIを使えるようになると、どんなことができるのか?

世の中には便利なツールやサービスがたくさんあります。そして、多くのサービスがREST APIを公開しています。このREST APIを使えば、自分でイチから作らなくても、その機能をすぐに使うことができるのです。

こんなことが簡単にできる!

  • 天気予報APIを使えば、現在の天気や予報をリアルタイムで取得可能。
  • 音声合成APIを活用して、自動でナレーション付き動画を生成。
  • 翻訳APIを使って文章を多言語に変換。

REST APIは、便利な機能を自分のアプリに取り込むための強力なツールです!

REST APIとは何なのか?

  • API(Application Programming Interface)とは?
    アプリ同士が情報をやりとりするための仕組み。
  • REST APIとは?
    REST(Representational State Transfer)は、シンプルで統一されたデータ通信の規格です。

    • HTTPを使う: GET、POSTなどのメソッドを使用。
    • URLで操作対象を指定: APIのエンドポイントにアクセス。
    • JSON形式でデータやりとり: 軽量なフォーマットでサーバーと通信。

REST APIとRESTful APIの違い

「REST API」と「RESTful API」という言葉を耳にすることがあると思いますが、この2つには微妙な違いがあります。

RESTful APIとは?

  • 「RESTful」とは、RESTの原則に忠実であることを指す言葉です。
    RESTの原則には、以下のようなルールがあります:

    1. クライアントとサーバーの分離: クライアントはサーバーに直接関与せず、リクエストだけを送る。
    2. ステートレス性: サーバーはクライアントの状態を記憶せず、全てのリクエストが独立している。
    3. 統一インターフェース: HTTPメソッド(GET、POSTなど)を一貫して使う。
    4. リソースの明確な識別: 各リソースが一意のURIで識別される。

これらのルールに従ったAPIが「RESTful API」と呼ばれます。

REST APIとは?

  • 「REST API」とは、RESTの原則を参考にしたAPIを指します。
    ただし、RESTの全ての原則に従う必要はなく、部分的に適用しているだけでもREST APIと呼ばれることがあります。

サンプルコードで学ぶREST API

ここでは、VOICEVOXのREST APIを使って、Excel VBAで音声ファイルを生成するプログラムを紹介します。

全体の流れ

  1. Excelのセルに音声化したい文章を入力。
  2. VBAがREST APIを使って音声を生成。
  3. 音声ファイルを出力し、ファイル名をセルに記載。

VOICEVOXを使ってREST APIを体験しよう(サンプルコード)

以下に、REST APIを使ったリクエストとレスポンスの処理を含む完全なコードを掲載します。

REST APIでテキストを音声に変換する

以下は、VOICEVOXのREST APIを利用してテキストから音声を生成する簡単なサンプルです。

必要な環境

  • VOICEVOXエンジンをローカルで実行していること(公式サイトからダウンロード可能)。
  • EXCELがインストールされていること。
  • こんな感じのシートを作成してA列に数値、B列にセリフを入れる(C列は自動で入力されます)

REST APIを使ったVBAの例

Option Explicit

' 定数定義
Const SPEAKER_ID_ZUNDAMON As Integer = 1 ' ずんだもんのスピーカーID
Const OUTPUT_DIR As String = "\output\" ' 出力ディレクトリ
Const API_BASE_URL As String = "http://localhost:50021/" ' REST APIベースURL

'-------------------------------------------------------------------
' 関数名: VoiceVoxBatchExecute
' 機能: ワークシートに入力されたテキストを順に音声合成し、結果をユーザーに通知する
' 引数: なし
' 戻り値: なし
'-------------------------------------------------------------------
Sub VoiceVoxBatchExecute()
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim i As Long
    Dim text As String
    Dim outputDir As String
    
    ' 使用するシート(必要に応じて変更)
    Set ws = ThisWorkbook.Sheets(1)
    
    ' 最終行を取得
    lastRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).row
    
    ' 出力ディレクトリ設定
    outputDir = ThisWorkbook.Path & OUTPUT_DIR
    If Dir(outputDir, vbDirectory) = "" Then MkDir outputDir

    On Error GoTo ErrorHandler ' エラーハンドリング開始

    ' 2行目から処理開始
    For i = 2 To lastRow
        Application.StatusBar = "Processing row " & i & " of " & lastRow
        
        ' テキストの取得とクリーンアップ
        text = Trim(ws.Cells(i, "B").Value)
        text = CleanText(text)
        
        ' テキストが空の場合は終了
        If Len(text) = 0 Then Exit For
        
        ' 音声クエリ生成・合成・出力の実行
        Call ProcessVoiceVoxText(ws, i, text, SPEAKER_ID_ZUNDAMON, outputDir)
    Next i
    
    Application.StatusBar = False
    MsgBox "すべての処理が完了しました!"
    Exit Sub ' 正常終了

ErrorHandler:
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical, "エラー"
    Application.StatusBar = False
End Sub

'-------------------------------------------------------------------
' 関数名: ProcessVoiceVoxText
' 機能: 音声クエリの生成、合成、ファイル出力をまとめて処理する
' 引数:
'   in ws (Worksheet): 対象のワークシート
'   in row (Long): 処理中の行番号
'   in text (String): 音声合成するテキスト
'   in speaker (Integer): 話者のID
'   in outputDir (String): 出力ディレクトリのパス
' 戻り値: なし
'-------------------------------------------------------------------
Sub ProcessVoiceVoxText(ws As Worksheet, row As Long, text As String, speaker As Integer, outputDir As String)
    Dim http As Object
    Dim audioQuery As String
    Dim outputFileName As String
    
    ' HTTPオブジェクト作成
    Set http = CreateObject("MSXML2.XMLHTTP")
    
    ' 音声クエリ生成
    audioQuery = GenerateAudioQuery(http, speaker, text)
    
    ' 音声ファイル名を生成
    outputFileName = ws.Cells(row, "A").Value & "_" & Format(Now, "yyyymmdd_HHMMSS") & ".wav"
    
    ' 音声合成とファイル出力
    SynthesizeAndSaveWAV http, audioQuery, speaker, outputDir & outputFileName
    
    ' 成功時にセルにファイル名を記載
    ws.Cells(row, "C").Value = outputFileName
End Sub

'-------------------------------------------------------------------
' 関数名: GenerateAudioQuery
' 機能: REST APIを使って音声クエリを生成する
' 引数:
'   in http (Object): HTTPリクエスト用のオブジェクト
'   in speaker (Integer): 話者のID
'   in text (String): 音声合成するテキスト
' 戻り値:
'   out (String): 音声クエリのJSON文字列
'-------------------------------------------------------------------
Function GenerateAudioQuery(http As Object, speaker As Integer, text As String) As String
    Dim queryURL As String
    Dim responseText As String

    queryURL = API_BASE_URL & "audio_query?text=" & WorksheetFunction.EncodeURL(text) & "&speaker=" & speaker
    
    On Error Resume Next
    http.Open "POST", queryURL, False
    http.setRequestHeader "accept", "application/json"
    http.Send
    On Error GoTo 0

    If http.Status = 200 Then
        responseText = http.responseText
        GenerateAudioQuery = responseText
    Else
        Err.Raise vbObjectError + 1, "GenerateAudioQuery", _
                  "[Error] 音声クエリ生成に失敗しました。Status: " & http.Status & _
                  ", Response: " & http.responseText
    End If
End Function

'-------------------------------------------------------------------
' 関数名: SynthesizeAndSaveWAV
' 機能: REST APIを使って音声を合成し、WAVファイルとして保存する
' 引数:
'   in http (Object): HTTPリクエスト用のオブジェクト
'   in audioQuery (String): 音声クエリのJSON文字列
'   in speaker (Integer): 話者のID
'   in outputFilePath (String): 出力ファイルのパス
' 戻り値: なし
'-------------------------------------------------------------------
Sub SynthesizeAndSaveWAV(http As Object, audioQuery As String, speaker As Integer, outputFilePath As String)
    Dim synthesisURL As String
    Dim responseBody As Variant
    synthesisURL = API_BASE_URL & "synthesis?speaker=" & speaker & "&enable_interrogative_upspeak=true"
    
    http.Open "POST", synthesisURL, False
    http.setRequestHeader "accept", "audio/wav"
    http.setRequestHeader "Content-Type", "application/json"
    http.Send audioQuery

    If http.Status = 200 Then
        responseBody = http.responseBody
        SaveBinaryDataWithWAVHeader responseBody, outputFilePath
    Else
        Err.Raise vbObjectError + 2, "SynthesizeAndSaveWAV", _
                  "[Error] 音声合成に失敗しました。Status: " & http.Status & _
                  ", Response: " & http.responseText
    End If
End Sub

'-------------------------------------------------------------------
' 関数名: SaveBinaryDataWithWAVHeader
' 機能: 音声データに正しいWAVフォーマットのヘッダーを追加し、ファイルに保存する
' 引数:
'   in responseBody (Variant): 音声データのバイナリ
'   in outputFilePath (String): 出力ファイルのパス
' 戻り値: なし
'-------------------------------------------------------------------
Sub SaveBinaryDataWithWAVHeader(responseBody As Variant, outputFilePath As String)
    Dim fileNum As Integer
    Dim wavHeader As String
    Dim dataSize As Long

    ' WAVフォーマットの正しいヘッダーを作成
    wavHeader = "52494646" & _
                "50814501" & _
                "57415645" & _
                "666d7420" & _
                "10000000" & _
                "01000100" & _
                "c05d0000" & _
                "80bb0000" & _
                "02001000" & _
                "64617461"

    ' データサイズを計算
    dataSize = LenB(responseBody)
    wavHeader = wavHeader & Right("00000000" & Hex(dataSize), 8)

    ' ファイルにヘッダーとデータを書き込む
    fileNum = FreeFile
    Open outputFilePath For Binary Access Write As #fileNum
    Put #fileNum, , HexToBinary(wavHeader)
    Put #fileNum, , responseBody
    Close #fileNum
End Sub

'-------------------------------------------------------------------
' 関数名: HexToBinary
' 機能: 16進文字列をバイナリデータに変換する
' 引数:
'   in hexString (String): 16進数形式の文字列
' 戻り値:
'   out (Byte()): バイナリデータ配列
'-------------------------------------------------------------------
Function HexToBinary(hexString As String) As Byte()
    Dim binaryData() As Byte
    Dim i As Long
    ReDim binaryData(Len(hexString) \ 2 - 1)
    For i = 0 To UBound(binaryData)
        binaryData(i) = CByte("&H" & Mid(hexString, i * 2 + 1, 2))
    Next i
    HexToBinary = binaryData
End Function

'-------------------------------------------------------------------
' 関数名: CleanText
' 機能: テキストから改行やエスケープ文字を削除する
' 引数:
'   in text (String): 入力テキスト
' 戻り値:
'   out (String): クリーンアップされたテキスト
'-------------------------------------------------------------------
Function CleanText(text As String) As String
    Dim tempText As String
    tempText = Replace(text, vbCr, "")
    tempText = Replace(tempText, vbLf, "")
    tempText = Replace(tempText, "\", "")
    CleanText = tempText
End Function

REST APIを使った重要な処理

このセクションでは、REST APIを使ったサンプルプログラムの中で特に重要なポイントをピックアップし、詳細に解説します。

1. リクエスト生成

リクエストURLを生成し、APIエンドポイントを呼び出す準備をする処理です。以下は、音声クエリ生成時の例です。

Function GenerateAudioQuery(http As Object, speakerId As Integer, text As String) As String
    Dim queryURL As String
    queryURL = "http://localhost:50021/audio_query?text=" & WorksheetFunction.EncodeURL(text) & "&speaker=" & speakerId
    Debug.Print "Request URL: " & queryURL
  • リクエストURL: REST APIのエンドポイント(例: /audio_query)を指定。
  • クエリパラメータ: text(セリフ)や speaker(話者ID)をURLに含めます。

2. REST API呼び出し

リクエストを送信する重要な部分です。

http.Open "POST", queryURL, False
http.setRequestHeader "accept", "application/json"
http.Send
  • http.Open: HTTPメソッド(POST)とエンドポイントURLを指定。
  • ヘッダー設定: accept ヘッダーで、受け取るデータ形式を application/json に指定。
  • http.Send: リクエストを送信。

3. レスポンス受け取り

サーバーからのレスポンスを取得します。

If http.Status = 200 Then
    responseText = http.responseText
    Debug.Print "Response: " & responseText
    GenerateAudioQuery = responseText
Else
    MsgBox "[Error] 音声クエリ生成失敗: " & http.Status
    GenerateAudioQuery = ""
End If
  • http.Status: サーバーのレスポンスコードを確認し、200(成功)であることをチェック。
  • http.responseText: サーバーから返されたJSON形式のデータを取得。

4. 音声データ(バイナリ)処理

音声データを生成するリクエストを送信し、サーバーから受け取った音声データを保存します。

リクエスト生成と送信

synthesisURL = "http://localhost:50021/synthesis?speaker=" & speakerId
http.Open "POST", synthesisURL, False
http.setRequestHeader "accept", "audio/wav"
http.setRequestHeader "Content-Type", "application/json"
http.Send audioQuery
  • URLとメソッドの指定: 音声生成エンドポイント(例: /synthesis)。
  • ヘッダー設定:
    • accept: audio/wav(音声データ形式を受け取る指定)。
    • Content-Type: リクエストデータがJSON形式であることを指定。
  • リクエストボディ: audioQuery を送信。

レスポンス(音声データ)の受け取り

If http.Status = 200 Then
    responseBody = http.responseBody
    SaveAudioFile responseBody, outputFilePath
    Debug.Print "Audio File Saved: " & outputFilePath

http.responseBody: サーバーから返された音声データ(バイナリ形式)を取得。

  • ファイル保存処理: 受け取った音声データをWAVファイルとして保存。

まとめ

サンプルプログラム内でREST APIを使った重要な処理は以下の通りです:

  1. リクエスト生成
    エンドポイントとクエリパラメータを指定してURLを組み立てる。
  2. REST API呼び出し
    HTTPメソッド(GETやPOST)とヘッダーを設定してリクエストを送信。
  3. レスポンス受け取り
    サーバーからのデータを確認し、レスポンス(JSONや音声データ)を取得。
  4. ファイル保存
    音声データをWAV形式で保存し、アプリケーションで利用可能にする。

次回予告:REST APIのリクエストとレスポンスを理解する

REST APIの世界を本格的に使いこなすには、リクエストとレスポンスの基本構造やデータの流れを正確に理解することが重要です。
次回は、以下の内容を中心に解説します。

次回の主な内容

  • REST APIの基本構造を知る
    REST APIの仕組みと動作の全体像を整理します。
    クライアントとサーバー間の役割分担を理解。
  • HTTPメソッドの解説(GET, POST, PUT, DELETE)
    各メソッドの役割や使いどころを解説。
    実際にどのような場面で使われるのか、具体例を交えて学びます。
  • リクエストの基本構造
    URLの役割やヘッダー、ボディの内容を分解して説明。
  • レスポンスの基本構造
    ステータスコード、レスポンスヘッダー、ボディの役割を理解。
    サーバーから返されるデータを正しく扱う方法を学びます。
  • データ形式の違いを理解する(JSONとXML)
    REST APIでよく使われるデータ形式の違いを解説。
    JSONを使ったデータやりとりの実例を紹介。
  • 実例で学ぶ:ブラウザとREST APIの共通点と違い
    REST APIの仕組みをブラウザとの対比で直感的に理解。
    ブラウザでのデータ取得と、プログラムでのデータ取得の違いを具体化。

なぜ次回この内容なのか?
今回の講座では、REST APIを「実際に使ってみる」ことを体験しました。次回は、REST APIを本格的に使いこなすために必要な「仕組み」を深く理解し、基礎を固めることが目的です。

次回も学べることが盛りだくさん!
次回の内容を学べば、REST APIの仕組みをより深く理解し、どのようなサービスでも応用できる基礎を確立できます。初心者の方でも無理なく進められるように丁寧に解説するので、ぜひご期待ください!

コメント

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