Azureの管理ポータルでの設定は省略。
HTMLファイルとPHPファイルのサンプル。
HTMLファイルだけで実装することも可能だが、APIを利用するためのキーの文字列をソースに入れたくないので、APIを利用する部分はPHPで実装する。
いずれのファイルもhttpdのドキュメントルート下の /cognitive/ に配置される前提。
サーバサイドは、Apache 2.2、PHP 5.3。
クライアントはHTML5 (Web Audio API)対応ブラウザ。
Windows10のChrome、Edgeで確認。IEはダメ。
text_to_speech.html
----- ここから -----
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="robots" content="noindex,nofollow" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title>Speech Service API (Text To Speech)</title>
<link rel="stylesheet" href="//stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous" />
<style>
<!--
.page-title {
color: #555555;
font-size: x-large;
font-weight: bold;
text-shadow: 1px 1px 1px #999999;
}
-->
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm-12">
<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
<a class="navbar-brand" href="/cognitive/">Cognitive Services Examples</a>
</nav>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<h3 class="page-title">Speech Service API (Text To Speech)</h3>
</div>
</div>
<br />
<div class="row">
<div class="col-sm-12">
<strong> ロケールを選択し、テキストを入力して「送信」ボタンをクリックしてください。</strong>
</div>
</div>
<br />
<div class="row">
<div class="col-sm-12">
<div class="card">
<div class="card-body">
<form id="text-to-speech-form" method="POST">
<div class="form-group row">
<label for="locale" class="col-sm-2 col-form-label">ロケール</label>
<div class="col-sm-4">
<select name="locale" id="locale" class="form-control">
<option value="ja">ja</option>
<option value="en">en</option>
</select>
</div>
</div>
<div class="form-group row">
<label for="text_for_speech" class="col-sm-2 col-form-label">テキスト</label>
<div class="col-sm-10">
<textarea name="text_for_speech" id="text_for_speech" cols="100" rows="8" class="form-control"></textarea>
</div>
</div>
<div class="form-group row">
<div class="col-sm-10 ml-sm-auto">
<button type="button" id="submit-btn" class="btn btn-primary">送信</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- javascript -->
<script src="//code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery.blockUI/2.70/jquery.blockUI.min.js" integrity="sha256-9wRM03dUw6ABCs+AU69WbK33oktrlXamEXMvxUaF+KU=" crossorigin="anonymous"></script>
<script>
(function() {
"use strict";
const root = this;
const $ = root.jQuery;
root.AudioContext = root.AudioContext || root.webkitAudioContext;
const context = new AudioContext();
// Audio 用の buffer を読み込む
const getAudioBuffer = function(url, param, fn) {
$.blockUI({
message : '<img src="/common/img/gif-load.gif" />',
css : {
color : '',
border : '',
backgroundColor : ''
},
overlayCSS : {
backgroundColor: '#FFFFFF'
}
});
const req = new XMLHttpRequest();
req.open('POST', url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.responseType = 'arraybuffer';
req.onreadystatechange = function() {
$.unblockUI();
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
context.decodeAudioData(req.response, function(buffer) {
fn(buffer);
});
}
};
param = encodeURI(param);
req.send(param);
};
// サウンドを再生
const playSound = function(buffer) {
const source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.start(0);
};
$(function() {
$('#submit-btn').on('click', function() {
if (!$('#text_for_speech').val()) {
alert('テキストを入力してください。');
return false;
}
const textForSpeech = $('#text_for_speech').val();
getAudioBuffer('/cognitive/text_to_speech.php', 'text_for_speech=' + textForSpeech + '&locale=' + $('#locale').val(), function(buffer) {
playSound(buffer);
});
});
});
}).call(this);
</script>
</body>
</html>
----- ここまで -----
text_to_speech.php
----- ここから -----
<?php
/**
* Azure Cognitive ServicesのSpeech Service API (Text To Speech) を使って
* 音声データを取得する
*/
global $php_errormsg;
$access_token_url = 'https://westus.api.cognitive.microsoft.com/sts/v1.0/issuetoken';
$api_key = 'Azure管理ポータルで取得したキー';
$tts_service_url = 'https://westus.tts.speech.microsoft.com/cognitiveservices/v1';
$user_agent = 'Azure管理ポータル上のリソース名';
$output_format = 'riff-24khz-16bit-mono-pcm';
$voice_fonts = array(
'ja' => array('ja-JP', 'ja-JP, Ichiro, Apollo'),
'en' => array('en-US', 'en-US, BenjaminRUS')
);
// リクエストパラメータの文字列を変換した音声データを取得
if (!empty($_POST['text_for_speech'])
and !empty($_POST['locale'])) {
$request = 'curl -Ss -X POST "' . $access_token_url . '"'
. ' -H "Content-type: application/x-www-form-urlencoded"'
. ' -H "Content-Length: 0"'
. ' -H "Ocp-Apim-Subscription-Key: ' . $api_key . '"';
$access_token = `$request`;
if (!$access_token) {
throw new Exception("Problem with $access_token_url, $php_errormsg");
}
else {
$locale = $_POST['locale'];
$text_for_speech = $_POST['text_for_speech'];
$voice_font_locale = $voice_fonts[$locale][0];
$voice_font = $voice_fonts[$locale][1];
$request = 'curl -Ss -X POST "' . $tts_service_url . '"'
. ' -A "' . $user_agent . '"'
. ' -H "X-Microsoft-OutputFormat: ' . $output_format . '"'
. ' -H "Content-Type: application/ssml+xml"'
. ' -H "Authorization: Bearer ' . $access_token . '"'
. ' -H "cache-control: no-cache"'
. ' --data'
. ' "<speak version=\"1.0\" xml:lang=\"' . $voice_font_locale . '\">'
. '<voice xml:lang=\"' . $voice_font_locale . '\" xml:gender=\"Male\" name=\"Microsoft Server Speech Text to Speech Voice (' . $voice_font . ')\">' . $text_for_speech . '</voice>'
. '</speak>"';
$result = `$request`;
if (!$result) {
throw new Exception("Problem with $tts_service_url, $php_errormsg");
}
else {
header('Content-Type: audio/x-wav');
header('Content-Length: ' . strlen($result));
echo $result;
}
}
}
?>
----- ここまで -----