ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
高品質なSiriメディアインタラクションをデザインする
Siri体験を音楽、音声Appに向けデザインする技術的な手順、その謎を解き明かします。優れたインタラクションを作ること、Siriがさらに高い正確性と個性をもって応答できるようにカスタムボキャブラリーを提供する方法をお伝えします。よくあるエラーをデバッグし、AppleのSiriチームも使っているのと同じ方法でインテントをテストする方法もお見せします。
リソース
関連ビデオ
WWDC20
- インテリジェンスのためのデザイン - 人々のいる場所で会うこと
- インテリジェンスのためのデザイン - 「システム」と友達になる
- インテリジェンスのためのデザイン-新しい機会を発見する
- インテリジェンスのためのデザイン-進化したApp
- インテントの強化
- ショートカット Appでアクションをフィーチャーする
- 就寝準備をAppに組み込む
- Appの音声インタラクションを評価し、最適化する
- Siriで一般的なエラーを読み解き、対応する
- SiriKit Media Intentsをより多くのプラットフォームに拡大する
- SiriKitとショートカットの新機能
- watchOSにおけるショートカットの活用
Tech Talks
WWDC19
-
ダウンロード
ようこそ WWDCへ “高品質なSiriメディアインタラクションを デザインする” ダニー・マンデルです 今日 お話しするのは SiriKit Mediaアプリケーションで 最高品質のSiri体験を実現する方法です 質を重視する理由は? 楽しんで使えるものを ビルドしたくても― 声の質が悪くては誰も楽しめません 音声アシスタンスに求められる信頼性は 従来のユーザーインターフェイスより 高いのです 使ってもらうには 信頼性の向上が必要ですので SiriKit Mediaサポートの 質を上げましょう
当たり前のことですが “再生して”と言われたら 実行することが大事です
あなたのアプリケーションを 誰かが初めて声で使った時に 再生しなければ 二度と使わないでしょう だから安定したplayback stackに Siriのエンジニアリソースを使いましょう
次は すぐに再生できるか確認しましょう SiriKit Mediaアプリケーションで 重大な不具合の1つはタイムアウトです 特にCarPlayのような環境では すぐに再生することが重要 運転中 ハンズフリーで使っている時 すぐに再生を始めないアプリケーションは まったく役に立ちません これに対処すべく 今年は新たなオプションを追加しました 詳細は― “Expand your SiriKit Media Intents to More Platforms”でご確認ください
次はSiriにリスナーの好みを 理解させることです これには Siriのuser vocabulary APIを採用します Siriにアプリケーションのカタログを 理解させるには Siriのglobal vocabulary APIを 採用します これらについては 後で深く掘り下げます
最適な曲を選んで再生する時 複数の言い方に対応したいものです 対応する発言の数が多いほど ユーザは日常で もっと使いたいと思うでしょう Siriは知的アシスタントになることが 期待されています これを実現するには 多種多様な自然言語に 対応すべきなのです SiriKit Mediaアプリケーションでよく使われる 自然言語パターンを見てみましょう “完璧っぽく”とは? 要求が不明確な時 答えに限りなく近い対応をするという意味 SiriKit Mediaの要求の半分以上は このパターンです “アプリケーションを再生して”や “アプリケーションで曲を再生して”など 一般的にユーザは欲しいものを 具体的に言わないことが多い これが最も重要なユースケースです このシナリオに対処すれば 多くのリスナーに即座に対応できます “完璧っぽい”の定義は 開発者が決められますが ユーザに驚きと喜びを 与えるようにしましょう このような要求を認識するには 音楽のmedia typeを含むnil media search またはmedia searchを行います 次のユースケースではユーザが 再生したいタイトルを指定しますが 曲 アルバム アーティスト Podcastのうち どのmedia typeかは言いません これには異なるmedia typeを把握し 広範囲の検索を行う必要があります
この種の要求を認識するには media search objectに入っている mediaNameが頼りです このようなクエリーは約30%あります より正確なクエリーではアーティストと 他の検索フィールドを組み合わせます このような複合検索にも対応しましょう このケースでは mediaNameにタイトルが入り artistNameに 求めるアーティスト名が入ります クエリーのタイプがより詳細になれば 使用率が下がり すべての要求の約5%になります プレイリストも頻繁に使われるカテゴリーなので 対応しましょう 具体的なクエリーの1つで 約5%の割合で使われています プレイリストのクエリーが発生したら mediaNameプロパティに プレイリストのクエリーを置き mediaTypeプロパティを “プレイリスト”に設定します INMediaSearchには 他にも多くの検索フィールドがあります しかし これら4つのユースケースだけで 現在のSiriKit Media trafficの 90%以上をキャプチャします 他にも多くのフィールドを 実装してください しかしエンジニアリングとQAを よくあるユースケースに対して 優先させるのも妥当です また注目すべきは Siriのサポートがよいほど ユーザは より複雑な要求をするということ ですから改良すれば 使用パターンも変化します ユーザが好んで使っている証拠ですね high trafficな発言と― わずかなIntentでusageの大部分を キャプチャする方法を見てきました それらのIntentをデバッガで確認し 各ケースのmedia searchを見てみましょう
media searchを見るために ブレークポイントを設定します
“ControlAudioを再生して”で 見てみましょう
ブレークポイントを見ると media searchが行われていません これは検索基準を 指定しなかったからです 次に“音楽を再生して”では どうか?
mediaTypeは音楽に設定され 他のフィールドは空欄です “Special Disaster Teamを再生して”では?
期待どおり mediaNameが“Special Disaster Team”に 次は より高度に タイトルとアーティスト名を入れます
mediaNameに“Maybe Sometime” artistNameに“Special Disaster Team” 他のフィールドは空欄です 最後はプレイリスト “私のWWDCプレイリストを再生して”を試します
“プレイリスト”を発言に入れたため mediaTypeは“プレイリスト” mediaNameに“WWDC”が入りました これらのIntentだけで Intent handlerにおける Siri trafficの大部分をキャプチャできます 次はSiriKit Mediaの ボキャブラリー機能を掘り下げます Siriの自然言語処理システムは 機械学習システムです ユーザがSiriに何かを要求する時 その人のIntentを推測する probabilistic modelがあるのです そのmodelは特定の機能を 認識するように訓練されています 例えばSiriにジャンルやmedia type sortsやリリース日を教えなくても それらを認識するように 訓練されているのです これはエンジニアリングと 使い方の観点で好都合です 新しいアプリケーションが SiriKit Media Intentsを採用するたびに model trainingを行う必要はありません また1つのSiriKit Mediaアプリケーションの 使い方を覚えてしまえば 全部 使えるのです ただし他のシステムと同様に 問題も生じます
例えば ControlAudioで “70年代パンク・クラシック”という プレイリストがある場合 おそらくSiri modelはデフォルトで “70年代”がmediaReleaseDate “パンク・クラシック”が mediaNameと解釈します そのためControlAudioは 具体的なプレイリスト名を出しません
これを解決するには Siriに追加のボキャブラリーを同期し “70年代パンク・クラシック”が プレイリスト名だと認識させます これを実行する方法は2つ Siriにカタログを教えるには Siriのユーザボキャブラリー機能を使います ユーザボキャブラリー機能は 特定のユーザに当てはまるものだけに 使用します Siriとボキャブラリーを共有するには INVocabulary APIを使います これを見てみましょう
INVocabularyを共有する
記憶したい値でordered setを作る ここでは重要な値を 最初のほうに置きましょう Siriは順番に注目します
次に記憶したいtypeに setVocabularyStringsを呼びます ここではmediaPlaylistTitleです
INVocabularyでの作業では 個人のプレイリストのような ユーザが作ったコンテンツを扱います しかし スピーチと自然言語の認識に バイアスをかけて アーティストやPodcastなどのtaste profileを 考慮することも可能です 一方 グローバルボキャブラリーは アプリケーションのユーザ全員に 対するものに使います ユーザボキャブラリーと違って 固定のため― アプリケーションの一部として配布する .plistに入れます 入れるのは アプリケーション特有のものだけ 人気の曲やPodcastはSiriが NL modelの一部として認識しているので不要です こちらがglobal vocabulary.plistの例 INPlayMediaIntent.playlistTitle fieldに 同期しているdataです ボキャブラリーのidentifierは “70年代パンク・アンセム” identifierはINMediaSearch mediaName fieldで Siriから受け取る値です これがkeyになり “70年代パンク・アンセム”が カタログのプレイリストと一致すると Siriに知らせるのです
ボキャブラリーには多くの種類があり 対応するmedia typeに合わせて使えます ユーザボキャブラリーのdata typeと グローバルボキャブラリーのkeyは 名称が違いますが 同じ場所でSiriと同期します 音楽アプリケーションには プレイリストのタイトルやアーティスト名 オーディオブックにはタイトルと著者名 ラジオやPodcastには番組名 ボキャブラリー機能の使用が SiriのIntentにどう影響するか? 例えば“70年代の パンク・クラシックをかけて”で Siriが送るIntentが アプリケーションの期待と異なる場合は? デバッガで見てみます
設定を行い その発言でテストしてみましょう
実行します
得られたIntentは 期待していたプレイリストのタイトルと 一致していません genreNameは“パンク” 年代は70年代 これを修正しましょう ボキャブラリーをAppDelegateに追加します このコードで重要なのは ボキャブラリーに順番があること Siriはリストの最初にあるアイテムを優先します 認識するアイテムの数は限られているので 重要なものを最初のほうに置いてください 設定できたらControlAudioを実行し Siriのサーバと同期させます ボキャブラリーがSiriのサーバと同期するまで 時間がかかるかもしれません ネットワークや電力の状況次第です
同期が完了したので 再び同じフレーズで Intent handlerを実行します
まずmedia searchで mediaTypeにプレイリストが設定されています Siriがユーザボキャブラリーで認識し 設定したのです mediaNameには“70年代パンク・クラシック”が フルで入っています 次はグローバルボキャブラリーを 見てみましょう global vocabulary.plistは ユーザボキャブラリーと異なり ユーザ全員が使うことができます 最初にvocabulary.plistを ControlAudioに追加します
見てみましょう
ここでParameter Vocabularies keyに注目 まずParameter Namesを見ます プレイリストのタイトルを定義するので 値はINPlayMediaIntent.playlistTitle
Parameter Vocabularyは Vocabulary Item Identifierの値を 持っています identifierは Intents Media Searchで受ける値 今回は直前の例を少し変えて “70年代パンク・アンセム”としました グローバルボキャブラリーファイルを 追加すると― Intent handlerでどうなるか?
再びIntentを見ると mediaTypeはプレイリスト プレイリストのタイトルは “70年代パンク・アンセム”です
このようにSiriの グローバルボキャブラリーを使い ユーザ全員に重要なものを Siriに認識させるのです Siriの重大なユースケースの1つは Now Playingのコントロール これらもテストしましょう iOSのNow Playingサポートは MPRemoteCommandCenter classにより 実装されています 特定のNow Playingコマンドに command handlerを登録すると使えます Now Playingコマンドの例は “再生” “一時停止” “次のトラック” “前のトラック”など コントロールセンターや CarPlayのNow Playing画面にボタンがあれば それに対応するNow Playingコマンドclassが あるのです Now Playing APIの詳細を掘り下げた― “Becoming a Now Playable App”という サンプルコードプロジェクトがあります より詳しい仕組みを知りたい方は それを見るといいでしょう
Siriは特定のNow Playingコマンドの上で 音声インターフェイスとして動きます この動作は何年も前から 見られるものです Now PlayingコマンドをSiriに送ると?
Siriの多くのコマンド同様に まずはSiriが発言を認識します ここでの発言は“次のトラック” 認識した後 MPRemoteCommandCenterにコマンドを送信 このケースでは “次のトラック”のコマンドです するとアプリケーションの registered handlerが呼び出され そのコマンドを扱えるようになります これはボタンを押して 実行することと同じなので Siriの操作と Now Playingボタンの押下は 同じことを実行しています 実装する場合には この点を覚えておくといいでしょう コマンドをいくつか呼び出してみましょう これから使う発言の例は Siriが対応している 多くの自然言語のうちのいくつかです Now Playingサポートを実装する時に すべきことは MPRemoteCommandCenterが Siriと正しく動作するかの確認です
まずは“一時停止”コマンド Siriに“一時停止して”と言うと MPRemoteCommandCenterの 一時停止コマンドを呼び出します
次は“再生”です 一時停止した曲を再開できます Siriに“再開して”と言うと MPRemoteCommandCenterの 再生コマンドを呼びます
“前のトラック”も Siriに発言することで コマンドを呼び出します
“次のトラック”も Siriに発言することで コマンドを呼び出します 次は“前方にスキップ” これも発言して コマンドを呼び出します スキップしたい秒数を 具体的に指定することができ Siriがコマンドのinterval propertyに 情報を送ります 次は“後方にスキップ” これも発言することで コマンドを呼び出します 具体的な秒数を指定し コマンドのinterval propertyに連携させます ロック画面に現れないコマンドもあります changeRepeatModeと changeShuffleModeは 各モードを有効または無効にします 使うのはリピートとシャッフルを オンかオフにする時のみ シャッフル再生やリピート再生は INPlayMediaIntentを使いましょう changePlaybackRateでは 再生速度を設定できます 例えば“ゆっくり”や “半分の速度”などです Now Playingコマンドを 実行するのと同様に MPNowPlayingInfoCenterで プロパティを設定すれば 再生中のコンテンツの質問に Siriが答えます サポートされているプロパティは まずMPMediaItemPropertyTitle “これは何の曲?”と言えば使えます MPMediaItemPropertyArtistは “このバンドは?”と聞きます MPMediaItemPropertyAlbumTitleは “このアルバムは?”と聞けば使えます コマンドをサポートしていない場合は 3通りの方法で知らせます アプリケーションに合った方法を 適用しましょう
最も簡単なのは コマンドを実行しない方法 MPRemoteCommandCenterでhandlerを インストールしなければ Siriはエラーダイアログを出します
コマンドを無効にもできます ある特定の状況下で コマンドを使用不可にしたい場合に便利です 例えば“次のトラック”コマンドを 音楽配信で広告を流す間 無効にできます
コマンドを失敗させて エラーダイアログを出すことも可能です これは例外的な場合ですが Siriは対処できます 最後に1つ 上質なSiriKit Media体験は 知ることで得られます どのボイスインテグレーションにも言えますが 上質な音声体験のために注いだ努力は 目に見えないため 気づかれないことがあります しかし機能性を知った人々は Siriを使う傾向にあります 具体的な数字は? アプリケーションの機能を学ぶと Siriの使用率が最大で10倍増えます もちろんアプリケーションの外見や 雰囲気に合わせることも大事です しかしSiriを通して より簡単に使ってもらいたければ 機能を教えるのがいいでしょう 話は以上です あなたのアプリケーションとSiriで ユーザが最高の体験を味わえることを祈ります 上質なSiriの体験は 使って初めて得られることを忘れずに ご視聴ありがとうございました
-
-
5:46 - resolveMediaItems method
func resolveMediaItems(for intent: INPlayMediaIntent, with completion: @escaping ([INPlayMediaMediaItemResolutionResult]) -> Void) { let mediaSearch = intent.mediaSearch resolveMediaItems(for: mediaSearch) { optionalMediaItems in guard let mediaItems = optionalMediaItems else { return } completion(INPlayMediaMediaItemResolutionResult.successes(with: mediaItems)) } }
-
10:21 - User vocabulary
let vocabulary = INVocabulary.shared() let playlistNames = NSOrderedSet(objects: "70s punk classics") vocabulary.setVocabularyStrings(playlistNames, of: .mediaPlaylistTitle)
-
11:28 - Global vocabulary example
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>ParameterVocabularies</key> <array> <dict> <key>ParameterNames</key> <array> <string>INPlayMediaIntent.playlistTitle</string> </array> <key>ParameterVocabulary</key> <array> <dict> <key>VocabularyItemSynonyms</key> <array> <dict> <key>VocabularyItemPhrase</key> <string>70s punk anthems</string> </dict> </array> <key>VocabularyItemIdentifier</key> <string>70s punk anthems</string> </dict> </array> </dict> </array> </dict> </plist>
-
13:07 - Resolve media items method
func resolveMediaItems(for intent: INPlayMediaIntent, with completion: @escaping ([INPlayMediaMediaItemResolutionResult]) -> Void) { let mediaSearch = intent.mediaSearch resolveMediaItems(for: mediaSearch) { optionalMediaItems in guard let mediaItems = optionalMediaItems else { return } completion(INPlayMediaMediaItemResolutionResult.successes(with: mediaItems)) } }
-
13:31 - User vocabulary syncing
// Set our playlist title in user vocabulary so we get the proper Siri intent let vocabulary = INVocabulary.shared() let playlistNames = NSOrderedSet(objects: "70s punk classics") vocabulary.setVocabularyStrings(playlistNames, of: .mediaPlaylistTitle)
-
14:57 - Global vocabulary example
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>ParameterVocabularies</key> <array> <dict> <key>ParameterNames</key> <array> <string>INPlayMediaIntent.playlistTitle</string> </array> <key>ParameterVocabulary</key> <array> <dict> <key>VocabularyItemSynonyms</key> <array> <dict> <key>VocabularyItemPhrase</key> <string>70s punk anthems</string> </dict> </array> <key>VocabularyItemIdentifier</key> <string>70s punk anthems</string> </dict> </array> </dict> </array> </dict> </plist>
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。