UNPKG

@lakshmiprasanth/react-voice-to-text

Version:

A modern React package for voice-to-text conversion with real-time speech recognition and file upload support

482 lines (478 loc) 14.4 kB
'use strict'; /** * Check browser support for speech recognition and related APIs */ function getBrowserSupport() { if (typeof window === 'undefined') { return { webSpeechAPI: false, mediaRecorder: false, getUserMedia: false, browser: { name: 'unknown', version: 'unknown' } }; } const browserInfo = getBrowserInfo(); return { webSpeechAPI: 'SpeechRecognition' in window || 'webkitSpeechRecognition' in window, mediaRecorder: 'MediaRecorder' in window, getUserMedia: 'mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices, browser: browserInfo }; } /** * Get the SpeechRecognition constructor for the current browser */ function getSpeechRecognition() { if (typeof window === 'undefined') { return null; } return (window.SpeechRecognition || window.webkitSpeechRecognition || null); } /** * Get browser name and version */ function getBrowserInfo() { if (typeof navigator === 'undefined') { return { name: 'unknown', version: 'unknown' }; } const userAgent = navigator.userAgent; let name = 'unknown'; let version = 'unknown'; // Chrome if (userAgent.includes('Chrome') && !userAgent.includes('Edg')) { name = 'Chrome'; const match = userAgent.match(/Chrome\/(\d+)/); if (match) version = match[1]; } // Safari else if (userAgent.includes('Safari') && !userAgent.includes('Chrome')) { name = 'Safari'; const match = userAgent.match(/Version\/(\d+)/); if (match) version = match[1]; } // Firefox else if (userAgent.includes('Firefox')) { name = 'Firefox'; const match = userAgent.match(/Firefox\/(\d+)/); if (match) version = match[1]; } // Edge else if (userAgent.includes('Edg')) { name = 'Edge'; const match = userAgent.match(/Edg\/(\d+)/); if (match) version = match[1]; } return { name, version }; } // Recognition utility functions for voice-to-text package /** * Create a new SpeechRecognition instance with the given configuration */ function createSpeechRecognition(config) { const SpeechRecognition = getSpeechRecognition(); if (!SpeechRecognition) { return null; } const recognition = new SpeechRecognition(); // Configure recognition properties recognition.continuous = config.continuous ?? true; recognition.interimResults = config.interimResults ?? true; recognition.lang = config.language ?? 'en-US'; recognition.maxAlternatives = config.maxAlternatives ?? 1; return recognition; } /** * Check if speech recognition is available in the current environment */ function isSpeechRecognitionAvailable() { const support = getBrowserSupport(); return support.webSpeechAPI; } /** * Validate speech recognition configuration */ function validateSpeechRecognitionConfig(config) { const errors = []; if (config.language && !isValidLanguageCode(config.language)) { errors.push(`Invalid language code: ${config.language}`); } if (config.maxAlternatives && (config.maxAlternatives < 1 || config.maxAlternatives > 10)) { errors.push('maxAlternatives must be between 1 and 10'); } return { isValid: errors.length === 0, errors }; } /** * Check if a language code is valid */ function isValidLanguageCode(languageCode) { // Basic validation - language codes should be in format like 'en-US', 'es-ES', etc. const languageCodePattern = /^[a-z]{2}(-[A-Z]{2})?$/; return languageCodePattern.test(languageCode); } /** * Get supported language codes */ function getSupportedLanguages() { return [ 'en-US', 'en-GB', 'en-AU', 'en-CA', 'en-IN', 'en-IE', 'en-NZ', 'en-ZA', 'es-ES', 'es-MX', 'es-AR', 'es-CL', 'es-CO', 'es-PE', 'es-VE', 'es-EC', 'fr-FR', 'fr-CA', 'fr-BE', 'fr-CH', 'fr-LU', 'fr-MC', 'de-DE', 'de-AT', 'de-CH', 'de-LU', 'de-LI', 'it-IT', 'it-CH', 'pt-BR', 'pt-PT', 'ru-RU', 'ru-UA', 'ru-KZ', 'ja-JP', 'ko-KR', 'zh-CN', 'zh-TW', 'zh-HK', 'ar-SA', 'ar-EG', 'ar-IL', 'ar-JO', 'ar-LB', 'ar-MA', 'ar-PS', 'ar-SY', 'hi-IN', 'th-TH', 'tr-TR', 'pl-PL', 'nl-NL', 'nl-BE', 'sv-SE', 'da-DK', 'no-NO', 'fi-FI', 'cs-CZ', 'hu-HU', 'ro-RO', 'bg-BG', 'hr-HR', 'sk-SK', 'sl-SI', 'et-EE', 'lv-LV', 'lt-LT', 'mt-MT', 'el-GR', 'he-IL', 'id-ID', 'ms-MY', 'vi-VN', 'uk-UA', 'ca-ES', 'eu-ES', 'gl-ES', 'cy-GB', 'ga-IE', 'is-IS', 'mk-MK', 'sq-AL', 'sr-RS', 'bs-BA', 'me-ME', 'mn-MN', 'ka-GE', 'hy-AM', 'az-AZ', 'uz-UZ', 'kk-KZ', 'ky-KG', 'tg-TJ', 'fa-IR', 'ur-PK', 'bn-BD', 'si-LK', 'my-MM', 'km-KH', 'lo-LA', 'ne-NP', 'gu-IN', 'pa-IN', 'te-IN', 'kn-IN', 'ml-IN', 'ta-IN', 'or-IN', 'as-IN', 'mr-IN', 'sa-IN', 'bo-CN', 'dz-BT', 'ti-ER', 'so-SO', 'sw-KE', 'rw-RW', 'lg-UG', 'am-ET', 'ha-NG', 'yo-NG', 'ig-NG', 'zu-ZA', 'af-ZA', 'xh-ZA', 'st-ZA', 'tn-ZA', 'ts-ZA', 've-ZA', 'nr-ZA', 'ss-ZA', 'sn-ZW', 'ny-MW', 'mg-MG', 'co-FR', 'br-FR', 'oc-FR', 'gv-GB', 'kw-GB', 'fo-FO', 'sm-WS', 'to-TO', 'fj-FJ', 'haw-US', 'mi-NZ', 'qu-PE', 'qu-EC', 'qu-BO', 'ay-BO', 'gn-PY', 'gn-AR', 'gn-BO', 'gn-PE', 'gn-EC', 'gn-CO', 'gn-VE', 'gn-GY', 'gn-SR', 'gn-FR', 'gn-BR', 'gn-UY', 'gn-AR', 'gn-PY', 'gn-BO', 'gn-PE', 'gn-EC', 'gn-CO', 'gn-VE', 'gn-GY', 'gn-SR', 'gn-FR', 'gn-BR', 'gn-UY' ]; } /** * Get language name from language code */ function getLanguageName(languageCode) { const languageNames = { 'en-US': 'English (US)', 'en-GB': 'English (UK)', 'en-AU': 'English (Australia)', 'en-CA': 'English (Canada)', 'en-IN': 'English (India)', 'en-IE': 'English (Ireland)', 'en-NZ': 'English (New Zealand)', 'en-ZA': 'English (South Africa)', 'es-ES': 'Spanish (Spain)', 'es-MX': 'Spanish (Mexico)', 'es-AR': 'Spanish (Argentina)', 'es-CL': 'Spanish (Chile)', 'es-CO': 'Spanish (Colombia)', 'es-PE': 'Spanish (Peru)', 'es-VE': 'Spanish (Venezuela)', 'es-EC': 'Spanish (Ecuador)', 'fr-FR': 'French (France)', 'fr-CA': 'French (Canada)', 'fr-BE': 'French (Belgium)', 'fr-CH': 'French (Switzerland)', 'fr-LU': 'French (Luxembourg)', 'fr-MC': 'French (Monaco)', 'de-DE': 'German (Germany)', 'de-AT': 'German (Austria)', 'de-CH': 'German (Switzerland)', 'de-LU': 'German (Luxembourg)', 'de-LI': 'German (Liechtenstein)', 'it-IT': 'Italian (Italy)', 'it-CH': 'Italian (Switzerland)', 'pt-BR': 'Portuguese (Brazil)', 'pt-PT': 'Portuguese (Portugal)', 'ru-RU': 'Russian (Russia)', 'ru-UA': 'Russian (Ukraine)', 'ru-KZ': 'Russian (Kazakhstan)', 'ja-JP': 'Japanese (Japan)', 'ko-KR': 'Korean (South Korea)', 'zh-CN': 'Chinese (Simplified)', 'zh-TW': 'Chinese (Traditional)', 'zh-HK': 'Chinese (Hong Kong)', 'ar-SA': 'Arabic (Saudi Arabia)', 'ar-EG': 'Arabic (Egypt)', 'ar-IL': 'Arabic (Israel)', 'ar-JO': 'Arabic (Jordan)', 'ar-LB': 'Arabic (Lebanon)', 'ar-MA': 'Arabic (Morocco)', 'ar-PS': 'Arabic (Palestine)', 'ar-SY': 'Arabic (Syria)', 'hi-IN': 'Hindi (India)', 'th-TH': 'Thai (Thailand)', 'tr-TR': 'Turkish (Turkey)', 'pl-PL': 'Polish (Poland)', 'nl-NL': 'Dutch (Netherlands)', 'nl-BE': 'Dutch (Belgium)', 'sv-SE': 'Swedish (Sweden)', 'da-DK': 'Danish (Denmark)', 'no-NO': 'Norwegian (Norway)', 'fi-FI': 'Finnish (Finland)', 'cs-CZ': 'Czech (Czech Republic)', 'hu-HU': 'Hungarian (Hungary)', 'ro-RO': 'Romanian (Romania)', 'bg-BG': 'Bulgarian (Bulgaria)', 'hr-HR': 'Croatian (Croatia)', 'sk-SK': 'Slovak (Slovakia)', 'sl-SI': 'Slovenian (Slovenia)', 'et-EE': 'Estonian (Estonia)', 'lv-LV': 'Latvian (Latvia)', 'lt-LT': 'Lithuanian (Lithuania)', 'mt-MT': 'Maltese (Malta)', 'el-GR': 'Greek (Greece)', 'he-IL': 'Hebrew (Israel)', 'id-ID': 'Indonesian (Indonesia)', 'ms-MY': 'Malay (Malaysia)', 'vi-VN': 'Vietnamese (Vietnam)', 'uk-UA': 'Ukrainian (Ukraine)', 'ca-ES': 'Catalan (Spain)', 'eu-ES': 'Basque (Spain)', 'gl-ES': 'Galician (Spain)', 'cy-GB': 'Welsh (UK)', 'ga-IE': 'Irish (Ireland)', 'is-IS': 'Icelandic (Iceland)', 'mk-MK': 'Macedonian (North Macedonia)', 'sq-AL': 'Albanian (Albania)', 'sr-RS': 'Serbian (Serbia)', 'bs-BA': 'Bosnian (Bosnia and Herzegovina)', 'me-ME': 'Montenegrin (Montenegro)', 'mn-MN': 'Mongolian (Mongolia)', 'ka-GE': 'Georgian (Georgia)', 'hy-AM': 'Armenian (Armenia)', 'az-AZ': 'Azerbaijani (Azerbaijan)', 'uz-UZ': 'Uzbek (Uzbekistan)', 'kk-KZ': 'Kazakh (Kazakhstan)', 'ky-KG': 'Kyrgyz (Kyrgyzstan)', 'tg-TJ': 'Tajik (Tajikistan)', 'fa-IR': 'Persian (Iran)', 'ur-PK': 'Urdu (Pakistan)', 'bn-BD': 'Bengali (Bangladesh)', 'si-LK': 'Sinhala (Sri Lanka)', 'my-MM': 'Burmese (Myanmar)', 'km-KH': 'Khmer (Cambodia)', 'lo-LA': 'Lao (Laos)', 'ne-NP': 'Nepali (Nepal)', 'gu-IN': 'Gujarati (India)', 'pa-IN': 'Punjabi (India)', 'te-IN': 'Telugu (India)', 'kn-IN': 'Kannada (India)', 'ml-IN': 'Malayalam (India)', 'ta-IN': 'Tamil (India)', 'or-IN': 'Odia (India)', 'as-IN': 'Assamese (India)', 'mr-IN': 'Marathi (India)', 'sa-IN': 'Sanskrit (India)', 'bo-CN': 'Tibetan (China)', 'dz-BT': 'Dzongkha (Bhutan)', 'ti-ER': 'Tigrinya (Eritrea)', 'so-SO': 'Somali (Somalia)', 'sw-KE': 'Swahili (Kenya)', 'rw-RW': 'Kinyarwanda (Rwanda)', 'lg-UG': 'Ganda (Uganda)', 'am-ET': 'Amharic (Ethiopia)', 'ha-NG': 'Hausa (Nigeria)', 'yo-NG': 'Yoruba (Nigeria)', 'ig-NG': 'Igbo (Nigeria)', 'zu-ZA': 'Zulu (South Africa)', 'af-ZA': 'Afrikaans (South Africa)', 'xh-ZA': 'Xhosa (South Africa)', 'st-ZA': 'Southern Sotho (South Africa)', 'tn-ZA': 'Tswana (South Africa)', 'ts-ZA': 'Tsonga (South Africa)', 've-ZA': 'Venda (South Africa)', 'nr-ZA': 'Southern Ndebele (South Africa)', 'ss-ZA': 'Swati (South Africa)', 'sn-ZW': 'Shona (Zimbabwe)', 'ny-MW': 'Chichewa (Malawi)', 'mg-MG': 'Malagasy (Madagascar)', 'co-FR': 'Corsican (France)', 'br-FR': 'Breton (France)', 'oc-FR': 'Occitan (France)', 'gv-GB': 'Manx (UK)', 'kw-GB': 'Cornish (UK)', 'fo-FO': 'Faroese (Faroe Islands)', 'sm-WS': 'Samoan (Samoa)', 'to-TO': 'Tongan (Tonga)', 'fj-FJ': 'Fijian (Fiji)', 'haw-US': 'Hawaiian (US)', 'mi-NZ': 'Maori (New Zealand)', 'qu-PE': 'Quechua (Peru)', 'qu-EC': 'Quechua (Ecuador)', 'qu-BO': 'Quechua (Bolivia)', 'ay-BO': 'Aymara (Bolivia)', 'gn-PY': 'Guarani (Paraguay)', 'gn-AR': 'Guarani (Argentina)', 'gn-BO': 'Guarani (Bolivia)', 'gn-PE': 'Guarani (Peru)', 'gn-EC': 'Guarani (Ecuador)', 'gn-CO': 'Guarani (Colombia)', 'gn-VE': 'Guarani (Venezuela)', 'gn-GY': 'Guarani (Guyana)', 'gn-SR': 'Guarani (Suriname)', 'gn-FR': 'Guarani (French Guiana)', 'gn-BR': 'Guarani (Brazil)', 'gn-UY': 'Guarani (Uruguay)' }; return languageNames[languageCode] || languageCode; } /** * Format a SpeechRecognitionResult for display */ function formatRecognitionResult(result) { const confidence = result.confidence ? ` (${(result.confidence * 100).toFixed(1)}%)` : ''; const status = result.isFinal ? 'Final' : 'Interim'; return `${result.transcript}${confidence} [${status}]`; } /** * Merge multiple recognition results */ function mergeRecognitionResults(results) { return results .filter(result => result.isFinal) .map(result => result.transcript) .join(' '); } /** * Get the best result from multiple alternatives */ function getBestResult(results) { if (results.length === 0) { return null; } // Return the result with the highest confidence return results.reduce((best, current) => { if (!best) return current; if (!current) return best; return (current.confidence || 0) > (best.confidence || 0) ? current : best; }); } exports.createSpeechRecognition = createSpeechRecognition; exports.formatRecognitionResult = formatRecognitionResult; exports.getBestResult = getBestResult; exports.getLanguageName = getLanguageName; exports.getSupportedLanguages = getSupportedLanguages; exports.isSpeechRecognitionAvailable = isSpeechRecognitionAvailable; exports.isValidLanguageCode = isValidLanguageCode; exports.mergeRecognitionResults = mergeRecognitionResults; exports.validateSpeechRecognitionConfig = validateSpeechRecognitionConfig; //# sourceMappingURL=recognition.js.map