はじめに
本記事の目的
Azure AI Foundry(最近名前がコロコロ変わりますね) の Speech Service は、音声テキスト変換(Speech-to-Text)、音声合成(Text-to-Speech)など、音声に関するさまざまなAI機能を提供するAzure クラウド サービスです。
一方、クラウドサービスへの通信をインターネット経由で行う場合、セキュリティ上の懸念が発生することもあります。
そこで、Azureでは「プライベートエンドポイント」を使うことで、AzureリソースへのアクセスをAzure仮想ネットワーク(VNet)内に限定し、ネットワーク経路をよりセキュアに保つことができます。
本記事では、Azure Speech Service の Text to Speech 機能を、プライベートエンドポイントを利用してセキュアに実行する方法を解説します。
さらに、Node.jsを使った音声合成(Text-to-Speech)プログラムの実装例もあわせてご紹介します。
この記事でわかること
- Azure Speech Service で Text to Speech を利用する方法
- プライベートエンドポイントの基礎と構成方法
- Node.js で実際に音声合成を行うサンプルコード
- セキュリティ強化のポイントやトラブルシューティング
対象読者
- Azure Speech Serviceを既に使ったことがあり、よりセキュアに運用したい方
- プライベートエンドポイントの設定方法を知りたい方
- Node.jsでのSpeech Service利用例を知りたい方
実際の構成手順から動作確認や注意点まで詳しく解説するので、ご興味のある方はぜひ最後までご覧ください。
1. 概要
本章では、本記事で扱うAzure Speech ServiceのText to Speech(TTS)機能とプライベートエンドポイントの概要、そして全体構成について解説します。
Azure Speech Service(Text to Speech)とは
Azure Speech Serviceは、Microsoft Azureが提供するAIサービス群「Azure AI Foundry」の一部です。その中でもText to Speech(TTS)機能は、テキストを自然な発音の音声データに変換するサービスです。さまざまな言語や話者に対応しており、多様なアプリケーションやサービスで利用することができます。
プライベートエンドポイントとは
通常、AzureのPaaSサービス(Speech ServiceやStorageなど)へアクセスする場合、通信はパブリックインターネット経由で行われます。しかし、パブリック経由ではセキュリティやネットワーク制約上の不安が生じるケースもあります。
「プライベートエンドポイント」とは、Azure上のPaaSサービスに対して仮想ネットワーク(VNet)から専用のプライベートIPアドレスでアクセスできる仕組みです。これにより、インターネットを経由せず社内や閉域ネットワークから直接サービスへ安全にアクセスできます。また、アクセス制限や監査も柔軟に行えるようになります。
システム全体の構成
本記事では、以下のような構成でText to Speechを実行します。
仮想ネットワーク(VNet)内、もしくはそれに接続した環境からアクセス
プライベートエンドポイントを経由してSpeech Serviceへ通信
インターネットを経由せず、セキュアな経路でText to Speech(TTS)機能を利用
本記事では、この構成の構築手順から、Node.jsによるAPI利用方法まで順を追って解説していきます。
2. 事前準備
Text to Speech機能をプライベートエンドポイント経由で利用するためには、いくつかのAzureリソースやネットワーク設定が事前に必要です。本章では必要なリソースやその作成手順、設定ポイントについて解説します。
2.1 予め必要なもの
-
Azure サブスクリプション及びAzure Account
無料で作成できます。Azureポータルにアクセスし、必要なリソースの作成・設定ができる権限を持ったアカウントが必要です。 -
仮想ネットワーク(VNet)とサブネット
プライベートエンドポイント用に、Azure上に仮想ネットワーク(VNet)と、その中にサブネットを作成しておきます。 -
プログラムを実行するVM
仮想ネットワーク上に展開しているVM。このVMからプライベートエンドポイントを経由してSpeech Serviceのリソースにアクセスします。
2.2 作成するもの
-
Azure Speech Service
Azure portal で音声用の Azure Speech Service リソースを作成します。
Speech リソース キーとリージョンを取得します。 音声リソースがデプロイされたら、[リソースに移動] を選択して、キーを表示および管理します。 -
Private endpoint
仮想ネットワーク(VNet)から専用のプライベートIPアドレスでアクセスするための機能です。
2.3 Azureリソースの作成手順
Azure Speech Serviceの作成
Private endpointの作成
1.SpeechリソースのCustom Domain Nameを作成する
一度作成すると元に戻せないので注意
左側のペインの [リソース管理] グループで、 [Network] を選択します。
[ファイアウォールと仮想ネットワーク] タブで、 [Generate Custom Domain Name] を選択します。

新しい右パネルが開き、リソースの一意のカスタム サブドメインを作成する手順が示されます。
[カスタム ドメイン名の生成] パネルで、カスタム ドメイン名を入力します。
完全なカスタム ドメインは、https://{your custom name}.cognitiveservices.azure.com のようになります。
リソース名を入力するのが一般的なのかなと思います。
カスタム ドメイン名を入力した後、 [Save] を選択します。

操作が終わったら、 [リソース管理] グループで [Keys and Endpoint] を選択します。
リソースの新しいエンドポイント名が次のように始まっていることを確認します: https://{your custom name}.cognitiveservices.azure.com。

2.プライベート エンドポイントを作成する
プライベートエンドポイントに設定する値は以下となります
| 設定 | 価値 |
|---|---|
| リソースの種類 | Microsoft.CognitiveServices/accounts |
| リソース | <あなたのスピーチリソース名> |
| ターゲットサブリソース | Account |
左側のペインの [リソース管理] グループで、 [Network] を選択します。
[Privat endpoint connections]タブを選択します。
[+Privat endpoint]から新規プライベートエンドポイントを作成します。

Basicsの項目を入力します。
Reginは仮想ネットワークと同じRegionを設定してください

上記表にあった項目を選択します。

対象の仮想ネットワークを選択します。

Private DNS ゾーンは名前解決を簡易にするためにも作成しておいた方が無難です。

[Review+create]からリソースを作成します。

3.パブリックネットワークアクセスを無効にする
左側のペインの [リソース管理] グループで、 [Network] を選択します。
[Firewalls and virtual networks]タブで[Disabled]を選択し、[Save]します。

DNSトラブルに注意
プライベートエンドポイント有効時にDNS設定が正しくされていないと、サービス名解決やアクセスに失敗する場合があります。エンドポイントのnslookupやdig、コマンドラインからの疎通確認をおすすめします。
2.4 開発環境の準備
1.synthesis-quickstart新しいフォルダーを作成し、次のコマンドを使用してクイック スタート フォルダーに移動します。
mkdir synthesis-quickstart && cd synthesis-quickstart
2.次のコマンドで package.json を作成します。
npm init -y
3.次のコマンドを使用して Speech SDK for JavaScript をインストールします。
npm install microsoft-cognitiveservices-speech-sdk
2.5 APIキーやエンドポイント情報の取得
Azureポータル>Speechリソース>「キーとエンドポイント」からリソースの情報を取得します。
APIキー
プライベートエンドポイントのFQDN
3. Node.jsでのText to Speech実装
以下のクイックスタートのサンプルコードをベースとします。
SDKのLogを取得するためのコードを追加します。
Diagnostics.SetLoggingLevel(LogLevel.Debug);
Diagnostics.SetLogOutputPath("log.txt");
プライベートエンドポイントでwebsocket通信をするコードを以下のドキュメントから取得します。
const SPEECH_ENDPOINT = "wss://250725-speech-aa.cognitiveservices.azure.com/tts/cognitiveservices/websocket/v1"
const SPEECH_KEY = "xxx"
const speechConfig = SpeechConfig.fromEndpoint(new URL(SPEECH_ENDPOINT), SPEECH_KEY);
//完成されたコードはこちら
import { createInterface } from "readline";
import { SpeechConfig, AudioConfig, SpeechSynthesizer, ResultReason,Diagnostics,LogLevel } from "microsoft-cognitiveservices-speech-sdk";
function synthesizeSpeech() {
const audioFile = "YourAudioFile.wav";
// This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
const SPEECH_ENDPOINT = "wss://250725-speech-aa.cognitiveservices.azure.com/tts/cognitiveservices/websocket/v1"
const SPEECH_KEY = "xxx"
const speechConfig = SpeechConfig.fromEndpoint(new URL(SPEECH_ENDPOINT), SPEECH_KEY);
const audioConfig = AudioConfig.fromAudioFileOutput(audioFile);
//log
Diagnostics.SetLoggingLevel(LogLevel.Debug);
Diagnostics.SetLogOutputPath("log.txt");
// The language of the voice that speaks.
speechConfig.speechSynthesisVoiceName = "en-US-AvaMultilingualNeural";
// Create the speech synthesizer.
const synthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
const rl = createInterface({
input: process.stdin,
output: process.stdout
});
rl.question("Enter some text that you want to speak >\n> ", function (text) {
rl.close();
// Start the synthesizer and wait for a result.
synthesizer.speakTextAsync(text, function (result) {
if (result.reason === ResultReason.SynthesizingAudioCompleted) {
console.log("synthesis finished.");
}
else {
console.error("Speech synthesis canceled, " + result.errorDetails +
"\nDid you set the speech resource key and region values?");
}
synthesizer.close();
}, function (err) {
console.trace("err - " + err);
synthesizer.close();
});
console.log("Now synthesizing to: " + audioFile);
});
}
synthesizeSpeech();
コンソールから以下のコマンドを実行することで試すことが可能。
node synthesis.js
Log出力の部分は省略しますが、以下の様な形で出力されます。
「I'm excited to try text to speech」と入力することで「I'm excited to try text to speech」と話している音声データがYourAudioFile.wavとして出力されます。
Enter some text that you want to speak >
> I'm excited to try text to speech
Now synthesizing to: YourAudioFile.wav
synthesis finished.
4.ハマったところ
websocket通信の場合、カスタムエンドポイントだけでは通信ができない。
以下の様な、ネットワークのエラーとなりSDKのログに出力される。
privMessage: Received network error or non-101 status code. | privType: error
その為、インフラ周りを整理したのち、実行することが望まれる。
Azure Speech Serviceは他のAzure AI Foundry製品と比べてプライベートエンドポイント化した時の制御に癖がある。その為、うまくいかない場合、ドキュメント通りの手順でやっているか今一度確認することをお勧めします。
5. まとめ
本記事では、Azure Speech Service の Text to Speech(TTS)をプライベートエンドポイント経由で利用する方法について、ポイントを押さえながら解説しました。
Node.jsを使ったサンプル実装も交え、より実践的な形で導入方法を示しました。
セキュリティと利便性のバランスを保ちつつ、Azure Speech Serviceをより安心して活用していきましょう。ご参考になれば幸いです!
6. 補足
CRLの関連で、接続ができない事もあります。
その際は、CRL の配布ポイント (URL) へアクセスを許可するか、CRL の確認を無効化することが必要です。
無効化する方法など以下のドキュメントを参照ください。





