#ios #swift #alexa #alexa-skill #alexa-app
#iOS #swift #alexa #alexa-навык #alexa-приложение
Вопрос:
Я смог настроить пользовательский навык Alexa и вызвать его из своего приложения для IOS. Когда я тестирую навык в симуляторе консоли Alexa, я вижу вывод JSON, и я хочу получить его из своего приложения для IOS, однако у меня проблема с тем, как его проанализировать. Мой код IOS работает нормально, так как я слышу текстовый ответ от моего пользовательского навыка.
Вот пример вывода JSON, который я хочу получить / проанализировать
{
"body": {
"version": "1.0",
"response": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Hello this is a custom skill</speak>"
},
"type": "_DEFAULT_RESPONSE"
},
"sessionAttributes": {},
"userAgent": "ask-node/2.9.0 Node/v10.23.1 sample/hello-world/v1.2"
}
}
Вот код для публикации записи
func postRecording(authToken:String, jsonData:String, audioData: Data) {
var request = URLRequest(url: URL(string: EVENTS_ENDPOINT)!)
//request.cachePolicy = NSURLRequest.CachePolicy.ReloadIgnoringCacheData
request.httpShouldHandleCookies = false
request.timeoutInterval = 60
request.httpMethod = "POST"
request.setValue("Bearer (authToken)", forHTTPHeaderField: "Authorization")
let boundry = NSUUID().uuidString
let contentType = "multipart/form-data; boundary=(boundry)"
request.setValue(contentType, forHTTPHeaderField: "Content-Type")
var bodyData = Data()
bodyData.append("--(boundry)rn".data(using: String.Encoding.utf8)!)
bodyData.append("Content-Disposition: form-data; name="metadata"rn".data(using: String.Encoding.utf8)!)
bodyData.append("Content-Type: application/json; charset=UTF-8rnrn".data(using: String.Encoding.utf8)!)
bodyData.append(jsonData.data(using: String.Encoding.utf8)!)
bodyData.append("rn".data(using: String.Encoding.utf8)!)
bodyData.append("--(boundry)rn".data(using: String.Encoding.utf8)!)
bodyData.append("Content-Disposition: form-data; name="audio"rn".data(using: String.Encoding.utf8)!)
bodyData.append("Content-Type: audio/L16; rate=16000; channels=1rnrn".data(using: String.Encoding.utf8)!)
bodyData.append(audioData)
bodyData.append("rn".data(using: String.Encoding.utf8)!)
bodyData.append("--(boundry)--rn".data(using: String.Encoding.utf8)!)
session.uploadTask(with: request, from: bodyData, completionHandler: { (data:Data?, response:URLResponse?, error:Error?) -> Void in
if (error != nil) {
print("Send audio error: (String(describing: error?.localizedDescription))")
} else {
let res = response as! HTTPURLResponse
if (res.statusCode >= 200 amp;amp; res.statusCode <= 299) {
if let contentTypeHeader = res.allHeaderFields["Content-Type"] {
let boundary = self.extractBoundary(contentTypeHeader: contentTypeHeader as! String)
let directives = self.extractDirectives(data: data!, boundary: boundary)
self.directiveHandler?(directives)
} else {
print("Content type in response is empty")
}
}
}
}).resume()
}
func extractDirectives(data: Data, boundary: String) -> [DirectiveData] {
var directives = [DirectiveData]()
let innerBoundry = "--(boundary)".data(using: String.Encoding.utf8)!
let endBoundry = "--(boundary)--".data(using: String.Encoding.utf8)!
let contentTypeApplicationJson = "Content-Type: application/json; charset=UTF-8".data(using: String.Encoding.utf8)!
let contentTypeAudio = "Content-Type: application/octet-stream".data(using: String.Encoding.utf8)!
let headerEnd = "rnrn".data(using: String.Encoding.utf8)!
var startIndex = 0
while (true) {
let firstAppearance = data.range(of: innerBoundry, in: startIndex..<(data.count))
if (firstAppearance == nil) {
break
}
var secondAppearance = data.range(of: innerBoundry, in: (firstAppearance?.upperBound)!..<(data.count))
if (secondAppearance == nil) {
secondAppearance = data.range(of: endBoundry, in: (firstAppearance?.upperBound)!..<(data.count))
if (secondAppearance == nil) {
break
}
} else {
startIndex = (secondAppearance?.lowerBound)!
}
let subdata = data.subdata(in: (firstAppearance?.upperBound)!..<(secondAppearance?.lowerBound)!)
var contentType = subdata.range(of: contentTypeApplicationJson)
if (contentType != nil) {
let headerRange = subdata.range(of: headerEnd)
var directiveData = String(data: subdata.subdata(in: (headerRange?.upperBound)!..<subdata.count), encoding: String.Encoding.utf8) ?? "Directive data is not String"
directiveData = directiveData.replacingOccurrences(of: "rn", with: "")
directives.append(DirectiveData(contentType: "application/json", data: directiveData.data(using: String.Encoding.utf8)!))
print("Directive: (directiveData)")
}
contentType = subdata.range(of: contentTypeAudio)
if (contentType != nil) {
let headerRange = subdata.range(of: headerEnd)
let audioData = subdata.subdata(in: (headerRange?.upperBound)!..<subdata.count)
directives.append(DirectiveData(contentType: "application/octet-stream", data: audioData))
print("Audio data")
}
}
return directives
}
Мой текущий код возвращает только этот пример ответа
{
"header": {
"namespace": "SpeechSynthesizer",
"name": "Speak",
"messageId": "35601dca-413f-4788-93ed-305e04328d0e",
"dialogRequestId": "db933fd9-3766-407d-99f6-2b33d9c814e6",
"keys": {
"isBlocking": true,
"channel": "audio"
}
},
"payload": {
"format": "AUDIO_MPEG",
"token": "amzn1.as-ct.v1.ThirdPartySdkSpeechlet#ACRI#ValidatedSpeakDirective_amzn1.ask.skill.5718d3ec-b56a-4a5a-bd61-fdd4ab501fc2_ca3ae40b-52cd-4be9-b831-98e975a57e5a_VoiceInitiated#ACRI#[[ENCRYPTED_WITH_AlexaServiceKeyMasterUtil]]AAAAAAAAAAAHT6zrrzQh3EDQVwUGrjOpUAAAAAAAAACFZJ/VU0i9/OCY89UvtcV9X0291NLF7L7nE4irlDAGaph7NlUpgq0Ps31s8OflwHh/9wr3vp5Py Gz 2Lgd8N6fPXWxPHp8 E6R8sLiRh9Cg==",
}
}
Ответ №1:
Если я правильно читаю, вы не получите такого ответа.
Похоже, у вас есть устройство AVS, отправляющее аудио в голосовую службу Alexa.
Отправляемый вами звук принимается службой, преобразуется в намерение и данные и отправляется вашему навыку.
Ответ, который вы ищете с помощью тегов «speak», отправляется ASK SDK из вашего навыка в Alexa.
Alexa преобразует его в аудио и отправляет аудио вашему клиенту AVS, но не отправляет копию прямого вывода из вашей команды skill, которая его создала. Вы просто не можете разобрать его из ответа.
Комментарии:
1. Можно ли настроить ответ Alexa (JSON) и отправить его моему клиенту AVS? @LetMyPeopleCode
2. Прошло некоторое время с тех пор, как я работал с API-интерфейсами AVS, но ознакомьтесь с этой страницей документации для директивы SpeechSynthesizer. Если ваше приложение получает это, вы можете найти текстовое содержимое в свойстве «заголовок»… developer.amazon.com/en-US/docs/alexa/alexa-voice-service /…
3. Я могу получить доступ к SpeechSnythesize. Директива Speak, однако я не вижу свойство caption. Я был бы очень признателен, если бы вы могли помочь мне с этой проблемой. Прошло несколько дней с тех пор, как я застрял с этим. @LetMyPeopleCode
4. Каков ваш вариант использования. Зачем вам нужна эта информация и что вы собираетесь с ней делать?
5. Я хочу воспроизводить музыку (классифицированную по жанру) в своем пользовательском приложении с помощью Alexa. Я хочу получить конкретный жанр, произнесенный пользователем, например. пользователь говорит, играйте музыку 80-х. Если у меня есть это значение в качестве ответа JSON от Alexa, я могу просто программно воспроизводить музыку в своем пользовательском приложении. Это правильный подход? @LetMyPeopleCode