Мое приложение записывает аудиофайл с микрофона в браузере, обычно это Chrome; отправляет его в Firebase Storage; затем облачная функция Firebase отправляет аудиофайл в Google Cloud Speech-to-Text. Все работает с IBM Cloud Speech-to-Text. С Google Cloud Speech-to-Text это работает, если я отправляю образец файла audio/flac
«несколько торнадо приземлились, когда в воскресенье в Колорадо прокатилась линия сильных гроз». Но когда я отправляю аудиофайл, записанный в браузере, я получаю сообщение об ошибке:
Error: 3 INVALID_ARGUMENT: Request contains an invalid argument.
Вот код браузера. Настройки звука находятся вверху: audio/webm;codecs=opus
и 48000
бит в секунду. Это единственный формат файла мультимедиа и кодировка , поддерживаемые Chrome.
navigator.mediaDevices.getUserMedia({ audio: true, video: false })
.then(stream => {
var options = {
audioBitsPerSecond: 48000, // switch to 8000 on slow connections?
mimeType: 'audio/webm;codecs=opus' // only options on Chrome
};
const mediaRecorder = new MediaRecorder(stream, options);
mediaRecorder.start();
const audioChunks = [];
mediaRecorder.addEventListener("dataavailable", event => {
audioChunks.push(event.data);
});
mediaRecorder.addEventListener("stop", () => {
const audioBlob = new Blob(audioChunks);
firebase.storage().ref('Users/' + $scope.user.uid + '/Pronunciation_Test').put(audioBlob) // upload to Firebase Storage
.then(function(snapshot) {
firebase.storage().ref(snapshot.ref.location.path).getDownloadURL() // get downloadURL
.then(function(url) {
firebase.firestore().collection('Users').doc($scope.user.uid).collection("Pronunciation_Test").doc('downloadURL').set({downloadURL: url})
.then(function() {
console.log("Document successfully written!");
})
.catch(function(error) {
console.error("Error writing document: ", error);
});
})
.catch(error => console.error(error))
})
.catch(error => console.error(error));
// play back the audio blob
const audioUrl = URL.createObjectURL(audioBlob);
const audio = new Audio(audioUrl);
audio.play();
});
setTimeout(() => {
mediaRecorder.stop();
}, 3000);
})
.catch(function(error) {
console.log(error.name + ": " + error.message);
});
Firebase Storage преобразует аудиофайл из webm/opus
в application/octet-streaming
.
Вот моя облачная функция Firebase, которая получает аудиофайл из Firebase Storage и отправляет его в Google Cloud Speech-to-Text.
exports.Google_Speech_to_Text = functions.firestore.document('Users/{userID}/Pronunciation_Test/downloadURL').onUpdate((change, context) => {
// Imports the Google Cloud client library
const speech = require('@google-cloud/speech');
// Creates a client
const client = new speech.SpeechClient();
const downloadURL = change.after.data().downloadURL;
const gcsUri = downloadURL;
const encoding = 'application/octet-stream';
const sampleRateHertz = 48000;
const languageCode = 'en-US';
const config = {
encoding: encoding,
sampleRateHertz: sampleRateHertz,
languageCode: languageCode,
};
const audio = {
uri: gcsUri,
};
const request = {
config: config,
audio: audio,
};
// Detects speech in the audio file
return response = client.recognize(request)
.then(function(response) {
const [responseArray] = response;
const transcription = responseArray.results
.map(result => result.alternatives[0].transcript)
.join('\n');
console.log(`Transcription: `, transcription);
})
.catch((err) => { console.error(err); });
}); // close Google_Speech_to_Text
Вот список поддерживаемых форматов и кодировок мультимедиа для Google Cloud Speech-to-Text:
MP3
FLAC
LINEAR16
MULAW
AMR
AMR_WB
OGG_OPUS
SPEEX_WITH_HEADER_BYTE
webm/opus
и application/octet-streaming
aren нет в списке.
Я что-то пропустил или невозможно записать аудиофайл в Chrome, сохранить его в Firebase Storage, а затем отправить в Google Cloud Speech-to-Text? Кажется странным, что продукты Google не будут работать вместе. Нужно ли перекодировать аудиофайл с помощью ffmpeg
, прежде чем я отправлю его в Google Cloud Speech-to-Text?