Alexaの音声の中断を制御する
Alexaに対するスキルの応答に出力音声が含まれている場合は、新しい音声により、Alexaが現在話している音声を中断するかどうかを制御できます。このトピックでは、この動作を制御する理由とその際に使用するアトリビュートについて説明します。
概要
Alexaが現在話している音声を中断させたい場合があります。たとえば、トリビアスキル付きの点灯式プッシュボタンガジェットがあるとします。Alexaが質問している最中にユーザーがブザーを鳴らすと、Alexaに質問を中断させ、「プレイヤー1さん、答えは何ですか?」と発話させる場合があります。
また、Alexaに発話を続けさせてから、新しい音声を読み上げさせる場合もあります。先ほどの例の続きで、トリビアスキルを開始するときには、「ロールコール」としてすべてのプレイヤーに各自のボタンを押させることが考えられます。 ボタンが押されるたびに、Alexaは「こんにちは、プレイヤー[n]さん」と応答します。 この場合、Alexaには、プレイヤー1への挨拶を終えてから、プレイヤー2への挨拶を行わせます。
CustomInterfaceController
インターフェースをサポートするスキルの場合、デフォルトの動作では、Alexaは音声を中断します。そのほかのスキルの場合、デフォルトでは、音声は中断されません。この動作は、次に説明するように変更できます。
音声の中断を制御する方法
Alexaに対するスキルの応答に含まれているoutputSpeech
オブジェクトには、playBehavior
というオプションのアトリビュートが用意されています。このアトリビュートを使用して、新しい音声によりAlexaの現在の音声を中断するかどうかを制御できます。
playBehavior
は、次の3つの値のいずれかに設定できます。
ENQUEUE
: Alexaの現在の音声を中断しません。代わりに、この音声をキューの最後に追加します。CustomInterfaceController
インターフェースを使用しないすべてのスキルで、これがデフォルト値になります。REPLACE_ALL
: 現在の音声およびキューに追加された音声を置き換え、この音声の再生をすぐに開始します。CustomInterfaceController
インターフェースを使用しているすべてのスキルで、これがデフォルト値になります。REPLACE_ENQUEUED
: Alexaの現在の音声を中断しません。キューのすべての音声をこの音声に置き換えます。
デフォルトの動作が既に目的の動作である場合は、応答でplayBehavior
を設定する必要はありません。
例
このセクションでは、playBehavior
アトリビュートを使用して、Alexaが現在話している音声を中断するかどうかを制御する応答の例を示します。
playBehavior
アトリビュートの設定は、次のSDKバージョンでサポートされています。
- Node.js SDK v2.4.0以降
- Java SDK v2.11.3以降
- Python SDK v1.7.0以降
音声を中断する例
次の応答に含まれる音声では、Alexaが現在話している音声を中断し、現在キューにある音声を完全に置き換えます。
スキルがCustomInterfaceController
インターフェースをサポートしている場合、CustomInterfaceController
インターフェースをサポートするスキルではREPLACE_ALL
がデフォルト設定であるため、playBehavior
アトリビュートを設定する必要はありません。
{
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>この音声により、Alexaが現在話している音声を中断します。"/></speak>"
},
"shouldEndSession": false,
"playBehavior": "REPLACE_ALL",
"directives": [ ]
}
このサンプルコードはAlexa Skills Kit SDK for Node.js(v2)を使用しています。
const Alexa = require('ask-sdk-core');
const MyIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'MyIntent';
},
handle(handlerInput) {
const speechText = "この音声により、Alexaが現在話している音声を中断します。";
const playBehavior = "REPLACE_ALL";
// 応答を組み立てます
const response = handlerInput.responseBuilder
.speak(speechText, playBehavior)
.withShouldEndSession(false)
.getResponse();
// CloudWatchへの応答を記述します
console.log("===応答=== "+ JSON.stringify(response));
// 応答を返します
return response;
}
};
このサンプルコードはAlexa Skills Kit SDK for Javaを使用しています。
package com.amazon.ask.buttongadget.handlers;
import com.amazon.ask.dispatcher.request.handler.HandlerInput;
import com.amazon.ask.dispatcher.request.handler.RequestHandler;
import com.amazon.ask.model.Response;
import static com.amazon.ask.request.Predicates.intentName;
import java.util.Optional;
import com.amazon.ask.model.ui.PlayBehavior;
public class MyIntentHandler implements RequestHandler {
@Override
public boolean canHandle(HandlerInput handlerInput) {
return handlerInput.matches(intentName("MyIntent"));
}
@Override
public Optional<Response> handle(HandlerInput handlerInput) {
// 応答を組み立てます。
Optional<Response> response = handlerInput.getResponseBuilder()
.withSpeech("この音声により、Alexaが現在話している "
+ "音声を中断します。",
PlayBehavior.REPLACE_ALL)
.withShouldEndSession(false)
.build();
// CloudWatchへの応答を記述します。
String responseLog = response.toString();
responseLog = responseLog.replace("\n", " ").replace("\r", " ");
System.out.println("===応答=== " + responseLog);
// 応答を返します。
return response;
}
}
このサンプルコードはAlexa Skills Kit SDK for Pythonを使用しています。
from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.utils import is_intent_name
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_model.ui import PlayBehavior
from ask_sdk_model import Response
class MyIntentHandler(AbstractRequestHandler):
"""ハローワールドインテント用ハンドラー"""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return is_intent_name("MyIntent")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
# 応答を組み立てます
speech_text = ("この音声により、Alexaが現在話している"
"音声を中断します。")
play_behavior = PlayBehavior.REPLACE_ALL
handler_input.response_builder.speak(
speech=speech_text,
play_behavior=play_behavior).set_should_end_session(
False)
# CloudWatchへの応答を記述します
response = handler_input.response_builder.response
print(response)
# 応答を返します
return response
音声をキューに追加する例
次の応答に含まれる音声では、Alexaが現在話している音声を中断しません。新しい音声はキューの最後に追加されます。
スキルがCustomInterfaceController
インターフェースをサポートしていない場合、CustomInterfaceController
インターフェースをサポートしていないスキルではENQUEUE
がデフォルト設定であるため、playBehavior
アトリビュートを設定する必要はありません。
{
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>この音声によってAlexaの音声は中断されません。この音声はキューに追加されます。"/></speak>"
},
"shouldEndSession": false,
"playBehavior": "ENQUEUE",
"directives": [ ]
}
このサンプルコードはAlexa Skills Kit SDK for Node.js(v2)を使用しています。
const Alexa = require('ask-sdk-core');
const MyIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'MyIntent';
},
handle(handlerInput) {
const speechText = "この音声によってAlexaの音声は中断されません。 "
+ "この音声はキューに追加されます。";
const playBehavior = "ENQUEUE";
// 応答を組み立てます
const response = handlerInput.responseBuilder
.speak(speechText, playBehavior)
.withShouldEndSession(false)
.getResponse();
// CloudWatchへの応答を記述します
console.log("===応答=== "+ JSON.stringify(response));
// 応答を返します
return response;
}
};
このサンプルコードはAlexa Skills Kit SDK for Javaを使用しています。
package com.amazon.ask.buttongadget.handlers;
import com.amazon.ask.dispatcher.request.handler.HandlerInput;
import com.amazon.ask.dispatcher.request.handler.RequestHandler;
import com.amazon.ask.model.Response;
import static com.amazon.ask.request.Predicates.intentName;
import java.util.Optional;
import com.amazon.ask.model.ui.PlayBehavior;
public class MyIntentHandler implements RequestHandler {
@Override
public boolean canHandle(HandlerInput handlerInput) {
return handlerInput.matches(intentName("MyIntent"));
}
@Override
public Optional<Response> handle(HandlerInput handlerInput) {
// 応答を組み立てます。
Optional<Response> response = handlerInput.getResponseBuilder()
.withSpeech("この音声によってAlexaの音声は中断されません。"
+ "この音声はキューに追加されます。",
PlayBehavior.ENQUEUE)
.withShouldEndSession(false)
.build();
// CloudWatchへの応答を記述します。
String responseLog = response.toString();
responseLog = responseLog.replace("\n", " ").replace("\r", " ");
System.out.println("===応答=== " + responseLog);
// 応答を返します。
return response;
}
}
このサンプルコードはAlexa Skills Kit SDK for Pythonを使用しています。
from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.utils import is_intent_name
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_model.ui import PlayBehavior
from ask_sdk_model import Response
class MyIntentHandler(AbstractRequestHandler):
"""ハローワールドインテント用ハンドラー"""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return is_intent_name("MyIntent")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
# 応答を組み立てます
speech_text = ("この音声によってAlexaの音声は中断されません。"
"この音声はキューに追加されます。")
play_behavior = PlayBehavior.ENQUEUE
handler_input.response_builder.speak(
speech=speech_text,
play_behavior=play_behavior).set_should_end_session(
False)
# CloudWatchへの応答を記述します
response = handler_input.response_builder.response
print(response)
# 応答を返します
return response
キューに追加した音声を置き換える例
次の応答に含まれる音声では、Alexaが現在話している音声を中断しません。ただし、キューに追加された音声が新しい音声に置き換えられます。
{
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>この音声により、Alexaが現在話している音声は中断されませんが、キューにある音声が置き換えられます。"/></speak>"
},
"shouldEndSession": false,
"playBehavior": "REPLACE_ENQUEUED",
"directives": [ ]
}
このサンプルコードはAlexa Skills Kit SDK for Node.js(v2)を使用しています。
const Alexa = require('ask-sdk-core');
const MyIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'MyIntent';
},
handle(handlerInput) {
const speechText = "この音声により、Alexaが現在話している"
+ "音声は中断されませんが"
+ "キューにある音声が置き換えられます。";
const playBehavior = "REPLACE_ENQUEUED";
// 応答を組み立てます
const response = handlerInput.responseBuilder
.speak(speechText, playBehavior)
.withShouldEndSession(false)
.getResponse();
// CloudWatchへの応答を記述します
console.log("===応答=== "+ JSON.stringify(response));
// 応答を返します
return response;
}
};
このサンプルコードはAlexa Skills Kit SDK for Javaを使用しています。
package com.amazon.ask.buttongadget.handlers;
import com.amazon.ask.dispatcher.request.handler.HandlerInput;
import com.amazon.ask.dispatcher.request.handler.RequestHandler;
import com.amazon.ask.model.Response;
import static com.amazon.ask.request.Predicates.intentName;
import java.util.Optional;
import com.amazon.ask.model.ui.PlayBehavior;
public class MyIntentHandler implements RequestHandler {
@Override
public boolean canHandle(HandlerInput handlerInput) {
return handlerInput.matches(intentName("MyIntent"));
}
@Override
public Optional<Response> handle(HandlerInput handlerInput) {
// 応答を組み立てます。
Optional<Response> response = handlerInput.getResponseBuilder()
.withSpeech("この音声により、Alexaが現在話している"
+ "音声は中断されませんが"
+ "キューにある音声が置き換えられます。",
PlayBehavior.REPLACE_ENQUEUED)
.withShouldEndSession(false)
.build();
// CloudWatchへの応答を記述します。
String responseLog = response.toString();
responseLog = responseLog.replace("\n", " ").replace("\r", " ");
System.out.println("===応答=== " + responseLog);
// 応答を返します。
return response;
}
}
このサンプルコードはAlexa Skills Kit SDK for Pythonを使用しています。
from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.utils import is_intent_name
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_model.ui import PlayBehavior
from ask_sdk_model import Response
class MyIntentHandler(AbstractRequestHandler):
"""ハローワールドインテント用ハンドラー"""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return is_intent_name("MyIntent")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
# 応答を組み立てます
speech_text = ("この音声により、Alexaが現在話している"
"音声は中断されませんが"
"キューにある音声が置き換えられます。")
play_behavior = PlayBehavior.REPLACE_ENQUEUED
handler_input.response_builder.speak(
speech=speech_text,
play_behavior=play_behavior).set_should_end_session(
False)
# CloudWatchへの応答を記述します
response = handler_input.response_builder.response
print(response)
# 応答を返します
return response