API веб-аудио: как я могу распознавать речь и записывать до тишины, с кнопкой Push-To-Talk или без нее

Я успешно запускаю клиентскую веб-страницу, которая действует как отправитель голосовых сообщений, используя MediaRecorder API:

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

Это своего рода PTT (Push To Talk) пользовательский опыт, когда пользователю нужно просто нажать клавишу (нажать), чтобы активировать запись голоса. И после этого он должен отпустить клавишу, чтобы остановить запись, инициировав отправку сообщения на сервер.

Вот фрагмент кода javascript, который я использовал:

    navigator.mediaDevices
      .getUserMedia({ audio: true })
        .then(stream => {

          const mediaRecorder = new MediaRecorder(stream)
          var audioChunks = []

          //
          // start and stop recording:
          // keyboard (any key) events
          //
          document
            .addEventListener('keydown', () => mediaRecorder.start())

          document
            .addEventListener('keyup', () => mediaRecorder.stop())

          //
          // add data chunk to mediarecorder
          //
          mediaRecorder
            .addEventListener('dataavailable', event => {
              audioChunks.push(event.data)
            })

          //
          // mediarecorder event stop
          // trigger socketio audio message emission.
          //
          mediaRecorder
            .addEventListener('stop', () => {
               socket.emit('audioMessage', audioChunks)
              audioChunks = []
            })

        })

Теперь я хочу активировать/деактивировать запись звука (речи) не только с кнопки/клавиши/касания веб-страницы, но и с внешнего аппаратного микрофона (с кнопкой Push-To-Talk). Точнее хочу подключить промышленную гарнитуру с кнопкой PTT на дужке, смотрите фото:

промышленная гарнитура с кнопкой PTT на ушной раковине

Кстати, кнопка PTT — это просто физическая кнопка, которая действует как тумблер короткого замыкания, как на фото, просто в качестве примера: схема кнопки

  • По умолчанию микрофон заземлен и входной сигнал == 0
  • При нажатии кнопки PTT микро активируется и входной сигнал != 0.

Теперь мой вопрос: как я могу использовать API веб-аудио, чтобы определить, когда нажата кнопка PTT (поэтому звуковой сигнал> 0), чтобы сделать mediaRecorder.start() ?

чтение здесь: думаю, мне нужно использовать возвращенный поток на mediaDevices.getUserMedia и создадим процессор AudioContext():

  navigator.mediaDevices.getUserMedia({ audio: true, video: false })
      .then(handleSuccess);

  const handleSuccess = function(stream) {
    const context = new AudioContext();
    const source = context.createMediaStreamSource(stream);
    const processor = context.createScriptProcessor(1024, 1, 1);

    source.connect(processor);
    processor.connect(context.destination);

    processor.onaudioprocess = function(e) {
      // Do something with the data, 
      console.log(e.inputBuffer);
    };
  };

Но что должна делать функция processor.onaudioprocess, чтобы запускать (громкость > DELTA) и останавливать (volume ‹ DELTA) MediaRecorder?

Я предполагаю, что определение объема может быть полезно для двух ситуаций:

  • С помощью кнопки PTT, где пользователь явно определяет продолжительность выступления, нажимая и отпуская кнопку
  • Без кнопки PTT в этом случае голосовое сообщение создается в так называемом режиме VOX (непрерывная обработка звука)

Любая идея?


person Giorgio Robino    schedule 31.05.2020    source источник
comment
веб-аудио API имеет цикл событий ... звуковой буфер заполняется внутри этого цикла ... чтобы определить тишину, просто проверьте этот буфер и после X периода времени среднеквадратичной амплитуды ‹ Y объявите тишину   -  person Scott Stensland    schedule 31.05.2020
comment
см. stackoverflow.com/questions/24515978/   -  person Scott Stensland    schedule 31.05.2020
comment
спасибо @ScottStensland, следуя вашему предложению, я сделал: github.com/solyarisoftware/WeBAD   -  person Giorgio Robino    schedule 17.12.2020


Ответы (1)


Я отвечаю на свой вопрос, чтобы поделиться решением, которое я нашел.

Старый проект @cwilso: volume-meter кажется точной реализацией того, что @scott- Стенсланд заявил в комментарии выше. См. демонстрацию: https://webaudiodemos.appspot.com/volume-meter/.

ОБНОВИТЬ

Кстати, используя проект @cwilso и предложение @scott-stensland, я реализовал проект с открытым исходным кодом WeBAD, чтобы решить также мой первоначальный вопрос:

https://github.com/solyarisoftware/WeBAD

person Giorgio Robino    schedule 05.06.2020