Рубрики
Без рубрики

Как построить речь к эмоции конвертер с веб-речевой API и Node.js

Вы когда-нибудь задумывались – мы можем сделать у Node.js проверить, если что мы говорим, положительный или отрицательный? Я получил рассылку, которая обсуждала обнаружение тона. Программа может проверить, что мы пишем, а затем рассказывает нам, если бы его можно было увидеть как агрессивный, уверенно или

Автор оригинала: FreeCodeCamp Community Member.

Вы когда-нибудь задумывались – мы можем сделать у Node.js проверить, если что мы говорим, положительный или отрицательный?

Я получил рассылку, которая обсуждала обнаружение тона. Программа может проверить то, что мы пишем, а затем рассказывает нам, если это можно рассматривать как агрессивный, уверенно или множество других чувств.

Это заставило меня задаться вопросом, как я могу построить упрощенную версию, используя браузер и Node.js, которые будут инициированы.

В результате я оказался небольшим проектом, который обнаруживает, если оно говорило, имеет положительную, нейтральную или негативную валентность.

Вот как я это сделал.

План

Когда вы начинаете проект, вы должны набросать – по крайней мере, смутно – ваша цель и как его достичь. Прежде чем начать мой поиск, я сказал, что мне нужно:

  • Запись голоса
  • Способ перевести запись в текст
  • Способ дать текст счет
  • Способ показать результат пользователю, который просто говорил

После некоторого времени после исследования я обнаружил, что запись голоса и перевод на текстовые запчасти уже сделаны Веб-речь API Это доступно в Google Chrome. Это именно то, что нам нужно в Производительность оформления интерфейс.

Что касается текста, я нашел Афинн который является списком слов, которые уже забиты. Он имеет ограниченный объем с «только» 2477 слов, но более чем достаточно для нашего проекта.

Поскольку мы уже используем браузер, мы можем показать другую эмоджи с HTML, JavaScript и CSS в зависимости от результата. Так что это обрабатывает наш последний шаг.

Теперь, когда мы знаем, что мы собираемся использовать, мы можем суммировать это:

  • Браузер слушает пользователю и возвращает какой-нибудь текст, используя API веб-речь
  • Это делает запрос на наш Node.js сервер с текстом
  • Сервер оценивает текст, используя список AFINN и возвращает счет
  • Браузер показывает другой эмодзи в зависимости от оценки

Примечание: Если вы знакомы с настройкой проекта, вы можете в основном пропустить раздел «Файлы проекта и настройки» ниже.

Файлы проекта и настройки

Наша папка для проекта и структура файлов будет следующим:

src/
  |-public // folder with the content that we will feed to the browser
    |-style // folder for our css and emojis
      |-css // optional folder, we have only one obvious file
        |-emojis.css
      |-images // folder for the emojis
    |-index.html
    |-recognition.js
  package.json
  server.js // our Node.js server

На передней стороне вещей наша index.html Файл будет включать в себя JS и CSS:


  
    
      Speech to emotion
    
	
  
  
    
    nothing for now
    
    
  

распознавание.js Файл будет завернутый в DomcontentLoaded Событие, поэтому мы гарантируем, что страница загружена перед выполнением наших JS:

document.addEventListener('DOMContentLoaded', speechToEmotion, false);

function speechToEmotion() {
  // Web Speech API section code will be added here
}

Мы оставляем наши emojis.csss Пустой на данный момент Отказ

В нашей папке мы будем работать NPM запустить init который создаст Package.json Отказ

На данный момент нам нужно будет установить два пакета, чтобы облегчить нашу жизнь. Так что только NPM установить оба:

  • Expressjs – Чтобы быстро запустить HTTP-сервер
  • Номемон – Итак, мы не постоянно печатаем Node Server.js Всякий раз, когда мы делаем изменения в наших Server.js Файл Отказ

Package.json в конечном итоге выглядит что-то подобное:

{
  "name": "speech-to-emotion",
  "version": "1.0.0",
  "description": "We speak and it feels us :o",
  "main": "index.js",
  "scripts": {
    "server": "node server.js",
    "server-debug": "nodemon --inspect server.js"
  },
  "author": "daspinola",
  "license": "MIT",
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "nodemon": "^2.0.2"
  }
}

server.js Начинается так:

const express = require('express')
const path = require('path')

const port = 3000
const app = express()

app.use(express.static(path.join(__dirname, 'public')))

app.get('/', function(req, res) {
  res.sendFile(path.join(__dirname, 'index.html'))
})

app.get('/emotion', function(req, res) {
  // Valence of emotion section code will be here for not it returns nothing
  res.send({})
})

app.listen(port, function () {
  console.log(`Listening on port ${port}!`)
})

И с этим мы можем запустить NPM запустить сервер-отладки В командной строке и откройте браузер на localhost: 3000. Тогда мы увидим наше сообщение «Ничего в настоящее время», которое в файле HTML.

Веб-речь API

Эта API выходит из коробки в Chrome и содержит Производительность оформления Отказ Это то, что позволит нам включить микрофон, говорить и получить результат назад в виде текста.

Он работает с событиями, которые могут обнаружить, например, когда аудио сначала и последний захвачен.

На данный момент нам понадобится onresult и oeend События, поэтому мы можем проверить, какой микрофон захвачен и когда он перестает работать соответственно.

Чтобы сделать наш первый звук для захвата текста, нам просто нуждаются в дюжина линий или около того кода в нашем распознавание.js файл.

const recognition = new webkitSpeechRecognition()
recognition.lang = 'en-US'

recognition.onresult = function(event) {
  const results = event.results;
  const transcript = results[0][0].transcript
  
  console.log('text ->', transcript)
}

recognition.onend = function() {
  console.log('disconnected')
}

recognition.start()

Мы можем найти список доступных языков в Google Docs здесь Отказ

Если мы хотим, чтобы он остался на связи больше нескольких секунд (или, когда мы говорим более одного раза), есть свойство под названием непрерывный Отказ Это можно изменить так же, как Лэнг Собственность, просто назначая это правда Отказ Это сделает микрофон слушать аудио на неопределенный срок.

const recognition = new webkitSpeechRecognition()
recognition.lang = 'en-US'
recognition.continuous = true

recognition.onresult = function(event) {
  const results = event.results;
  const transcript = results[results.length-1][0].transcript
  
  console.log('text ->', transcript)
}

recognition.onend = function() {
  console.log('disconnected')
}

recognition.start()

Если мы обновим нашу страницу, сначала следует спросить, хотите ли мы разрешить использование микрофона. После ответа Да, мы можем говорить и проверить на Chrome devtools утешать результат нашей речи.

Ненормативность проявляется цензуре, и, похоже, нет способа удалить цензуру. То, что это значит, что мы не можем положиться на ненормативную лексику за счет забивания, хотя Афинн не доцензурный.

Примечание: На момент написания этот API можно найти только в Chrome и Android с ожидаемой поддержкой EDGE в ближайшем будущем. Вероятно, существуют многобилы или другие инструменты, которые дают лучшую совместимость браузера, но я не проверил их. Вы можете проверить совместимость в Могу ли я использовать Отказ

Сделать запрос

Для запроса простой извлекать достаточно. Мы отправляем транскрипта в качестве параметра запроса, который мы позвоним текст Отказ

Наше onresult Функция должна теперь выглядеть так:

  recognition.onresult = function(event) {
    const results = event.results;
    const transcript = results[results.length-1][0].transcript

    // making a request to our /emotion endpoint that we defined on the project start and setup section
    fetch(`/emotion?text=${transcript}`)
      .then((response) => response.json())
      .then((result) => {
        console.log('result ->', result) // should be undefined
      })
      .catch((e) => {
        console.error('Request error -> ', e)
      })
  }

Валентность эмоций

Валентность можно рассматривать как способ измерить, если наши эмоции положительны или отрицательны, и если они создают низкий или высокий возбуждение.

Для этого проекта мы будем использовать два эмоция: счастлив на положительной стороне для любого балла выше нуля, а расстроить на отрицательной стороне для баллов ниже нуля. Баллы нуля будут рассматриваться как равнодушные. Любой балл 0 будет рассматриваться как « Что?! »

Список AFINN забита от -5 до 5, и файл содержит слова, организованные, как это:

hope 2
hopeful 2
hopefully 2
hopeless -2
hopelessness -2
hopes 2
hoping 2
horrendous -3
horrible -3
horrific -3

В качестве примера, скажем, мы говорили с микрофоном и сказали: «Я надеюсь, что это не ужасно». Это было бы 2 Очки для “надежды” и -3 Точки для «ужасных», которые сделали бы наш приговор негативным с -1 точки. Все остальные слова, которые не в списке, мы бы проигнорировали для оценки.

Мы могли бы разбирать файл и преобразовать его в файл JSON, который выглядит похоже на это:

{
  : ,
  : ,
  ..
}

И тогда мы могли бы проверить каждое слово в тексте и суммировать оценки. Но это то, что Эндрю Сливински уже сделал с настроения Отказ Таким образом, мы собираемся использовать это вместо того, чтобы кодировать все с нуля.

Чтобы установить мы используем NPM установить настроение и открыть server.js Таким образом, мы можем импортировать библиотеку с помощью:

const Sentiment = require('sentiment');

Сопровождается изменением маршрута «/эмоции» на:

app.get('/emotion', function(req, res) {
  const sentiment = new Sentiment()
  const text = req.query.text // this returns our request query "text"
  const score = sentiment.analyze(text);

  res.send(score)
})

sentiament.Analyze () Описан шаги ранее: он проверяет каждое слово нашего текста против списка Afinn и дает нам счет в конце.

Переменная Оценка будет иметь объект, похожий на это:

{
  score: 7,
  comparative: 2.3333333333333335,
  calculation: [ { awesome: 4 }, { good: 3 } ],
  tokens: [ 'good', 'awesome', 'film' ],
  words: [ 'awesome', 'good' ],
  positive: [ 'awesome', 'good' ],
  negative: []
}

Теперь, когда у нас вернулась оценка, мы просто должны сделать это шоу в нашем браузере.

Примечание: Afinn на английском языке. Хотя мы можем выбрать другие языки в веб-речевом API, нам придется найти забитый список, похожий на Afinn на нашем желаемом языке, чтобы сделать соответствие.

Заставляя это улыбнуться

Для нашего последнего шага мы обновим наше index.html Чтобы отобразить область, где мы можем показать эмодзи. Итак, мы меняем это следующим:


  
    
      Speech to emotion
    
    
  
  
    
    

Эмодзи, используемый в этом проекте, бесплатен для коммерческого использования и можно найти здесь Отказ Слава художнику.

Мы загружаем иконы, которые нам нравятся, и добавьте их в папку изображений. Мы будем нуждаться в Emoji для:

  • Ошибка . – Когда возникает ошибка
  • холостой – всякий раз, когда микрофон не активен
  • слушать – Когда микрофон подключен и ждет ввода
  • Отрицательный – Для положительных баллов
  • Нейтральный – Ибо когда счет равен нулю
  • Положительный – Для отрицательных баллов
  • Поиск – Ибо когда наш запрос сервера делается

И в нашем emojis.csss Мы просто добавляем:

.emoji img {
  width: 100px;
  width: 100px;
}

.emoji .error {
  content:url("../images/error.png");
}

.emoji .idle {
  content:url("../images/idle.png");
}

.emoji .listening {
  content:url("../images/listening.png");
}

.emoji .negative {
  content:url("../images/negative.png");
}

.emoji .neutral {
  content:url("../images/neutral.png");
}

.emoji .positive {
  content:url("../images/positive.png");
}

.emoji .searching {
  content:url("../images/searching.png");
}

Когда мы перезагружаем страницу после этих изменений, она покажет холостой emoji. Это никогда не меняется, хотя, так как мы не заменили наши холостой Класс в элементе в зависимости от сценария.

Исправить, что мы идем в последний раз к нашему распознавание.js файл. Там мы собираемся добавить функцию, чтобы изменить emoji:

/**
 * @param {string} type - could be any of the following:
 *   error|idle|listening|negative|positive|searching
 */
function setEmoji(type) {
  const emojiElem = document.querySelector('.emoji img')
  emojiElem.classList = type
}

В ответ нашего запроса на сервер мы добавляем проверку на положительный, отрицательный или нейтральный счет и позвоните нашему SeteMoji Функция соответственно:

console.log(transcript) // So we know what it understood when we spoke

setEmoji('searching')

fetch(`/emotion?text=${transcript}`)
  .then((response) => response.json())
  .then((result) => {
    if (result.score > 0) {
      setEmoji('positive')
    } else if (result.score < 0) {
      setEmoji('negative')
    } else {
      setEmoji('listening')
    }
  })
  .catch((e) => {
    console.error('Request error -> ', e)
    recognition.abort()
  })

Наконец, мы добавляем события OneRor и Оносиостарт и изменить событие oeend Таким образом, мы у нас есть с надлежащей эмоджи.

  recognition.onerror = function(event) {
    console.error('Recognition error -> ', event.error)
    setEmoji('error')
  }

  recognition.onaudiostart = function() {
    setEmoji('listening')
  }

  recognition.onend = function() {
    setEmoji('idle')
  }

Наш финал распознавание.js Файл должен выглядеть что-то вроде этого:

document.addEventListener('DOMContentLoaded', speechToEmotion, false);

function speechToEmotion() {
  const recognition = new webkitSpeechRecognition()
  recognition.lang = 'en-US'
  recognition.continuous = true

  recognition.onresult = function(event) {
    const results = event.results;
    const transcript = results[results.length-1][0].transcript

    console.log(transcript)

    setEmoji('searching')

    fetch(`/emotion?text=${transcript}`)
      .then((response) => response.json())
      .then((result) => {
        if (result.score > 0) {
          setEmoji('positive')
        } else if (result.score < 0) {
          setEmoji('negative')
        } else {
          setEmoji('listening')
        }
      })
      .catch((e) => {
        console.error('Request error -> ', e)
        recognition.abort()
      })
  }

  recognition.onerror = function(event) {
    console.error('Recognition error -> ', event.error)
    setEmoji('error')
  }

  recognition.onaudiostart = function() {
    setEmoji('listening')
  }

  recognition.onend = function() {
    setEmoji('idle')
  }

  recognition.start();

  /**
   * @param {string} type - could be any of the following:
   *   error|idle|listening|negative|positive|searching
   */
  function setEmoji(type) {
    const emojiElem = document.querySelector('.emoji img')
    emojiElem.classList = type
  }
}

И путем проверки нашего проекта теперь мы можем увидеть окончательные результаты:

Примечание: Вместо console.log Чтобы проверить, что понятно распознавание, мы можем добавить элемент на нашем HTML и заменить console.log. Таким образом, у нас всегда есть доступ к тому, что он понял.

Последние замечания

Есть некоторые области, где этот проект может быть значительно улучшен:

  • Это не может обнаружить сарказм
  • Нет способа проверить, разъяруются ли вы из-за цензуры речи к тексту API
  • Там, вероятно, способ сделать это только с голосом без преобразования в текст.

Из того, что я видел при исследовании этого проекта, есть реализации, которые проверяют, приведут ли ваш тон и настроение к продаже в колл-центре. И рассылка, которую я получил из грамматики, который использует его, чтобы проверить тонус того, что вы пишете. Так как вы можете видеть, есть интересные приложения.

Надеюсь, этот контент помог каким-то образом помог. Если кто-нибудь строит ничего, используя этот стек, дайте мне знать – всегда весело посмотреть, что люди строят.

Код можно найти в моем github здесь Отказ

Увидимся в следующем, в то же время иди что-нибудь!