Я пытаюсь получить доступ к сервису IBM Speech to Text без использования библиотеки. Я использую Retrofit с GSON.
Проблема заключается в аутентификации, которая, по-видимому, не выполняется правильно, возвращая код 401. Из официальной документации HTTP-запрос должен прийти в этом формате
curl -X POST -u "apikey:{apikey}" \
--header "Content-Type: audio/flac" \
--data-binary @{path_to_file}audio-file.flac \
"{url}/v1/recognize"
Когда я проверяю команду curl
с моими учетными данными, служба работает нормально.
Это интерфейс, который я использую
interface SpeechToTextApi {
@Multipart
@POST("v1/recognize")
fun speechToText(
@Header("Authorization") authKey: String,
@Part("file") filename: RequestBody,
@Part voiceFile: MultipartBody.Part
): Call<List<SpeechToText>>
}
, гдеУ меня есть следующие классы данных
data class SpeechToText(val results: List<SttResult>)
data class SttResult(val alternatives: List<RecognitionResult>, val final: Boolean)
data class RecognitionResult(val confidence: Float, val transcript: String)
, и вот как я настраиваю Retrofit
private val retrofit = Retrofit.Builder()
.baseUrl(STT_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
private val service = retrofit.create(SpeechToTextApi::class.java)
, в то время как вызов реальной службы выглядит следующим образом
val requestFile = RequestBody.create(MediaType.parse("audio/mp3"), file.name)
val body = MultipartBody.Part.createFormData("file", file.name, requestFile)
service
.speechToText(getString(R.string.stt_iam_api_key), requestFile, body)
.enqueue(object: Callback<List<SpeechToText>> {
override fun onResponse(call: Call<List<SpeechToText>>, response: Response<List<SpeechToText>>) {
val listOfStts = response.body()
Log.d(TAG, "Response code: ${response.code()}")
if (listOfStts != null) {
for (stt in listOfStts) {
for (res in stt.results) {
Log.d(TAG, "Final value: ${res.final}")
for (alt in res.alternatives) {
Log.d(TAG, "Alternative confidence: ${alt.confidence}\nTranscript: ${alt.transcript}")
Toast.makeText(this@MainActivity, alt.transcript, Toast.LENGTH_SHORT).show()
}
}
}
}
}
override fun onFailure(call: Call<List<SpeechToText>>, t: Throwable) {
Log.d(TAG, "Error: ${t.message}")
t.printStackTrace()
}
})
ЗаписиMP3-файлы, для которых я уверен, что они хранятся правильно и доступны. Я также заменил audio/flac
на audio/mp3
.
Кажется, проблема в том, как работает аутентификация. До кода, который я показал выше, я использовал
private val retrofit = Retrofit.Builder()
.baseUrl(STT_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(OkHttpClient.Builder()
.addInterceptor { chain ->
val request = chain.request()
val headers = request
.headers()
.newBuilder()
.add("Authorization", getString(R.string.stt_iam_api_key))
.build()
val finalRequest = request.newBuilder().headers(headers).build()
chain.proceed(finalRequest)
}
.build())
.build()
, но тот же код ответа 401 сохранялся. Конечно, в методе интерфейса отсутствовал параметр @Header
.
Любая помощь очень ценится.