メディア レスポンスを使用すると、アクションは、SSML の 240 秒の制限を超える再生時間で音声コンテンツを再生できます。メディア レスポンスは、音声のみのデバイスと、ビジュアル コンテンツを表示できるデバイスの両方で機能します。ディスプレイでは、メディア レスポンスは、メディア コントロールおよび(必要に応じて)静止画像を含む視覚コンポーネントとともに表示されます。
メディア レスポンスを定義する場合は、Google アシスタントがサポートされているデバイスでのみリッチ レスポンスを返すように、RICH_RESPONSE
と LONG_FORM_AUDIO
の両方のサーフェス機能を持つ候補を使用します。リッチ レスポンスは、プロンプト内の content
オブジェクトごとに 1 つだけ使用できます。
再生する音声は、正しい形式の MP3 ファイルである必要があります。MP3 ファイルは、ウェブサーバーでホストし、HTTPS URL で一般公開する必要があります。ライブ ストリーミングは MP3 形式でのみサポートされています。
![スマートディスプレイのメディア レスポンスの例](https://developers.google.cn/static/assistant/conversational/images/smart-display/media.png?authuser=6&hl=ja)
動作
![スマートフォンに表示されたメディア レスポンスの例](https://developers.google.cn/static/assistant/conversational/images/media.png?authuser=6&hl=ja)
メディア レスポンスの主なコンポーネントは単一トラックカードです。このカードを使用すると、ユーザーは次のことができます。
- 最後の 10 秒を再生
- 30 秒早送り
- メディア コンテンツの全長を表示する
- メディア再生の進行状況インジケーターを確認する
- 経過時間を確認する
メディア レスポンスは、音声操作で次の音声コントロールをサポートしています。これらはすべて Google アシスタントによって処理されます。
- 「OK Google, 再生して」
- 「OK Google, 一時停止して」
- 「OK Google, 止めて」
- 「OK Google, 最初からやり直して」
「OK Google, 音量を上げて」や「OK Google, 音量を 50% に設定して」などと話しかけて音量を調整することもできます。アクション内のインテントは、類似のトレーニング フレーズを処理する場合、優先されます。アクションに特別な理由がない限り、アシスタントはこのようなユーザー リクエストを処理できるようにします。
Android スマートフォンでの動作
Android スマートフォンでは、スマートフォンがロックされているときもメディア コントロールを使用できます。 メディア コントロールも通知領域に表示され、次のいずれかの条件が満たされると、ユーザーはメディア レスポンスを確認できます。
- Google アシスタントがフォアグラウンドで動作していて、スマートフォンの画面がオンになっている。
- ユーザーが音声の再生中に Google アシスタントから離れ、再生が完了してから 10 分以内に Google アシスタントに戻った。Google アシスタントに戻ると、メディアカードと候補ワードが表示されます。
プロパティ
メディア レスポンスには次の特性があります。
プロパティ | 種類 | 必須 / 任意 | 説明 |
---|---|---|---|
media_type |
MediaType |
必須 | 提供されたレスポンスのメディアタイプ。メディア ステータスを確認応答する場合は、MEDIA_STATUS_ACK を返します。 |
start_offset |
string | 任意 | 最初のメディア トラックを開始する位置を移動します。値は秒単位で指定します。小数点以下の秒数は小数第 9 位以下で表し、末尾は接尾辞「s」にします。たとえば、3 秒と 1 ナノ秒は「3.000000001s」と表されます。 |
optional_media_controls |
OptionalMediaControls の配列 |
任意 | ユーザーがメディア再生ステータスを変更(メディア再生の一時停止や停止など)したときにコールバックを受け取るオプトイン プロパティ。 |
media_objects |
MediaObject の配列 |
必須 | プロンプトに含めるメディア オブジェクトを表します。MEDIA_STATUS_ACK でメディア ステータスを確認する場合は、メディア オブジェクトを指定しないでください。 |
first_media_object_index |
整数 | 任意 | media_objects 内で再生する最初の MediaObject の 0 ベースのインデックス。指定されていない場合、ゼロまたは境界外の場合、最初の MediaObject から再生が開始されます。
|
repeat_mode |
RepeatMode |
任意 | メディア オブジェクトのリストを繰り返し表示するためのモードです。 |
サンプルコード
YAML
candidates: - first_simple: variants: - speech: This is a media response. content: media: start_offset: 2.12345s optional_media_controls: - PAUSED - STOPPED media_objects: - name: Media name description: Media description url: 'https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3' image: large: url: 'https://storage.googleapis.com/automotive-media/album_art.jpg' alt: Jazz in Paris album art media_type: AUDIO
JSON
{ "candidates": [ { "first_simple": { "variants": [ { "speech": "This is a media response." } ] }, "content": { "media": { "start_offset": "2.12345s", "optional_media_controls": [ "PAUSED", "STOPPED" ], "media_objects": [ { "name": "Media name", "description": "Media description", "url": "https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3", "image": { "large": { "url": "https://storage.googleapis.com/automotive-media/album_art.jpg", "alt": "Jazz in Paris album art" } } } ], "media_type": "AUDIO" } } } ] }
Node.js
// Media response app.handle('media', (conv) => { conv.add('This is a media response'); conv.add(new Media({ mediaObjects: [ { name: 'Media name', description: 'Media description', url: 'https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3', image: { large: JAZZ_IN_PARIS_IMAGE, } } ], mediaType: 'AUDIO', optionalMediaControls: ['PAUSED', 'STOPPED'], startOffset: '2.12345s' })); });
JSON
{ "session": { "id": "session_id", "params": {}, "languageCode": "" }, "prompt": { "override": false, "content": { "media": { "mediaObjects": [ { "name": "Media name", "description": "Media description", "url": "https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3", "image": { "large": { "alt": "Jazz in Paris album art", "height": 0, "url": "https://storage.googleapis.com/automotive-media/album_art.jpg", "width": 0 } } } ], "mediaType": "AUDIO", "optionalMediaControls": [ "PAUSED", "STOPPED" ] } }, "firstSimple": { "speech": "This is a media response", "text": "This is a media response" } } }
メディアのステータスの受信
ユーザーのメディア再生中または再生後に、Google アシスタントはメディア ステータス イベントを生成して、アクションに再生の進行状況を通知します。これらのステータス イベントを Webhook コードで処理して、ユーザーがメディアの再生を一時停止、停止、終了したときに、適切にルーティングされるようにします。
Google アシスタントは、メディアの再生の進行状況とユーザークエリに基づいて、次のリストからステータス イベントを返します。
FINISHED
: ユーザーがメディアの再生を完了し(または次のメディアにスキップした)、遷移が会話の終了ではない場合。このステータスはMEDIA_STATUS_FINISHED
システム インテントにもマッピングされます。PAUSED
: ユーザーがメディアの再生を一時停止しました。optional_media_controls
プロパティで、このステータス イベントの受信をオプトインします。このステータスはMEDIA_STATUS_PAUSED
システム インテントにもマッピングされます。STOPPED
: ユーザーがメディアの再生を停止または終了しました。optional_media_controls
プロパティで、このステータス イベントの受信をオプトインします。このステータスはMEDIA_STATUS_STOPPED
システム インテントにもマッピングされます。FAILED
: メディアの再生に失敗しました。このステータスはMEDIA_STATUS_FAILED
システム インテントにもマッピングされます。
メディアの再生中に、ユーザーがメディアの一時停止イベントと停止イベントの両方として解釈可能なクエリを提供する場合があります(「停止」、「キャンセル」、「終了」など)。その場合、アシスタントはアクションに actions.intent.CANCEL
システム インテントを提供し、「STOPPED」ステータス値を含むメディア ステータス イベントを生成して、アクションを完全に終了します。
Google アシスタントがステータス値 PAUSED
または STOPPED
を含むメディア ステータス イベントを生成すると、確認応答(タイプ MEDIA_STATUS_ACK
)のみを含むメディア レスポンスで応答します。
メディアの進行状況
現在のメディア再生の進行状況は、Webhook リクエストの context.media.progress
フィールドで確認できます。メディアの進行状況を開始時間オフセットとして使用して、メディアの再生が終了した時点から再生を再開できます。開始時間オフセットをメディア レスポンスに適用するには、start_offset
プロパティを使用します。
サンプルコード
Node.js
// Media status app.handle('media_status', (conv) => { const mediaStatus = conv.intent.params.MEDIA_STATUS.resolved; switch(mediaStatus) { case 'FINISHED': conv.add('Media has finished playing.'); break; case 'FAILED': conv.add('Media has failed.'); break; case 'PAUSED' || 'STOPPED': if (conv.request.context) { // Persist the media progress value const progress = conv.request.context.media.progress; } // Acknowledge pause/stop conv.add(new Media({ mediaType: 'MEDIA_STATUS_ACK' })); break; default: conv.add('Unknown media status received.'); } });
再生リストを返す
レスポンスに複数の音声ファイルを追加して、再生リストを作成できます。最初のトラックの再生が完了すると、次のトラックが自動的に再生されます。各トラックの再生が完了するまでは、この処理が継続されます。ユーザーは、画面上の [Next] ボタンを押すか、「Next」などと話しかけて次のトラックにスキップすることもできます。
プレイリストの最後のトラックで [次へ] ボタンが無効になります。ただし、ループモードを有効にすると、プレイリストは最初のトラックから再び再生されます。ループモードの詳細については、ループモードを実装するをご覧ください。
再生リストを作成するには、media_objects
配列に複数の MediaObject
を含めます。次のコード スニペットは、3 つのトラックのプレイリストを返すプロンプトを示しています。
{ "candidates": [ { "content": { "media": { "media_objects": [ { "name": "1. Jazz in Paris", "description": "Song 1 of 3", "url": "https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3", "image": { "large": { "url": "https://storage.googleapis.com/automotive-media/album_art.jpg", "alt": "Album cover of an ocean view", "height": 1600, "width": 1056 } } }, { "name": "2. Jazz in Paris", "description": "Song 2 of 3", "url": "https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3", "image": { "large": { "url": "https://storage.googleapis.com/automotive-media/album_art.jpg", "alt": "Album cover of an ocean view", "height": 1600, "width": 1056 } } }, { "name": "3. Jazz in Paris", "description": "Song 3 of 3", "url": "https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3", "image": { "large": { "url": "https://storage.googleapis.com/automotive-media/album_art.jpg", "alt": "Album cover of an ocean view", "height": 1600, "width": 1056 } } } ], } } } ] }
ループモードを実装する
ループモードでは、自動的に繰り返される音声レスポンスを提供できます。このモードを使用して、単一トラックを繰り返し再生したり、プレイリストをループしたりできます。ループした 1 つのトラックに対してユーザーが「次へ」などのように言えば、曲が再び再生されます。ループ再生された再生リストの場合、ユーザーが「Next」と話しかけると、再生リストの次のトラックが開始されます。
ループモードを実装するには、プロンプトに repeat_mode
フィールドを追加し、その値を ALL
に設定します。この追加により、最後のメディア オブジェクトの最後に到達したときに、メディア レスポンスを最初のメディア オブジェクトの先頭までループさせることができます。
次のコード スニペットは、ループ トラックを返すプロンプトを示しています。
{ "candidates": [ { "content": { "media": { "media_objects": [ { "name": "Jazz in Paris", "description": "Single song (repeated)", "url": "https://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3", "image": { "large": { "url": "https://storage.googleapis.com/automotive-media/album_art.jpg", "alt": "Album cover of an ocean view", "height": 1600, "width": 1056 } } } ], "repeat_mode": "ALL" } } } ] }