В этом посте мы расскажем о том, как настроить Deepgram для живой транскрипции в вашем приложении Vue.js. Мы настроим Deepgram в одном HTML-файле с включением Vue.js <script>
и без каких-либо других зависимостей.
Перед началом работы
Вам понадобится бесплатный API-ключ Deepgram.
Настройка проекта Vue с включенным скриптом
Создайте файл index.html
и откройте его в редакторе кода. Настройте проект Vue:
<html>
<head></head>
<body>
<div id="app">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.0"></script>
<script>
const app = new Vue({
el: '#app'
})
</script>
</body>
</html>
Получить данные микрофона
Этот код будет написан в методе жизненного цикла created()
— это означает, что он произойдет немедленно.
Сначала запросите у пользователя доступ к его микрофону:
const app = new Vue({
el: '#app',
async created() {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
.catch(error => alert(error))
}
})
Затем подключите поток к MediaRecorder, чтобы впоследствии мы могли получить доступ к необработанным данным с микрофона пользователя:
const app = new Vue({
el: '#app',
async created() {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
.catch(error => alert(error))
// Create MediaRecorder
if(!MediaRecorder.isTypeSupported('audio/webm')) return alert('Unsupported browser')
this.mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' })
},
// Store MediaRecorder
data: {
mediaRecorder: null
}
})
Помните, что если вы создаете компоненты Vue, data
должна быть функцией, возвращающей объект.
Подключение к Deepgram
Создайте кнопку, которая начнет транскрипцию. Запустите новый метод begin()
при ее нажатии:
<html>
<head></head>
<body>
<div id="app">
<!-- Add button -->
<button @click="begin">Begin transcription</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.0"></script>
<script>
const app = new Vue({
el: '#app',
async created() {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
.catch(error => alert(error))
if(!MediaRecorder.isTypeSupported('audio/webm')) return alert('Unsupported browser')
this.mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' })
},
data: {
mediaRecorder: null
},
// Create begin method
methods: {
begin() {
}
}
})
</script>
</body>
</html>
Прежде чем продолжить, уделите время получению бесплатного API-ключа Deepgram.
Используйте встроенный в браузер интерфейс WebSocket для подключения к серверу транскрипции Deepgram. Сохраните экземпляр WebSocket в data
:
data: {
mediaRecorder: null,
// Add socket
socket: null
},
methods: {
begin() {
const DG_URL = 'wss://api.deepgram.com/v1/listen?language=de'
const DG_KEY = 'YOUR_DEEPGRAM_API_KEY'
this.socket = new WebSocket(DG_URL, ['token', DG_KEY])
}
}
Этот WebSocket создает двустороннее соединение с Deepgram. Видите language=de
в URL? Это говорит о том, что вы будете говорить по-немецки. У нас есть множество поддерживаемых языков, с которыми вы можете ознакомиться!
Отправка данных в Deepgram
После того как WebSocket-соединение открыто, начните отправлять микрофонные данные:
methods: {
begin() {
const DG_URL = 'wss://api.deepgram.com/v1/listen?language=de'
const DG_KEY = 'YOUR_DEEPGRAM_API_KEY'
this.socket = new WebSocket(DG_URL, ['token', DG_KEY])
// Run the startStreaming method when socket is opened
this.socket.onopen = this.startStreaming
},
// Create startStreaming method
startStreaming() {
this.mediaRecorder.addEventListener('dataavailable', event => {
if(event.data.size > 0 && this.socket.readyState == 1) {
this.socket.send(event.data)
}
// Send data every 250ms (.25s)
mediaRecorder.start(250)
})
}
}
Получение результатов расшифровки
В настоящее время вы отправляете данные через наше постоянное соединение в Deepgram каждые 0,25 секунды. Вы будете получать стенограммы обратно почти так же часто — пришло время написать код обработки.
methods: {
begin() {
const DG_URL = 'wss://api.deepgram.com/v1/listen?language=de'
const DG_KEY = 'YOUR_DEEPGRAM_API_KEY'
this.socket = new WebSocket(DG_URL, ['token', DG_KEY])
this.socket.onopen = this.startStreaming
// Run the handleResponse method when data is received
this.socket.onmessage = this.handleResponse
},
startStreaming() {
this.mediaRecorder.addEventListener('dataavailable', event => {
if(event.data.size > 0 && this.socket.readyState == 1) {
this.socket.send(event.data)
}
mediaRecorder.start(250)
})
},
// Create handleResponse method
handleResponse(message) {
const received = JSON.parse(message.data)
const transcript = received.channel.alternatives[0].transcript
if(transcript) {
console.log(transcript)
}
}
}
Обновите браузер, и вы увидите транскрипты в консоли.
Показ транскриптов на странице
Сначала создайте новое свойство transcripts
в data
с пустым массивом:
data: {
mediaRecorder: null,
socket: null,
// Add this
transcripts: []
},
Затем, вместо регистрации транскриптов, добавьте их в этот массив:
if(transcript) {
this.transcripts.push(transcript)
}
Наконец, обновите HTML, чтобы отобразить элементы из массива:
<div id="app">
<button @click="begin">Begin transcription</button>
<!-- Add looping element -->
<p v-for="transcript in transcripts">{{ transcript }}</p>
</div>
Ваша страница должна выглядеть следующим образом после того, как вы произнесете пару фраз:
Завершение
Окончательный код выглядит следующим образом:
<html>
<head></head>
<body>
<div id="app">
<button @click="begin">Begin transcription</button>
<p v-for="transcript in transcripts">{{ transcript }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.0"></script>
<script>
const app = new Vue({
el: '#app',
async created() {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
.catch(error => alert(error))
if(!MediaRecorder.isTypeSupported('audio/webm')) return alert('Unsupported browser')
this.mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' })
},
data: {
mediaRecorder: null,
socket: null,
transcripts: []
},
methods: {
begin() {
const DG_URL = 'wss://api.deepgram.com/v1/listen?language=de'
const DG_KEY = 'YOUR_DEEPGRAM_API_KEY'
this.socket = new WebSocket(DG_URL, ['token', DG_KEY])
this.socket.onopen = this.startStreaming
this.socket.onmessage = this.handleResponse
},
startStreaming() {
this.mediaRecorder.addEventListener('dataavailable', event => {
if(event.data.size > 0 && this.socket.readyState == 1) {
this.socket.send(event.data)
}
mediaRecorder.start(250)
})
},
handleResponse(message) {
const received = JSON.parse(message.data)
const transcript = received.channel.alternatives[0].transcript
if(transcript) {
this.transcripts.push(transcript)
}
}
}
})
</script>
</body>
</html>
Это самая простая реализация с Vue, и она написана для ясности, а не для краткости. Если вы хотите узнать больше о Vue 3, включая функцию setup() и составные элементы, то Сандра написала отличную серию уроков по Vue 3.
Если у вас есть вопросы, пожалуйста, не стесняйтесь писать нам в Twitter, @DeepgramDevs.