0.1.1 • Published 1 year ago

@tiro-is/speech v0.1.1

Weekly downloads
-
License
See specified lic...
Repository
-
Last release
1 year ago

@tiro-is/speech

A utility library for speech recognition provided by Tiro.

Usage

Installation

yarn add @tiro-is/speech

Documentation

An autogenerated API reference doc is available at ./docs.

Example usage

Here is a simple vanilla JS/TS example of how this library can be used:

index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Example</title>
    <style type="text/css">
     #root {
       font-family: sans-serif;
     }
     span#partial-results {
       font-style: italic;
     }
     button#pause {
       width: 50px;
       height: 30px;
     }
    </style>
  </head>

  <body>
    <div id="root">
      <audio id="audio" controls></audio>
      <button id="pause">Pause</button>
      <p>
        <span id="final-results"></span>
        <span id="partial-results"></span>
      </p>
    </div>
    <script type="module" src="./index.ts"></script>
  </body>
</html>

index.ts:

import { AudioSrcUpdatedEvent, SpeechHandler, SpeechResultsEvent, Duration } from '@tiro-is/speech';

const partial = document.getElementById('partial-results')!;
const final = document.getElementById('final-results')!;
const audio = document.getElementById('audio')! as HTMLAudioElement;
const pause = document.getElementById('pause')!;

const formatTs = (ts: Duration) => {
    return `${ts.seconds}.${ts.nanos.toString().padStart(9, '0').slice(0, 3)}s`;
};

navigator.mediaDevices
    .getUserMedia({
        audio: true,
        video: false,
    })
    .then((stream) => {
        const speech = new SpeechHandler({
            stream,
            languageCode: 'is-IS-x-ortho',
            serverUrl: 'https://speech.talgreinir.is',
            serverKey: 'ak_...',
        });

        pause.addEventListener('click', () => {
            if (speech!.paused) {
                pause.innerText = 'Rec';
                speech!.resume();
            } else {
                speech!.pause();
                pause.innerText = 'Pause';
            }
        });

        speech.addEventListener('audiosrcupdated', (event: AudioSrcUpdatedEvent) => {
            if (audio.paused) {
                const currentTime = audio.currentTime;
                audio.src = event.detail.audioURL;
                audio.onloadeddata = () => {
                    audio.currentTime = currentTime;
                };
            }
        });

        speech.addEventListener('speechresults', (event: SpeechResultsEvent) => {
            if (event.detail.isFinal) {
                const tobeAdded = event.detail.words
                    .map((w) => {
                        return `<span data-start-time="${formatTs(w.startTime)}" data-end-time="${formatTs(
                            w.endTime,
                        )}">${w.word.replace('\n', '<br>')}</span>`;
                    })
                    .join(' ');
                final.innerHTML = `${final.innerHTML} ${tobeAdded}`;
                partial.innerHTML = '';
            } else {
                partial.innerHTML = event.detail.transcript.replace('\n', '<br>');
            }
        });
    });
0.1.1

1 year ago