この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
MicrosoftのCognitive Services APIs(マイクロソフト認知サービスAPI)では、AI技術を利用した、たくさんのサービスが提供されていますが、Translator APIは、そのうちの翻訳に関するものです。
https://www.microsoft.com/cognitive-services/en-us/translator-api
Translator APIでは、「テキスト」を入力とするものと、「音声」を入力とするものが提供されていますが、現在では、どちらも日本語に対応しています。
「音声から音声への翻訳」というニーズの場合は、Text Translation APIでは、別途、「音声」から「テキスト」への変換が必要になるため、断然、Speech Translation APIの方がお勧めとなるでしょう。
また、Speech Translation APIでは、入出力が「音声」になるだけでなく、入力(翻訳前)と出力(翻訳後)の内容を「テキスト」として取り出せるので、軽易に表示等に利用することもできます。
下図は、Speech Translation APIにおける処理の流れです。
https://www.microsoft.com/ja-jp/translator/speech.aspxより
今回は、このSpeech Translation API をiOS (Swift 3) で動作させて見ましたので、その紹介をさせて下さい。
最初に、作成したサンプルアプリを操作している様子です。下のセグメンテッドスイッチで、翻訳の言語を指定し、あとはボタンを押して話すだけです。
2 アプリの登録
Speech Translation APIを利用するためには、アプリの登録が必要です。
(1) リソ一スの作成
Microsoft Azureのポータルサイトにログインし、新規 > Intelligence + analytics > Cognitive Services APIs(プレビュー) とたどります。
Account name 、Resource group に、適当な名前を指定し、API typeでTranslator Speech APIを選択します。
なお、価格レベルについては、初めて利用する場合は、F0を選択すると、2時間/月まで無料で試すことができます。
https://azure.microsoft.com/ja-jp/pricing/details/cognitive-services/translator-speech-api/ より
(2) KEYの取得
すべてのリソース から、作成したリソースを選択します。
Keysを選択して表示されるKEY 1 及び KEY 2 が、次の認証トークンを取得する処理で必要になります。
3 認証トークン
Speech Translator API を呼び出すたびに認証トークンが必要です。
認証トークンは、パラメータ(Subscription-Key)に、先程のKEY (KEY 1若しくはKEY 2のどちらでも良い) を指定して取得できます。(有効期間は10分間)
下記は、認証トークンを取得している例です。
fileprivate var tokenString = ""
func token(completionHandler: @escaping (String) -> Void) {
if tokenString != "" {
completionHandler(tokenString)
}
let key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
let url = "https://api.cognitive.microsoft.com/sts/v1.0/issueToken?Subscription-Key=\(key)"
let request = NSMutableURLRequest(url: NSURL(string: url)! as URL)
request.httpMethod = "POST"
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {data, response, error in
if (error == nil) {
let str = String(data: data!, encoding: .utf8)
if str != nil {
self.tokenString = str!
completionHandler(str!)
} else {
completionHandler("ERROR: Failed to convert to String")
}
} else {
completionHandler("ERROR: \(error.debugDescription)"
}
})
task.resume()
}
参考:Cognitive Services DocumentationAuthentication Token API
4 Starscream
Speech Translation APIのエンドポイントは、WebSocket で提供されています。SwiftでWebSocketを扱う場合、Starscreamというフレームワークがあり、これを利用させて頂くのが簡単でお薦めです。
Starscreamは、CocoaPodsで組み込み可能ですが、現在のmasterは、まだ、Swift 3.0 対応となっていません。
最新のXcode 8.3を利用する場合は、Siwft 3.1一択となってしまいますが、この場合、swift3というブランチが利用可能です。
pod 'Starscream',:git => 'https://github.com/daltoniam/Starscream', :branch => 'swift3'
5 APIの使い方
(1) エンドポイントへのアクセス
Speech Translation APIの基本的な使用例は、下記のとおりです。
GET wss://dev.microsofttranslator.com/speech/translate?from=en-US&to=it-IT&features=texttospeech&voice=it-IT-Elsa&api-version=1.0
Authorization: Bearer {access token}
X-ClientTraceId: {GUID}
そして、これを、Starscreamフレームワークを利用してSwiftで記述すると、次のようになります。
let to = "en"
let from = "ja"
let features = "partial,texttospeech"
let url = URL(string: "wss://dev.microsofttranslator.com/speech/translate?from=\(from)&to=\(to)&features=\(features)&api-version=1.0")
socket = WebSocket(url: url!, protocols: nil)
socket.headers["Authorization"] = "Bearer " + (tokenString as String)
socket.headers["X-ClientTraceId"] = UUID.init().uuidString
socket.delegate = self
socket.connect()
ヘッダ Authorizationに設定しているのは、認証トークンです。パラメータ features に TextToSpeechを設定しておくと、翻訳後の音声も取得できます。
(2) オーディオ送信
翻訳したい音声データは、RIFFフォーマットでクライアントからサーバへ送信されますが、その内容は、RIFFヘッダ、fmtチャンク、dataチャンクの順で並んでいます。 最初にデータを生成するためのクラスとして、下記のようなものを作成しました。[UInt8]のバッファに文字列や数値を順に配置して、最後にDataで受け取るクラスです。
class Buffer {
var offset = 0
var buffer: [UInt8]
init(size: Int) {
buffer = [UInt8](repeating : 0, count : size)
}
func append(short: Int16) {
(0..<2).forEach { buffer[$0 + offset] = UInt8((Int(short) >> ($0 * 8)) & 0xff) }
offset += 2
}
func append(int: Int) {
(0..<4).forEach { buffer[$0 + offset] = UInt8((int >> ($0 * 8)) & 0xff) }
offset += 4
}
func append(_ str: String) {
str.utf8.enumerated().forEach { buffer[$0 + offset] = $1 }
offset += str.utf8.count
}
var data: Data {
return Data(bytes: buffer)
}
}
そして、上記のクラスを利用して、各チャンクを生成しているコードは下記のとおりです。
//Riff Chunk
fileprivate func riff() -> Data {
let size = 4
let buffer = Buffer(size: size + 8)
buffer.append("RIFF")
buffer.append(int: size)
buffer.append("WAVE")
return buffer.data
}
// Wave Format Chunk
fileprivate func waveFormat() -> Data {
let size = 16
let buffer = Buffer(size: size + 8)
buffer.append("fmt ")
buffer.append(int: size)
buffer.append(short: 1) // Audio Format
buffer.append(short: 1) // Channels
buffer.append(int: 16000) // SamplePerSecond
buffer.append(int: 32000) // BytesPerSecond
buffer.append(short: 2) // BlockAlign
buffer.append(short: 16) // BitsPerSample
return buffer.data
}
// Wave Data Chunk (Header)
fileprivate func dataHeader(count: Int) -> Data {
let buffer = Buffer(size: 8)
buffer.append("data")
buffer.append(int: count)
return buffer.data
}
そして、サーバとの接続完了後に、これを送信しているコードです。
func websocketDidConnect(_ socket: WebSocket) {
let channels = UnsafeBufferPointer(start: audioFileBuffer?.int16ChannelData, count: 1)
let length = Int((audioFileBuffer?.frameCapacity)! * (audioFileBuffer?.format.streamDescription.pointee.mBytesPerFrame)!)
let audioData = NSData(bytes: channels[0], length: length)
if length > 50000 { // これ以下のサイズは、エラーとして送信しない
socket.write(data: riff())
socket.write(data: waveFormat())
socket.write(data: dataHeader(count: length))
socket.write(data: audioData as Data)
socket.write(data: Buffer(size: 100000).data) // 最後に、いくらかの0データを送る必要がある
} else {
socket.disconnect()
}
}
送受信処理は、StarscreamのWebSocketDelegateの各メソッドで実装しています。 コードを置きましたので、不明な点があればご参照ください。
[GitHub] https://github.com/furuya02/TranslatorSpeechAPISample
参考: Documentation Translation Speech API
6 最後に
今回は、Speech Translation APIについて、試してみましたが、非常に流暢で、かつ、優れていると実感しました。
時間を見つけて、Microsoftの Cognitive Services APIs の他の「認知」サービスも、色々試してみたいと思います。
7 参考リンク
最大100人まで同時通訳ーーMS、日本語の音声リアルタイム翻訳を提供開始
Microsoft 機械翻訳
Translator API を使い始める
Microsoft Translator のよくあるご質問
MicrosoftTranslator/InfoCenter-Speech-To-Speech-IOS-Swift
Microsoft Translator Documentation
Speech Translation API Document
StarScream
[iOS] 翻訳機能付Twitterクライアント
ios