Plugin Directory

Changeset 2289691


Ignore:
Timestamp:
04/23/2020 12:32:39 AM (6 years ago)
Author:
mspanwa2
Message:

Version 2.0.0 Add support for 130 languages

Location:
universal-voice-search/trunk
Files:
36 added
17 edited

Legend:

Unmodified
Added
Removed
  • universal-voice-search/trunk/classes/plugin.php

    r2225505 r2289691  
    1414    public static $uvs_api_access_key = null;
    1515    public static $uvs_admin_notice_logo = "";
    16     public static $uvs_selected_language = "English";
     16    public static $uvs_selected_language = "en-US";
    1717    public static $uvs_floating_mic_position = "Middle Right";
    18     public static $uvs_file_type  = '.min';
    19     //public static $uvs_file_type = ''; // For debugging
    20 
    21     /*
    22      * Note: This map of language name as value (Eg: English) maps to value being saved to DB for plugin language option on settings page
    23      *
    24      * The keys of map (eg: en_US) are taken into account as of Wordpress version 5.3.2
    25      */
    26     public static $uvs_auto_detect_lang_map = array(
    27         'en_US' => 'English',
    28         'en_GB' => 'British English',
    29         'de_DE' => 'German',
    30         'pt_PT' => 'Portuguese',
    31         'zh_CN' => 'Chinese',
    32         'zh_TW' => 'Chinese',
    33         'fr_FR' => 'French',
    34         'ja'    => 'Japanese',
    35         'ja_JP' => 'Japanese',
    36         'ko_KR' => 'Korean',
    37         'es_ES' => 'Spanish'
     18    //public static $uvs_file_type  = '.min';
     19    public static $uvs_file_type = ''; // For debugging
     20    public static $uvs_settings_updated_ts  = null;
     21
     22    /**
     23     * This map of language name as value (Eg: English) maps to value being saved to DB for plugin language option on settings page
     24     *
     25     * With additional 130 language support feature this fallback is needed to preserve plugin language while upgrading/updating existing plugin on their site
     26     */
     27    public static $uvs_fallback_lang_map = array(
     28        'en-US' => 'English',
     29        'en-GB' => 'British English',
     30        'de-DE' => 'German',
     31        'pt-PT' => 'Portuguese',
     32        'zh-CN' => 'Chinese',
     33        'zh-TW' => 'Chinese',
     34        'fr-FR' => 'French',
     35        'ja-JP' => 'Japanese',
     36        'ko-KR' => 'Korean',
     37        'es-ES' => 'Spanish'
    3838    );
    3939
     40    // For access keys
     41    public static $uvs_voice_services_access_keys = array(
     42        'api_url' => "https://yjonpgjqs9.execute-api.us-east-1.amazonaws.com/V2",
     43        'db_col_name' => 'uvs_navigation_voice_services_access_keys',
     44        'value' => array(
     45            'ibm_stt_token' => null,
     46            'g_stt_key'     => null,
     47            'g_tts_key'     => null,
     48            'synched_at'    => null
     49        )
     50    );
     51
     52    // For browser and OS detection
     53    public static $uvs_client_info = array(
     54        'chrome'       => false,
     55        'firefox'      => false,
     56        'safari'       => false,
     57        'edge'         => false,
     58        'ie'           => false,
     59        'macIE'        => false,
     60        'winIE'        => false,
     61        'iphoneSafari' => false,
     62        'ns4'          => false,
     63        'opera'        => false,
     64        'mac'          => false,
     65        'opera'        => false,
     66        'opera'        => false
     67    );
     68
    4069    /**
    4170     * Plugin version.
    4271     */
    43     const VERSION = '1.1.4';
     72    const VERSION = '2.0.0';
    4473   
    4574    /**
     
    4877    protected function __construct()
    4978    {
     79        global
     80        $is_iphone, // (boolean) iPhone Safari
     81        $is_chrome, // (boolean) Google Chrome
     82        $is_safari, // (boolean) Safari
     83        $is_NS4, // (boolean) Netscape 4
     84        $is_opera, // (boolean) Opera
     85        $is_macIE, // (boolean) Mac Internet Explorer
     86        $is_winIE, // (boolean) Windows Internet Explorer
     87        $is_gecko, // (boolean) FireFox
     88        $is_lynx, // (boolean)
     89        $is_IE, // (boolean) Internet Explorer
     90        $is_edge; // (boolean) Microsoft Edge
     91
     92        // Browser detection
     93        self::$uvs_client_info['chrome'] = $is_chrome;
     94        self::$uvs_client_info['firefox'] = $is_gecko;
     95        self::$uvs_client_info['safari'] = $is_safari;
     96        self::$uvs_client_info['edge'] = $is_edge;
     97        self::$uvs_client_info['ie'] = $is_IE;
     98        self::$uvs_client_info['macIE'] = $is_macIE;
     99        self::$uvs_client_info['winIE'] = $is_winIE;
     100        self::$uvs_client_info['iphoneSafari'] = $is_iphone;
     101        self::$uvs_client_info['ns4'] = $is_NS4;
     102        self::$uvs_client_info['opera'] = $is_opera;
     103
     104        // OS Detection
     105        self::$uvs_client_info['mac'] = stristr( $_SERVER['HTTP_USER_AGENT'],"mac") ? true : false;
     106        self::$uvs_client_info['linux'] = $is_lynx === true || stristr( $_SERVER['HTTP_USER_AGENT'],"linux") ? true : false;
     107        self::$uvs_client_info['windows'] = stristr( $_SERVER['HTTP_USER_AGENT'],"windows") ? true : false;
    50108        // Get database values
    51109        self::$uvs_license_key = get_option(Universal_Voice_Search_Settings_Page::BASIC_CONFIG_OPTION_NAMES['license_key'], null);
     
    67125        if (!($iPod == false && $iPhone == false && $iPad == false)) { /*self::$uvs_ios = true;*/ }
    68126
    69         if ($chrome_browser != false) { self::$is_chrome = true; }
     127        if ($chrome_browser != false) { /*self::$is_chrome = true;*/ }
    70128
    71129        $this->hook( 'plugins_loaded', 'add_hooks' );
     
    73131
    74132    /**
     133     * Static method to get third party voice services access keys
     134     *
     135     */
     136    public static function uvs_get_access_keys_from_db()
     137    {
     138        $temp_access_keys_from_db = get_option(self::$uvs_voice_services_access_keys['db_col_name'], null);
     139
     140        if (!!$temp_access_keys_from_db && is_array($temp_access_keys_from_db)) {
     141            if (array_key_exists('ibm_stt_token', $temp_access_keys_from_db)) {
     142                self::$uvs_voice_services_access_keys['value']['ibm_stt_token'] = $temp_access_keys_from_db['ibm_stt_token'];
     143            }
     144
     145            if (array_key_exists('g_stt_key', $temp_access_keys_from_db)) {
     146                self::$uvs_voice_services_access_keys['value']['g_stt_key'] = $temp_access_keys_from_db['g_stt_key'];
     147            }
     148
     149            if (array_key_exists('g_tts_key', $temp_access_keys_from_db)) {
     150                self::$uvs_voice_services_access_keys['value']['g_tts_key'] = $temp_access_keys_from_db['g_tts_key'];
     151            }
     152
     153            if (array_key_exists('synched_at', $temp_access_keys_from_db)) {
     154                self::$uvs_voice_services_access_keys['value']['synched_at'] = $temp_access_keys_from_db['synched_at'];
     155            }
     156
     157            unset($temp_access_keys_from_db);
     158        }
     159    }
     160
     161
     162    /**
    75163     * Adds hooks.
    76164     */
    77165    public function add_hooks()
    78166    {
     167        self::$uvs_settings_updated_ts = Universal_Voice_Search_Settings_Page::uvs_settings_modified_timestamp('set');
     168
    79169        $this->hook( 'init' );
    80170        $this->hook( 'admin_enqueue_scripts', 'enqueue_admin_scripts' );
    81171
    82         if ( self::$is_chrome == true
    83             || (self::$is_chrome == false && !empty(self::$uvs_license_key) && !empty(self::$uvs_api_access_key)) ) {
     172        if ((!empty(self::$uvs_license_key) && !empty(self::$uvs_api_access_key)) ||
     173            (self::$uvs_client_info['chrome'] === true && UvsLanguage::gcp_supported(self::$uvs_selected_language))) {
    84174            $this->hook( 'wp_enqueue_scripts', 'enqueue_frontend_scripts' );
    85175        }
     
    101191        add_action ( 'wp_ajax_nopriv_' . 'uvs_log_service_call', array($this, 'uvs_log_service_call'));
    102192
     193        // Register the action for HTTP Ajax request to refresh voice services token and keys
     194        add_action ( 'wp_ajax_nopriv_'.'uvs_refresh_access_keys', array($this, 'uvs_refresh_access_keys'));
     195        add_action ( 'wp_ajax_'.'uvs_refresh_access_keys', array($this, 'uvs_refresh_access_keys'));
     196
    103197        // Register action to hook into admin_notices to display dahsboard notices when license key is missing or invalid
    104198        if (empty(self::$uvs_license_key) || empty(self::$uvs_api_access_key)) {
     
    156250            self::$uvs_floating_mic_position = 'Middle Right';
    157251        }
    158     }
    159 
    160     /**
    161      * Class method to broadcast 'settings' page data in 'uvs.speech-handler.js'
    162      */
    163     public static function broadcast_api_meta_data()
    164     {
    165         $stt_model = '&model=en-US_BroadbandModel';
    166 
    167         switch (strtolower(self::$uvs_selected_language)) {
    168             case 'german':
    169                 $stt_model = '&model=de-DE_BroadbandModel';
    170                 break;
    171             case 'british english':
    172                 $stt_model = '&model=en-GB_BroadbandModel';
    173                 break;
    174             case 'portuguese':
    175                 $stt_model = '&model=pt-BR_BroadbandModel';
    176                 break;
    177             case 'chinese':
    178                 $stt_model = '&model=zh-CN_BroadbandModel';
    179                 break;
    180             case 'french':
    181                 $stt_model = '&model=fr-FR_BroadbandModel';
    182                 break;
    183             case 'japanese':
    184                 $stt_model = '&model=ja-JP_BroadbandModel';
    185                 break;
    186             case 'korean':
    187                 $stt_model = '&model=ko-KR_BroadbandModel';
    188                 break;
    189             case 'spanish':
    190                 $stt_model = '&model=es-ES_BroadbandModel';
    191                 break;
    192             default:
    193                $stt_model = '&model=en-US_BroadbandModel';
    194                 break;
    195         }
    196 
    197         $web_socket_url = array(
    198             'url'     => 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize',
    199             'tokenQs' => '?access_token=',
    200             'otherQs' => $stt_model
    201         );
    202         $token_api_url = 'https://yjonpgjqs9.execute-api.us-east-1.amazonaws.com/V2';
    203 
    204         // Make web socket url and token url available to 'uvs.speech-handler.js'
    205         wp_localize_script( 'uvs.speech-handler', 'uvsWebSocketUrl', $web_socket_url);
    206         wp_localize_script( 'uvs.speech-handler', 'uvsTokenApiUrl', $token_api_url);
    207 
    208         // Make token url available to 'uvs.audio-input-handler.js'
    209         wp_localize_script( 'uvs.audio-input-handler', 'uvsTokenApiUrl', $token_api_url);
     252
     253        // load access keys of third party voice services from local DB
     254        self::uvs_get_access_keys_from_db();
     255
     256        // Obtain third party voice services token and keys from api
     257        self::uvs_synch_voice_access_keys();
     258
     259        // Inject short audio phrases
     260        Universal_Voice_Search_Settings_Page::uvs_inject_short_audio_phrases(empty(self::$uvs_selected_language) ? 'en-US' : self::$uvs_selected_language);
     261    }
     262
     263    /**
     264     * Static method to get data related to file
     265     *
     266     * @param $intent - string : 'url' or 'timestamp'
     267     * @param $partial_file_path - string : Path of file (Partial and mostly relative path)
     268     * @param $file_extension - string : 'js' or 'css'
     269     *
     270     * $returns $uvs_file_data - string : Time as a Unix timestamp or absolute url to the file
     271     */
     272    public static function uvs_get_file_meta_data($intent = "", $partial_file_path = "", $file_extension = "")
     273    {
     274        $uvs_file_data = "";
     275
     276        try {
     277            if (empty($file_extension) || empty($partial_file_path) || empty($intent)) throw new Exception("VDN: Error while getting file data.", 1);
     278
     279            $intent = strtolower(trim($intent));
     280            $file_ext = '.' . str_replace(".", "", trim($file_extension));
     281            $partial_file_path = trim($partial_file_path);
     282
     283            if ($intent == 'timestamp') {
     284                if (!empty(self::$uvs_settings_updated_ts)) {
     285                    $uvs_file_data = self::$uvs_settings_updated_ts;
     286                } else {
     287                    $uvs_file_data = filemtime(UVS_PLUGIN['ABS_PATH'] . $partial_file_path . self::$uvs_file_type . $file_ext);
     288                }
     289            } else if ($intent == 'url') {
     290                $uvs_file_data = UVS_PLUGIN['ABS_URL'] . $partial_file_path . self::$uvs_file_type . $file_ext;
     291            }
     292        } catch (\Exception $ex) {
     293            $uvs_file_data = "";
     294        }
     295
     296        return $uvs_file_data;
    210297    }
    211298
     
    214301     */
    215302    public function enqueue_admin_scripts()
    216     {
     303    {   
     304        // Enqueue CSS: uvs-settings.css
     305        wp_enqueue_style(
     306            'uvs_settings_css',
     307            self::uvs_get_file_meta_data('url', 'css/settings/uvs-settings', 'css'),
     308            array(),
     309            self::uvs_get_file_meta_data('timestamp', 'css/settings/uvs-settings', 'css'),
     310            'screen'
     311        );
     312       
    217313        // Enqueue JS: uvs-settings.js
    218314        wp_enqueue_script(
    219315            'uvs-settings',
    220             $this->get_url() . 'js/settings/uvs-settings'.self::$uvs_file_type.'.js',
     316            self::uvs_get_file_meta_data('url', 'js/settings/uvs-settings', 'js'),
    221317            array(),
    222             filemtime(self::$plugin_directory_path.'js/settings/uvs-settings'.self::$uvs_file_type.'.js'),
     318            self::uvs_get_file_meta_data('timestamp', 'js/settings/uvs-settings', 'js'),
    223319            true
    224320        );
    225321
    226         // Enqueue CSS: uvs-settings.css
     322    }
     323
     324    /**
     325     * Method to enqueue JS scripts and CSS for loading at Front end
     326     */
     327    public function enqueue_frontend_scripts()
     328    {
     329        //################################################################################
     330        //
     331        // Enqueue 'universal-voice-search' CSS file to load at front end
     332        //
     333        //################################################################################
    227334        wp_enqueue_style(
    228             'uvs_settings_css',
    229             $this->get_url() . '/css/settings/uvs-settings'.self::$uvs_file_type.'.css',
     335            'universal-voice-search',
     336            self::uvs_get_file_meta_data('url', 'css/universal-voice-search', 'css'),
    230337            array(),
    231             filemtime(self::$plugin_directory_path.'css/settings/uvs-settings'.self::$uvs_file_type.'.css'),
     338            self::uvs_get_file_meta_data('timestamp', 'css/universal-voice-search', 'css'),
    232339            'screen'
    233340        );
    234     }
    235 
    236     /**
    237      * Method to enqueue JS scripts and CSS for loading at Front end
    238      */
    239     public function enqueue_frontend_scripts()
    240     {
    241         // Enqueue JS: uvs.text-library.js
     341
     342        //################################################################################
     343        //
     344        // Enqueue 'uvs.text-library' javasctipt file to load at front end
     345        //
     346        //################################################################################       
    242347        wp_enqueue_script(
    243348            'uvs.text-library',
    244             $this->get_url() . 'js/uvs.text-library'.self::$uvs_file_type.'.js',
     349            self::uvs_get_file_meta_data('url', 'js/uvs.text-library', 'js'),
    245350            array(),
    246             filemtime(self::$plugin_directory_path.'js/uvs.text-library'.self::$uvs_file_type.'.js'),
     351            self::uvs_get_file_meta_data('timestamp', 'js/uvs.text-library', 'js'),
    247352            true
    248353        );
    249354
    250         // Make selected language available to 'uvs.text-library.js'
     355        //##################################################################################################################
     356        // Determine STT language context for plugin
     357        //##################################################################################################################
     358        $uvs_stt_language_context = array(
     359            'isChrome' => self::$is_chrome === true ? 'Y' : 'N',
     360            'ibm' => array(
     361                'stt' => 'N',
     362                'endPoint' => null,
     363                'token' => null,
     364                'model' => null,
     365                'qs' => array('token' => null, 'model' => null)
     366            ),
     367            'gcp' => array(
     368                'stt' => 'N',
     369                'langCode' => null,
     370                'endPoint' => null,
     371                'key' => null,
     372                'qs' => array('key' => null)
     373            )
     374        );
     375
     376        $uvs_gcp_supported = UvsLanguage::gcp_supported(self::$uvs_selected_language);
     377        $uvs_ibm_supported = UvsLanguage::ibm_supported(self::$uvs_selected_language);
     378        $uvs_lang_not_supported_by_vendors = false;
     379
     380        if (self::$is_chrome === true) {
     381            if ($uvs_gcp_supported === true) {
     382                $uvs_stt_language_context['gcp']['stt'] = 'Y';
     383            } else if ($uvs_ibm_supported === true) {
     384                $uvs_stt_language_context['ibm']['stt'] = 'Y';
     385            } else {
     386                $uvs_stt_language_context['gcp']['stt'] = 'Y';
     387                $uvs_lang_not_supported_by_vendors = true;
     388            }
     389        } else {
     390            if ($uvs_ibm_supported === true) {
     391                $uvs_stt_language_context['ibm']['stt'] = 'Y';
     392            } else if ($uvs_gcp_supported === true) {
     393                $uvs_stt_language_context['gcp']['stt'] = 'Y';
     394            } else {
     395                $uvs_stt_language_context['ibm']['stt'] = 'Y';
     396                $uvs_lang_not_supported_by_vendors = true;
     397            }
     398        }
     399
     400        if ($uvs_lang_not_supported_by_vendors === true) {
     401            self::$uvs_selected_language = 'en-US';
     402            update_option(Universal_Voice_Search_Settings_Page::BASIC_CONFIG_OPTION_NAMES['selected_language'], self::$uvs_selected_language);
     403        }
     404
     405        if ($uvs_stt_language_context['ibm']['stt'] == 'Y') {
     406            $uvs_ibm_model = UvsLanguage::$ibm_language_set[self::$uvs_selected_language][UvsLanguage::LANG_CODE];
     407            $uvs_ibm_token = self::$uvs_voice_services_access_keys['value']['ibm_stt_token'];
     408
     409            $uvs_stt_language_context['ibm']['endPoint'] = 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize';
     410            $uvs_stt_language_context['ibm']['token'] = $uvs_ibm_token;
     411            $uvs_stt_language_context['ibm']['model'] = $uvs_ibm_model;
     412            $uvs_stt_language_context['ibm']['qs']['token'] = '?access_token=';
     413            $uvs_stt_language_context['ibm']['qs']['model'] = '&model=';
     414        }
     415
     416        if ($uvs_stt_language_context['gcp']['stt'] == 'Y') {
     417            $uvs_gcp_lang_code = UvsLanguage::$gcp_language_set[self::$uvs_selected_language][UvsLanguage::LANG_CODE];
     418            $uvs_gcp_key = self::$uvs_voice_services_access_keys['value']['g_stt_key'];
     419           
     420            $uvs_stt_language_context['gcp']['endPoint'] = 'https://speech.googleapis.com/v1/speech:recognize';
     421            $uvs_stt_language_context['gcp']['langCode'] = $uvs_gcp_lang_code;
     422            $uvs_stt_language_context['gcp']['key'] = $uvs_gcp_key;
     423            $uvs_stt_language_context['gcp']['qs']['key'] = '?key=';
     424        }
     425
    251426        wp_localize_script( 'uvs.text-library', 'uvsSelectedLanguage', self::$uvs_selected_language);
    252 
    253         // Enqueue JS: uvs.speech-handler.js
    254         wp_enqueue_script(
    255             'uvs.speech-handler',
    256             $this->get_url() . 'js/uvs.speech-handler'.self::$uvs_file_type.'.js',
    257             array(),
    258             filemtime(self::$plugin_directory_path.'js/uvs.speech-handler'.self::$uvs_file_type.'.js'),
    259             true
    260         );
    261 
    262         // Make images path available to 'uvs.speech-handler.js'
    263         wp_localize_script( 'uvs.speech-handler', 'uvsImagesPath', self::$uvs_url . 'images/');
    264 
    265         // Make ajax obj available to 'uvs.speech-handler.js'
     427        wp_localize_script( 'uvs.text-library', '_uvsSttLanguageContext', $uvs_stt_language_context);
     428        wp_localize_script( 'uvs.text-library', 'uvsIsttT', self::$uvs_voice_services_access_keys['value']['ibm_stt_token']);
     429        wp_localize_script( 'uvs.text-library', '_uvsTextPhrases', UvsLanguage::$textual_phrases[self::$uvs_selected_language]);
     430
     431        wp_localize_script( 'uvs.text-library', 'uvsImagesPath', self::$uvs_url . 'images/');
     432        wp_localize_script( 'uvs.text-library', '_uvsPath', UVS_PLUGIN['ABS_URL']);
     433
    266434        $count_nonce = wp_create_nonce( 'service_call_count' );
    267 
    268         wp_localize_script( 'uvs.speech-handler', 'uvsAjaxObj', array(
    269             'ajax_url' => admin_url( 'admin-ajax.php' ),
    270             'nonce'    => $count_nonce,
     435        $uvs_keys_refresh_nonce = wp_create_nonce( 'keys_refresh' );
     436
     437        wp_localize_script( 'uvs.text-library', 'uvsAjaxObj', array(
     438            'ajax_url'   => admin_url( 'admin-ajax.php' ),
     439            'nonce'      => $count_nonce,
     440            'keys_nonce' => $uvs_keys_refresh_nonce
    271441        ));
    272442
    273         // Make host name available to 'uvs.speech-handler.js'
    274443        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
    275444        $domainName = $_SERVER['SERVER_NAME'];
    276         wp_localize_script( 'uvs.speech-handler', 'uvsCurrentHostName', $protocol.$domainName);
    277 
    278         // Enqueue JS: uvs.audio-input-handler.js
    279         wp_enqueue_script(
    280             'uvs.audio-input-handler',
    281             $this->get_url() . 'js/uvs.audio-input-handler'.self::$uvs_file_type.'.js',
    282             array(),
    283             filemtime(self::$plugin_directory_path.'js/uvs.audio-input-handler'.self::$uvs_file_type.'.js'),
    284             true
    285         );
    286 
    287         // Making API meta data broadcasted in JS file(s)
    288         self::broadcast_api_meta_data();
    289 
    290         // Enqueue JS: uvs.audio-recorder.js
    291         wp_enqueue_script(
    292             'uvs.audio-recorder',
    293             $this->get_url() . 'js/recorderjs/uvs.audio-recorder'.self::$uvs_file_type.'.js',
    294             array(),
    295             filemtime(self::$plugin_directory_path.'js/recorderjs/uvs.audio-recorder'.self::$uvs_file_type.'.js'),
    296             true
    297         );
    298 
    299         // Make worker path available to 'uvs.audio-recorder.js'
    300         wp_localize_script( 'uvs.audio-recorder', 'uvsWorkerPath', $this->get_url(). 'js/recorderjs/uvs.audio-recorder-worker'.self::$uvs_file_type.'.js');
    301 
    302         // Enqueue JS: universal-voice-search.js
    303         wp_enqueue_script(
    304             'universal-voice-search',
    305             $this->get_url() . 'js/universal-voice-search'.self::$uvs_file_type.'.js',
    306             array(),
    307             filemtime(self::$plugin_directory_path.'js/universal-voice-search'.self::$uvs_file_type.'.js'),
    308             true
    309         );
    310 
    311         // Make floating mic status available to 'universal-voice-search.js'
     445        wp_localize_script( 'uvs.text-library', 'uvsCurrentHostName', $protocol.$domainName);
     446
     447        wp_localize_script( 'uvs.text-library', 'uvsWorkerPath', $this->get_url(). 'js/recorderjs/uvs.audio-recorder-worker'.self::$uvs_file_type.'.js');
     448
    312449        $uvs_floating_mic = get_option(Universal_Voice_Search_Settings_Page::BASIC_CONFIG_OPTION_NAMES['floating_mic'], null);
    313450        $uvs_floating_mic = self::uvs_sanitize_variable_for_local_script($uvs_floating_mic);
    314         wp_localize_script( 'universal-voice-search', 'uvsFloatingMic', $uvs_floating_mic);
    315 
    316         // Make selected Mic Position available to 'voice-forms.js'
    317         wp_localize_script( 'universal-voice-search', 'uvsSelectedMicPosition', self::$uvs_floating_mic_position);
    318 
    319         // Make button message and talk message available to 'universal-voice-search.js'
    320         wp_localize_script( 'universal-voice-search', 'universal_voice_search', array(
     451        wp_localize_script( 'uvs.text-library', 'uvsFloatingMic', $uvs_floating_mic);
     452        wp_localize_script( 'uvs.text-library', 'uvsSelectedMicPosition', self::$uvs_floating_mic_position);
     453
     454        wp_localize_script( 'uvs.text-library', 'universal_voice_search', array(
    321455            'button_message' => __( 'Speech Input', 'universal-voice-search' ),
    322456            'talk_message'   => __( 'Start Talking…', 'universal-voice-search' ),
    323457        ));
    324458
    325         // Enqueue CSS: universal-voice-search.css
    326         wp_enqueue_style(
    327             'universal-voice-search',
    328             $this->get_url() . 'css/universal-voice-search'.self::$uvs_file_type.'.css',
    329             array(),
    330             filemtime(self::$plugin_directory_path.'css/universal-voice-search'.self::$uvs_file_type.'.css'),
    331             'screen'
    332         );
    333 
    334         // Get auto timeout value from Database
    335459        $uvs_mic_listening_timeout = get_option(Universal_Voice_Search_Settings_Page::BASIC_CONFIG_OPTION_NAMES['mic_listening_timeout'], null);
    336460        $uvs_mic_listening_timeout = self::uvs_sanitize_variable_for_local_script($uvs_mic_listening_timeout);
     
    341465        }
    342466
    343         // Make mic auto timeout value and images path available to 'universal-voice-search.js'
    344         wp_localize_script( 'universal-voice-search', 'uvsMicListenTimeoutDuration', $uvs_mic_listening_timeout);
    345         wp_localize_script( 'universal-voice-search', 'uvsImagesPath', self::$uvs_url . 'images/');
    346 
    347         // Make 'X API Key' available to 'uvs.speech-handler.js', 'uvs.audio-input-handler.js' and 'universal-voice-search.js'
    348         wp_localize_script( 'uvs.speech-handler', 'uvsXApiKey', self::$uvs_api_access_key);
    349         wp_localize_script( 'uvs.audio-input-handler', 'uvsXApiKey', self::$uvs_api_access_key);
    350         wp_localize_script( 'universal-voice-search', 'uvsXApiKey', self::$uvs_api_access_key);
     467        wp_localize_script( 'uvs.text-library', 'uvsMicListenTimeoutDuration', $uvs_mic_listening_timeout);
     468        wp_localize_script( 'uvs.text-library', 'uvsXApiKey', self::$uvs_api_access_key);
    351469
    352470        $uvs_current_value = get_option('uvs_current_value', "0");
     
    355473        $uvs_last_value_updated_at = self::uvs_sanitize_variable_for_local_script($uvs_last_value_updated_at);
    356474
    357         // Make 'Service logs' available to 'uvs.speech-handler.js'
    358475        $uvs_service_logs = array(
    359476            'updatedAt' => $uvs_last_value_updated_at,
     
    362479        );
    363480
    364         wp_localize_script( 'uvs.speech-handler', 'uvsServiceLogs', $uvs_service_logs);
     481        wp_localize_script( 'uvs.text-library', 'uvsServiceLogs', $uvs_service_logs);
     482
     483        //################################################################################
     484        //
     485        // Enqueue 'uvs.speech-handler' javasctipt file to load at front end
     486        //
     487        //################################################################################
     488        wp_enqueue_script(
     489            'uvs.speech-handler',
     490            self::uvs_get_file_meta_data('url', 'js/uvs.speech-handler', 'js'),
     491            array(),
     492            self::uvs_get_file_meta_data('timestamp', 'js/uvs.speech-handler', 'js'),
     493            true
     494        );
     495
     496        //################################################################################
     497        //
     498        // Enqueue 'uvs.audio-input-handler' javasctipt file to load at front end
     499        //
     500        //################################################################################
     501        wp_enqueue_script(
     502            'uvs.audio-input-handler',
     503            self::uvs_get_file_meta_data('url', 'js/uvs.audio-input-handler', 'js'),
     504            array(),
     505            self::uvs_get_file_meta_data('timestamp', 'js/uvs.audio-input-handler', 'js'),
     506            true
     507        );
     508
     509        //################################################################################
     510        //
     511        // Enqueue 'vdn.audio-recorder' javasctipt file to load at front end
     512        //
     513        //################################################################################
     514        wp_enqueue_script(
     515            'uvs.audio-recorder',
     516            self::uvs_get_file_meta_data('url', 'js/recorderjs/uvs.audio-recorder', 'js'),
     517            array(),
     518            self::uvs_get_file_meta_data('timestamp', 'js/recorderjs/uvs.audio-recorder', 'js'),
     519            true
     520        );
     521
     522        //################################################################################
     523        //
     524        // Enqueue 'universal-voice-search' javasctipt file to load at front end
     525        //
     526        //################################################################################
     527        wp_enqueue_script(
     528            'universal-voice-search',
     529            self::uvs_get_file_meta_data('url', 'js/universal-voice-search', 'js'),
     530            array(),
     531            self::uvs_get_file_meta_data('timestamp', 'js/universal-voice-search', 'js'),
     532            true
     533        );
    365534    }
    366535
     
    578747                // Detect site language and set the plugin language
    579748                $uvs_site_language_code = get_locale();
    580 
    581                 if (!empty($uvs_site_language_code) && array_key_exists($uvs_site_language_code, self::$uvs_auto_detect_lang_map)) {
    582                     update_option(
    583                         Universal_Voice_Search_Settings_Page::BASIC_CONFIG_OPTION_NAMES['selected_language'],
    584                         self::$uvs_auto_detect_lang_map[$uvs_site_language_code]
    585                     );
     749                $uvs_site_language_code = str_replace('_', '-', $uvs_site_language_code);
     750
     751                if (!empty($uvs_site_language_code) && array_key_exists($uvs_site_language_code, UvsLanguage::get_all_languages())) {
     752                    update_option(Universal_Voice_Search_Settings_Page::BASIC_CONFIG_OPTION_NAMES['selected_language'],$uvs_site_language_code);
    586753                }
    587754
     
    623790        }
    624791    }
     792
     793    /**
     794     * Method as HTTP request handler to obtain refreshed voice services token and keys
     795     *
     796     * @return JSON $uvs_refreshed_keys Containing IBM Watson STT token for now.
     797     *
     798     */
     799    public function uvs_refresh_access_keys()
     800    {
     801        check_ajax_referer('keys_refresh');
     802
     803        self::uvs_synch_voice_access_keys(true);
     804
     805        $uvs_refreshed_keys = array(
     806            'token' => self::$uvs_voice_services_access_keys['value']['ibm_stt_token'],
     807            'gStt' => self::$uvs_voice_services_access_keys['value']['g_stt_key']
     808        );
     809
     810        wp_send_json($uvs_refreshed_keys);
     811    }
     812
     813    /**
     814     * Static method to obtain access keys for Google STT & TTS and IBN Watson token
     815     *
     816     * @param boolean $forced_synch To by-pass validation to obtain token and keys from API
     817     *
     818     */
     819    public static function uvs_synch_voice_access_keys($forced_synch = false)
     820    {
     821        try {
     822            $uvs_do_synch = false;
     823
     824            $uvs_ibm_stt_token = self::$uvs_voice_services_access_keys['value']['ibm_stt_token'];
     825            $uvs_g_stt_key     = self::$uvs_voice_services_access_keys['value']['g_stt_key'];
     826            $uvs_g_tts_key     = self::$uvs_voice_services_access_keys['value']['g_tts_key'];
     827            $uvs_synched_at    = self::$uvs_voice_services_access_keys['value']['synched_at'];
     828
     829            if (
     830                empty($uvs_ibm_stt_token) ||
     831                empty($uvs_g_stt_key) ||
     832                empty($uvs_g_tts_key) ||
     833                empty($uvs_synched_at) ||
     834                $forced_synch === true
     835            ) {
     836                $uvs_do_synch = true;
     837            }
     838
     839            if ( !!$uvs_synched_at && $uvs_do_synch === false ) {
     840                $uvs_synched_at_threshold = $uvs_synched_at + (60 * 60 * 6);
     841                $uvs_current_time = time();
     842
     843                if ($uvs_current_time > $uvs_synched_at_threshold) {
     844                    $uvs_do_synch = true;
     845                }
     846            }
     847
     848            if ($uvs_do_synch === false ) return;
     849
     850            $uvs_args = array(
     851                'timeout' => '90',
     852                'headers' => array(
     853                    'Content-Type' => 'application/json',
     854                    'x-api-key'    => self::$uvs_api_access_key
     855                )
     856            );
     857
     858            $uvs_response = wp_remote_get(self::$uvs_voice_services_access_keys['api_url'], $uvs_args);
     859
     860            // Check the response code
     861            $response_code = wp_remote_retrieve_response_code( $uvs_response );
     862
     863            if ($response_code == 200) {
     864                $response_body = wp_remote_retrieve_body($uvs_response);
     865                $uvs_result = @json_decode($response_body, true);
     866
     867                $uvs_ibm_stt_token = array_key_exists('token',$uvs_result) ? $uvs_result['token'] : null;
     868                $uvs_google_stt_key = array_key_exists('gSTT',$uvs_result) ? $uvs_result['gSTT'] : null;
     869                $uvs_google_tts_key = array_key_exists('TTS',$uvs_result) ? $uvs_result['TTS'] : null;
     870
     871                /**
     872                 * Deliberate separation of if blocks, do not merge them for optimization as
     873                 * it would ruin the flexibility and independency of response values (none of them depend on each other anyway).
     874                 *
     875                 */
     876                $uvs_synchable_local_keys = 0;
     877
     878                if (!!$uvs_ibm_stt_token) {
     879                    self::$uvs_voice_services_access_keys['value']['ibm_stt_token'] = $uvs_ibm_stt_token;
     880                    $uvs_synchable_local_keys += 1;
     881                }
     882
     883                if (!!$uvs_google_stt_key) {
     884                    self::$uvs_voice_services_access_keys['value']['g_stt_key'] = $uvs_google_stt_key;
     885                    $uvs_synchable_local_keys += 1;
     886                }
     887
     888                if (!!$uvs_google_tts_key) {
     889                    self::$uvs_voice_services_access_keys['value']['g_tts_key'] = $uvs_google_tts_key;
     890                    $uvs_synchable_local_keys += 1;
     891                }
     892
     893                if ($uvs_synchable_local_keys > 0) {
     894                    self::$uvs_voice_services_access_keys['value']['synched_at'] = time();
     895                    update_option(self::$uvs_voice_services_access_keys['db_col_name'], self::$uvs_voice_services_access_keys['value']); 
     896                }
     897            }
     898        } catch(\Exception $ex) {
     899            // Nullify keys
     900            self::$uvs_voice_services_access_keys['value']['ibm_stt_token'] = null;
     901            self::$uvs_voice_services_access_keys['value']['g_stt_key'] = null;
     902            self::$uvs_voice_services_access_keys['value']['g_tts_key'] = null;
     903            self::$uvs_voice_services_access_keys['value']['synched_at'] = null;
     904        }
     905    }
     906
    625907}
    626908
  • universal-voice-search/trunk/classes/settings-page.php

    r2207334 r2289691  
    1515    private $uvs_license_key           = '';
    1616    private $uvs_mic_listening_timeout = null;
    17     private $uvs_selected_language     = 'English';
     17    private $uvs_selected_language     = 'en-US';
    1818    private $uvs_floating_mic          = null;
    1919    private $uvs_floating_mic_position = 'Middle Right';
     20    private $uvs_all_languages = array();
    2021
    2122    /**
     
    2627        add_action( 'admin_menu', array( $this, 'uvs_add_plugin_page' ) );
    2728        add_action( 'admin_init', array( $this, 'uvs_page_init' ) );
     29
     30        //### THIS FILTERS HOOK INTO A PROCESS BEFORE OPTION GETTING STORED TO DB
     31        // Register filters for basic config options
     32        foreach (self::BASIC_CONFIG_OPTION_NAMES as $key => $option) {
     33            add_filter( 'pre_update_option_'.$option, array($this, 'uvs_pre_update_basic_config'), 10, 3 );
     34        }
    2835
    2936        // Register callback to hook into post create and update (License key) option action
     
    3340
    3441    /**
     42     * Static method to get timestamp from and set timestamp to DB (Timestamp of setting option update)
     43     *
     44     * @param $action - string : 'get' or 'set'
     45     *
     46     * $returns $uvs_modified_timestamp - string : Time as a Unix timestamp
     47     */
     48    public static function uvs_settings_modified_timestamp($action = null)
     49    {
     50        $uvs_modified_timestamp = null;
     51
     52        try {
     53            if (empty($action)) return $uvs_modified_timestamp;
     54
     55            if ($action == 'get') {
     56                $uvs_modified_timestamp = get_option('uvs_settings_updated_timestamp', null);
     57            } else if ($action == 'set') {
     58                $vdn_timestamp = time();
     59                update_option('uvs_settings_updated_timestamp', $vdn_timestamp);
     60                $uvs_modified_timestamp = $vdn_timestamp;
     61            }
     62        } catch (\Exception $ex) {
     63            $uvs_modified_timestamp = null;
     64        }
     65
     66        return $uvs_modified_timestamp;
     67    }
     68
     69    /**
     70     * Method as callback to handle basic config options data before storing to DB
     71     *
     72     * @param $old_value - string : Existing Option value from database
     73     * @param $new_value - string : New Option value to be stored in database
     74     * @param $option_name - string : Name of the option
     75     */
     76    public function uvs_pre_update_basic_config($new_value, $old_value, $option_name) {
     77        /**
     78         * Comparing two string values to check if option data modified.
     79         *
     80         * Preserve settings updated timestamp
     81         */
     82        if ($old_value != $new_value) {
     83            $uvs_setting_update_ts = self::uvs_settings_modified_timestamp('set');
     84            unset($uvs_setting_update_ts);
     85
     86            if ($option_name == self::BASIC_CONFIG_OPTION_NAMES['selected_language']) {
     87                self::uvs_inject_short_audio_phrases(trim($new_value));
     88            }
     89        }
     90
     91        return $new_value;
     92    }
     93
     94    /**
     95     * Static method to fetch short audio phrases from 'speak2web.com' and create local audio file for it.
     96     *
     97     * @param String  $uvs_lang_code  Language code (eg: en-US)
     98     *
     99     */
     100    public static function uvs_inject_short_audio_phrases($uvs_lang_code)
     101    {
     102        $uvs_lang_file_path = $uvs_lang_code.'/'.$uvs_lang_code;
     103        $uvs_general = UVS_PLUGIN['ABS_PATH'].UVS_PLUGIN['SHORT_PHRASES']['root'].UVS_PLUGIN['SHORT_PHRASES']['general'];
     104        $uvs_random = UVS_PLUGIN['ABS_PATH'].UVS_PLUGIN['SHORT_PHRASES']['root'].UVS_PLUGIN['SHORT_PHRASES']['random'];
     105
     106        $uvs_general_lang_mismatch = false;
     107
     108        if (file_exists($uvs_general.$uvs_lang_code) && file_exists($uvs_general.$uvs_lang_code.'/lang_mismatch.txt')) {
     109            unlink($uvs_general.$uvs_lang_code.'/lang_mismatch.txt');
     110            $uvs_general_lang_mismatch = true;
     111        }
     112
     113        // Check folder exist with language name in 'general' folder
     114        if (!file_exists($uvs_general.$uvs_lang_code) || $uvs_general_lang_mismatch === true) {
     115            // Create 'general' folder
     116            if (!file_exists($uvs_general.$uvs_lang_code)) {
     117                $oldmask = umask(0);
     118                mkdir($uvs_general.$uvs_lang_code, 0777);
     119                umask($oldmask);
     120            }
     121
     122            $uvs_general_file_names = array(
     123                '_basic',
     124                '_mic_connect',
     125                '_not_audible',
     126                '_unavailable'
     127            );
     128
     129            $uvs_lang_mismatch = false;
     130
     131            for ($i = 0; $i < count($uvs_general_file_names); $i++) {
     132                $uvs_file_name = $uvs_general_file_names[$i];
     133                $uvs_file_data = file_get_contents('https://speak2web.com/'.UVS_PLUGIN['SHORT_PHRASES']['root'].UVS_PLUGIN['SHORT_PHRASES']['general'].$uvs_lang_file_path.$uvs_file_name.'.mp3');
     134
     135                if ($uvs_file_data !== false) {
     136                    if (file_exists($uvs_general.$uvs_lang_file_path.$uvs_file_name.'.mp3')) {
     137                        unlink($uvs_general.$uvs_lang_file_path.$uvs_file_name.'.mp3');
     138                    }
     139
     140                    $uvs_local_file = fopen($uvs_general.$uvs_lang_file_path.$uvs_file_name.'.mp3', "w");
     141
     142                    if ($uvs_local_file) {
     143                        // Write contents to the file
     144                        fwrite($uvs_local_file, $uvs_file_data);
     145
     146                        // Close the file
     147                        fclose($uvs_local_file);
     148                    }
     149                } else {
     150                    $uvs_src_file = $uvs_general.'en-US/en-US'.$uvs_file_name.'.mp3';
     151                    $uvs_dest_file = $uvs_general.$uvs_lang_file_path.$uvs_file_name.'.mp3';
     152                    copy($uvs_src_file, $uvs_dest_file);
     153
     154                    if ($uvs_lang_mismatch !== true) {
     155                        $uvs_lang_mismatch = true;
     156                    }
     157                }
     158            }
     159
     160            if ($uvs_lang_mismatch === true) {
     161                $uvs_lang_mismatch = false;
     162                touch($uvs_general.$uvs_lang_code.'/lang_mismatch.txt');
     163            }
     164        }
     165
     166        $uvs_random_lang_mismatch = false;
     167
     168        if (file_exists($uvs_random.$uvs_lang_code) && file_exists($uvs_random.$uvs_lang_code.'/lang_mismatch.txt')) {
     169            unlink($uvs_random.$uvs_lang_code.'/lang_mismatch.txt');
     170            $uvs_random_lang_mismatch = true;
     171        }
     172
     173        // Check folder exist with language name in 'random' folder
     174        if (!file_exists($uvs_random.$uvs_lang_code) || $uvs_random_lang_mismatch === true) {
     175            // Create 'random' folder
     176            if (!file_exists($uvs_random.$uvs_lang_code)) {
     177                $oldmask = umask(0);
     178                mkdir($uvs_random.$uvs_lang_code, 0777);
     179                umask($oldmask);
     180            }
     181
     182            $uvs_lang_mismatch = false;
     183
     184            for ($j = 0; $j < 10; $j++) {
     185                $uvs_file_name = '_'.$j;
     186                $uvs_file_data = file_get_contents('https://speak2web.com/'.UVS_PLUGIN['SHORT_PHRASES']['root'].UVS_PLUGIN['SHORT_PHRASES']['random'].$uvs_lang_file_path.$uvs_file_name.'.mp3');
     187
     188                if ($uvs_file_data !== false) {
     189                    if (file_exists($uvs_random.$uvs_lang_file_path.$uvs_file_name.'.mp3')) {
     190                        unlink($uvs_random.$uvs_lang_file_path.$uvs_file_name.'.mp3');
     191                    }
     192
     193                    $uvs_local_file = fopen($uvs_random.$uvs_lang_file_path.$uvs_file_name.'.mp3', "w");
     194
     195                    if ($uvs_local_file) {
     196                        // Write contents to the file
     197                        fwrite($uvs_local_file, $uvs_file_data);
     198
     199                        // Close the file
     200                        fclose($uvs_local_file);
     201                    }
     202                } else {
     203                    $uvs_src_file = $uvs_random.'en-US/en-US'.$uvs_file_name.'.mp3';
     204                    $uvs_dest_file = $uvs_random.$uvs_lang_file_path.$uvs_file_name.'.mp3';
     205                    copy($uvs_src_file, $uvs_dest_file);
     206
     207                    if ($uvs_lang_mismatch !== true) {
     208                        $uvs_lang_mismatch = true;
     209                    }
     210                }
     211            }
     212
     213            if ($uvs_lang_mismatch === true) {
     214                $uvs_lang_mismatch = false;
     215                touch($uvs_random.$uvs_lang_code.'/lang_mismatch.txt');
     216            }
     217        }
     218    }
     219
     220    /**
    35221     * Method as callback post to license key option creation in DB
    36222     *
     
    38224     * @param $option_value - string : Option value
    39225     */
    40     public function uvs_post_adding_license_key( $option_name, $option_value)
     226    public function uvs_post_adding_license_key($option_name, $option_value)
    41227    {
    42228        try {
    43229            Universal_Voice_Search_Plugin::uvs_get_api_key_from_license_key(trim($option_value), true);
     230           
     231            $uvs_setting_update_ts = self::uvs_settings_modified_timestamp('set');
     232            unset($uvs_setting_update_ts);
    44233        } catch (\Exception $ex) {
    45234            // Do nothing for now
     
    60249            if ($old_value != trim($option_value)) {
    61250                Universal_Voice_Search_Plugin::uvs_get_api_key_from_license_key(trim($option_value), true);
     251               
     252                $uvs_setting_update_ts = self::uvs_settings_modified_timestamp('set');
     253                unset($uvs_setting_update_ts);
    62254            }
    63255        } catch (\Exception $ex) {
     
    107299        // For language
    108300        $this->uvs_selected_language = strip_tags(stripslashes(get_option(
    109             self::BASIC_CONFIG_OPTION_NAMES['selected_language'], 'English')));
     301            self::BASIC_CONFIG_OPTION_NAMES['selected_language'], 'en-US')));
    110302
    111303        // For floating mic
     
    115307        $this->uvs_floating_mic_position = strip_tags(stripslashes(get_option(
    116308            self::BASIC_CONFIG_OPTION_NAMES['floating_mic_position'], 'Middle Right')));
     309
     310        $this->uvs_all_languages = UvsLanguage::get_all_languages();
     311        $this->uvs_all_languages = isset($this->uvs_all_languages) ? $this->uvs_all_languages : array('en-US' => array(UvsLanguage::NAME => 'English (United States)', UvsLanguage::LANG_CODE => 'en-US'));
    117312?>
    118313        <div class="wrap">
     
    151346                                <div><?php echo UVS_LANGUAGE_LIBRARY['basicConfig']['selectLanguage']; ?>
    152347                                    <select  id="uvsLanguage" class="uvs-language" name="<?php echo self:: BASIC_CONFIG_OPTION_NAMES['selected_language']; ?>">
    153                                         <option value="English" <?php selected('English', $this->uvs_selected_language);?>>English(US)</option>
    154                                         <option value="British English" <?php selected('British English', $this->uvs_selected_language);?> >British English</option>
    155                                         <option value="German"  <?php selected('German', $this->uvs_selected_language);?> >German</option>
    156                                         <option value="Portuguese"  <?php selected('Portuguese', $this->uvs_selected_language);?> >Portuguese</option>
    157                                         <option value="Chinese"  <?php selected('Chinese', $this->uvs_selected_language);?> >Chinese</option>
    158                                         <option value="French"  <?php selected('French', $this->uvs_selected_language);?> >French</option>
    159                                         <option value="Japanese"  <?php selected('Japanese', $this->uvs_selected_language);?> >Japanese</option>
    160                                         <option value="Korean"  <?php selected('Korean', $this->uvs_selected_language);?> >Korean</option>
    161                                         <option value="Spanish"  <?php selected('Spanish', $this->uvs_selected_language);?> >Spanish</option>
     348                                        <?php
     349                                            foreach($this->uvs_all_languages as $langCode => $lang) {
     350                                        ?>
     351                                            <option
     352                                                <?php selected($langCode, $this->uvs_selected_language);?>
     353                                                value=<?php echo $langCode;?>><?php echo $lang[UvsLanguage::NAME];?>
     354                                            </option>
     355                                        <?php
     356                                            }
     357                                        ?>
    162358                                    </select>
    163359                                </div>                           
  • universal-voice-search/trunk/composer.json

    r2225505 r2289691  
    22  "name": "speak2web/universal-voice-search",
    33  "description": "Allows user to fill up text fields via voice.",
    4   "version": "1.1.4",
     4  "version": "2.0.0",
    55  "type": "wordpress-plugin",
    66  "license": "GPL-2.0+",
  • universal-voice-search/trunk/js/recorderjs/uvs.audio-recorder-worker.min.js

    r2176461 r2289691  
    1 var recLength=0,recBuffersL=[],recBuffersR=[],sampleRate;this.onmessage=function(e){switch(e.data.command){case 'init':init(e.data.config);break;case 'record':record(e.data.buffer);break;case 'exportWAV':exportWAV(e.data.type);break;case 'exportMonoWAV':exportMonoWAV(e.data.type);break;case 'getBuffers':getBuffers();break;case 'clear':clear();break}};function init(config){sampleRate=config.sampleRate}
    2 function record(inputBuffer){recBuffersL.push(inputBuffer[0]);recBuffersR.push(inputBuffer[1]);recLength+=inputBuffer[0].length}
    3 function exportWAV(type){var bufferL=mergeBuffers(recBuffersL,recLength);var bufferR=mergeBuffers(recBuffersR,recLength);var interleaved=interleave(bufferL,bufferR);var dataview=encodeWAV(interleaved);var audioBlob=new Blob([dataview],{type:type});this.postMessage(audioBlob)}
    4 function exportMonoWAV(type){var bufferL=mergeBuffers(recBuffersL,recLength);var dataview=encodeWAV(bufferL,!0);var audioBlob=new Blob([dataview],{type:type});this.postMessage(audioBlob)}
    5 function getBuffers(){var buffers=[];buffers.push(mergeBuffers(recBuffersL,recLength));buffers.push(mergeBuffers(recBuffersR,recLength));this.postMessage(buffers)}
    6 function clear(){recLength=0;recBuffersL=[];recBuffersR=[]}
    7 function mergeBuffers(recBuffers,recLength){var result=new Float32Array(recLength);var offset=0;for(var i=0;i<recBuffers.length;i++){result.set(recBuffers[i],offset);offset+=recBuffers[i].length}
    8 return result}
    9 function interleave(inputL,inputR){var length=inputL.length+inputR.length;var result=new Float32Array(length);var index=0,inputIndex=0;while(index<length){result[index++]=inputL[inputIndex];result[index++]=inputR[inputIndex];inputIndex++}
    10 return result}
    11 function floatTo16BitPCM(output,offset,input){for(var i=0;i<input.length;i++,offset+=2){var s=Math.max(-1,Math.min(1,input[i]));output.setInt16(offset,s<0?s*0x8000:s*0x7FFF,!0)}}
    12 function writeString(view,offset,string){for(var i=0;i<string.length;i++){view.setUint8(offset+i,string.charCodeAt(i))}}
    13 function encodeWAV(samples,mono){var buffer=new ArrayBuffer(44+samples.length*2);var view=new DataView(buffer);writeString(view,0,'RIFF');view.setUint32(4,32+samples.length*2,!0);writeString(view,8,'WAVE');writeString(view,12,'fmt ');view.setUint32(16,16,!0);view.setUint16(20,1,!0);view.setUint16(22,mono?1:2,!0);view.setUint32(24,sampleRate,!0);view.setUint32(28,sampleRate*4,!0);view.setUint16(32,4,!0);view.setUint16(34,16,!0);writeString(view,36,'data');view.setUint32(40,samples.length*2,!0);floatTo16BitPCM(view,44,samples);return view}
     1var sampleRate,recLength=0,recBuffersL=[],recBuffersR=[];function init(e){sampleRate=e.sampleRate}function record(e){recBuffersL.push(e[0]),recBuffersR.push(e[1]),recLength+=e[0].length}function exportWAV(e){var t=encodeWAV(interleave(mergeBuffers(recBuffersL,recLength),mergeBuffers(recBuffersR,recLength))),r=new Blob([t],{type:e});this.postMessage(r)}function exportMonoWAV(e){var t=encodeWAV(mergeBuffers(recBuffersL,recLength),!0),r=new Blob([t],{type:e});this.postMessage(r)}function getBuffers(){var e=[];e.push(mergeBuffers(recBuffersL,recLength)),e.push(mergeBuffers(recBuffersR,recLength)),this.postMessage(e)}function clear(){recLength=0,recBuffersL=[],recBuffersR=[]}function mergeBuffers(e,t){for(var r=new Float32Array(t),n=0,a=0;a<e.length;a++)r.set(e[a],n),n+=e[a].length;return r}function interleave(e,t){for(var r=e.length+t.length,n=new Float32Array(r),a=0,f=0;a<r;)n[a++]=e[f],n[a++]=t[f],f++;return n}function floatTo16BitPCM(e,t,r){for(var n=0;n<r.length;n++,t+=2){var a=Math.max(-1,Math.min(1,r[n]));e.setInt16(t,a<0?32768*a:32767*a,!0)}}function writeString(e,t,r){for(var n=0;n<r.length;n++)e.setUint8(t+n,r.charCodeAt(n))}function encodeWAV(e,t){var r=new ArrayBuffer(44+2*e.length),n=new DataView(r);return writeString(n,0,"RIFF"),n.setUint32(4,32+2*e.length,!0),writeString(n,8,"WAVE"),writeString(n,12,"fmt "),n.setUint32(16,16,!0),n.setUint16(20,1,!0),n.setUint16(22,t?1:2,!0),n.setUint32(24,sampleRate,!0),n.setUint32(28,4*sampleRate,!0),n.setUint16(32,4,!0),n.setUint16(34,16,!0),writeString(n,36,"data"),n.setUint32(40,2*e.length,!0),floatTo16BitPCM(n,44,e),n}this.onmessage=function(e){switch(e.data.command){case"init":init(e.data.config);break;case"record":record(e.data.buffer);break;case"exportWAV":exportWAV(e.data.type);break;case"exportMonoWAV":exportMonoWAV(e.data.type);break;case"getBuffers":getBuffers();break;case"clear":clear()}};
  • universal-voice-search/trunk/js/recorderjs/uvs.audio-recorder.js

    r2176461 r2289691  
    181181        }
    182182
     183        this.convertBlobToBase64 = function(blobObj) {
     184            return new Promise(function(resolve, reject){
     185                if (!(typeof blobObj != 'undefined' && !!blobObj && blobObj instanceof Blob)) {
     186                    reject(null);
     187                    return;
     188                }
     189
     190                let reader = new FileReader();
     191                reader.readAsDataURL(blobObj);
     192               
     193                reader.onload = function() {
     194                    let base64data = reader.result;
     195
     196                    if (typeof base64data != 'undefined' && !!base64data && base64data.indexOf(',') !== -1) {
     197                        resolve(base64data.split(',')[1]);
     198                    } else {
     199                        reject(null);
     200                    }
     201                }
     202
     203                reader.onerror = function(event) {
     204                    reader.abort();
     205                };
     206
     207                reader.onabort = function() {
     208                    reject(null);
     209                }
     210            });
     211        }
     212
    183213        worker.onmessage = function (e) {
    184214            var blob = e.data;
  • universal-voice-search/trunk/js/recorderjs/uvs.audio-recorder.min.js

    r2176461 r2289691  
    1 (function(window){var WORKER_PATH=uvsWorkerPath;var Recorder=function(source,cfg){var config=cfg||{};var bufferLen=config.bufferLen||4096;this.context=source.context;var uvsAnalyserNode=source.context.createAnalyser();source.connect(uvsAnalyserNode);uvsAnalyserNode.fftSize=2048;let lastLowFilterValue=null;let lowFilterValue=null;let minFilterValue=null;let maxFilterValue=null;let reachedHigh=!1;let highFreqCount=0;let lowFreqCount=0;if(!this.context.createScriptProcessor){this.node=this.context.createJavaScriptNode(bufferLen,2,2)}else{this.node=this.context.createScriptProcessor(bufferLen,2,2)}
    2 var worker=new Worker(config.workerPath||WORKER_PATH);worker.postMessage({command:'init',config:{sampleRate:this.context.sampleRate}});var recording=!1,currCallback;function uvsAdd(accumulator,a){return accumulator+a}
    3 function uvsLowPassFilter(lastFilterValue,rawFreqValue){if(lastFilterValue==null){return rawFreqValue}
    4 let x=(lastFilterValue*4+rawFreqValue)/5;return x}
    5 function uvsMicButtonClickHandler(){try{if(typeof(uvsMicButtonElInCtx)!='undefined'&&uvsMicButtonElInCtx!==null){var uvsMicClassList=uvsMicButtonElInCtx.className||'';if(uvsMicClassList.indexOf('listening')!=-1)uvsMicButtonElInCtx.click()}}catch(err){console.log('uvs Error: Unable to reset Mic button.')}}
    6 this.node.onaudioprocess=function(e){if(!recording){return}
    7 var uvsAudioData=new Uint8Array(uvsAnalyserNode.frequencyBinCount);uvsAnalyserNode.getByteFrequencyData(uvsAudioData);var currentVol=0;for(let i=0;i<uvsAudioData.length;i++){currentVol=currentVol+uvsAudioData[i]}
    8 lowFilterValue=uvsLowPassFilter(lowFilterValue,currentVol);lowFilterValue=parseInt(lowFilterValue);if(minFilterValue==null){minFilterValue=lowFilterValue}else if(lowFilterValue<minFilterValue){minFilterValue=lowFilterValue}
    9 if(maxFilterValue==null){maxFilterValue=lowFilterValue}else if(lowFilterValue>maxFilterValue){maxFilterValue=lowFilterValue;if(maxFilterValue>2*minFilterValue){reachedHigh=!0}}
    10 if((lastLowFilterValue+10)<lowFilterValue){lowFreqCount=0;highFreqCount=highFreqCount+1}
    11 if((lastLowFilterValue-10)>lowFilterValue){highFreqCount=0;lowFreqCount=lowFreqCount+1}
    12 lastLowFilterValue=lowFilterValue;if(lowFreqCount>17&&reachedHigh){uvsMicButtonClickHandler()}
    13 worker.postMessage({command:'record',buffer:[e.inputBuffer.getChannelData(0),e.inputBuffer.getChannelData(1)]})}
    14 this.configure=function(cfg){for(var prop in cfg){if(cfg.hasOwnProperty(prop)){config[prop]=cfg[prop]}}}
    15 this.record=function(micButtonEl=null){recording=!0;uvsMicButtonElInCtx=micButtonEl}
    16 this.stop=function(){recording=!1;lastLowFilterValue=null;highFreqCount=0;lowFreqCount=0;lowFilterValue=null;minFilterValue=null;maxFilterValue=null;reachedHigh=!1}
    17 this.clear=function(){uvsMicButtonInCtx=null;worker.postMessage({command:'clear'})}
    18 this.getBuffers=function(cb){currCallback=cb||config.callback;worker.postMessage({command:'getBuffers'})}
    19 this.exportWAV=function(cb,type){currCallback=cb||config.callback;type=type||config.type||'audio/wav';if(!currCallback)throw new Error('Callback not set');worker.postMessage({command:'exportWAV',type:type})}
    20 this.exportMonoWAV=function(cb,type){currCallback=cb||config.callback;type=type||config.type||'audio/wav';if(!currCallback)throw new Error('Callback not set');worker.postMessage({command:'exportMonoWAV',type:type})}
    21 worker.onmessage=function(e){var blob=e.data;currCallback(blob)}
    22 uvsAnalyserNode.connect(this.node);this.node.connect(this.context.destination)};window.Recorder=Recorder})(window)
     1!function(t){var n=uvsWorkerPath;t.Recorder=function(t,e){var o=e||{},r=o.bufferLen||4096;this.context=t.context;var a=t.context.createAnalyser();t.connect(a),a.fftSize=2048;let c=null,i=null,s=null,l=null,u=!1,f=0,d=0;this.context.createScriptProcessor?this.node=this.context.createScriptProcessor(r,2,2):this.node=this.context.createJavaScriptNode(r,2,2);var h=new Worker(o.workerPath||n);h.postMessage({command:"init",config:{sampleRate:this.context.sampleRate}});var p,v=!1;this.node.onaudioprocess=function(t){if(v){var n=new Uint8Array(a.frequencyBinCount);a.getByteFrequencyData(n);var e,o,r=0;for(let t=0;t<n.length;t++)r+=n[t];o=r,i=null==(e=i)?o:(4*e+o)/5,i=parseInt(i),null==s?s=i:i<s&&(s=i),null==l?l=i:i>l&&(l=i)>2*s&&(u=!0),c+10<i&&(d=0,f+=1),c-10>i&&(f=0,d+=1),c=i,d>17&&u&&function(){try{"undefined"!=typeof uvsMicButtonElInCtx&&null!==uvsMicButtonElInCtx&&-1!=(uvsMicButtonElInCtx.className||"").indexOf("listening")&&uvsMicButtonElInCtx.click()}catch(t){console.log("uvs Error: Unable to reset Mic button.")}}(),h.postMessage({command:"record",buffer:[t.inputBuffer.getChannelData(0),t.inputBuffer.getChannelData(1)]})}},this.configure=function(t){for(var n in t)t.hasOwnProperty(n)&&(o[n]=t[n])},this.record=function(t=null){v=!0,uvsMicButtonElInCtx=t},this.stop=function(){v=!1,c=null,f=0,d=0,i=null,s=null,l=null,u=!1},this.clear=function(){uvsMicButtonInCtx=null,h.postMessage({command:"clear"})},this.getBuffers=function(t){p=t||o.callback,h.postMessage({command:"getBuffers"})},this.exportWAV=function(t,n){if(p=t||o.callback,n=n||o.type||"audio/wav",!p)throw new Error("Callback not set");h.postMessage({command:"exportWAV",type:n})},this.exportMonoWAV=function(t,n){if(p=t||o.callback,n=n||o.type||"audio/wav",!p)throw new Error("Callback not set");h.postMessage({command:"exportMonoWAV",type:n})},this.convertBlobToBase64=function(t){return new Promise(function(n,e){if(!(void 0!==t&&t&&t instanceof Blob))return void e(null);let o=new FileReader;o.readAsDataURL(t),o.onload=function(){let t=o.result;void 0!==t&&t&&-1!==t.indexOf(",")?n(t.split(",")[1]):e(null)},o.onerror=function(t){o.abort()},o.onabort=function(){e(null)}})},h.onmessage=function(t){var n=t.data;p(n)},a.connect(this.node),this.node.connect(this.context.destination)}}(window);
  • universal-voice-search/trunk/js/settings/uvs-settings.min.js

    r2176461 r2289691  
    1 function uvsResetTimeoutDefaultValue(el,evt){if(typeof(el)=='undefined')return;if(el.value.length==0){el.value="8"}else if(parseInt(el.value)>20){el.value="20"}else if(parseInt(el.value)<8){el.value="8"}}
    2 function uvsValidateTimeoutValue(el,evt){if(typeof(el)=='undefined')return;if(el.value.length==2&&parseInt(el.value)>20){evt.preventDefault()}}
     1function uvsResetTimeoutDefaultValue(e,u){void 0!==e&&(0==e.value.length?e.value="8":parseInt(e.value)>20?e.value="20":parseInt(e.value)<8&&(e.value="8"))}function uvsValidateTimeoutValue(e,u){void 0!==e&&2==e.value.length&&parseInt(e.value)>20&&u.preventDefault()}
  • universal-voice-search/trunk/js/universal-voice-search.js

    r2207334 r2289691  
    245245            var ignore_onend;
    246246
    247             if ('webkitSpeechRecognition' in window) {
     247            if ('webkitSpeechRecognition' in window && uvsSttLanguageContext['ibm']['stt'] === false) {
    248248                var recognition = new webkitSpeechRecognition();
    249249                recognition.continuous = true;
     
    260260
    261261                    if (event.error == 'no-speech') {
    262                         inputEl.placeholder = uvsAlternativeResponse['notAudible'];
    263                         tts(uvsAlternativeResponse['notAudible'], function(){});
     262                        inputEl.placeholder = uvsMessages['unableToHear'];
     263
     264                        // Play 'notAudible' playback
     265                        uvsAudioPlayer.configure(uvsAlternativeResponse['notAudible']);
     266                        uvsAudioPlayer.play();
     267
    264268                        ignore_onend = true;
    265269                    }
     
    287291                        inputEl.value = final_transcript;
    288292
    289                         tts(uvsAlternativeResponse['basic'], function () {
    290                             speechInputWrapper.submit();
    291                         });
     293                        // Play 'basic' playback
     294                        uvsAudioPlayer.configure(uvsAlternativeResponse['basic'], function () { speechInputWrapper.submit(); });
     295                        uvsAudioPlayer.play();
    292296                    } else {
    293                         // tts(uvsAlternativeResponse['notAudible'], function(){});
    294297                        inputEl.placeholder = uvsMessages['ask'];
    295298                    }
     
    309312                        recognition.stop();
    310313                        inputEl.placeholder = uvsMessages['unableToHear'];
    311                         tts(uvsAlternativeResponse['micConnect'], function () { });
     314
     315                        // Play 'micConnect' playback
     316                        uvsAudioPlayer.configure(uvsAlternativeResponse['micConnect']);
     317                        uvsAudioPlayer.play();
     318                       
    312319                        return;
    313320                    }
     
    356363
    357364                    if (recognizing) {
     365                        // Stop ongoing playback if nay
     366                        if (uvsAudioPlayer.isPlaying()) {
     367                            uvsAudioPlayer.stop();
     368                        }
     369                       
    358370                        if (isAndroid == false) {
    359371                            processEnd();
     
    363375                        micBtn.classList.add('listening');
    364376                        event.preventDefault();
    365                         tts_stop();
     377
     378                        // Stop ongoing playback if nay
     379                        if (uvsAudioPlayer.isPlaying()) {
     380                            uvsAudioPlayer.stop();
     381                        }
     382
    366383                        inputEl.value = finalTranscript = '';
    367384                        recognizing = true;
    368                         recognition.lang = uvsSelectedLang;
     385                        recognition.lang = !!uvsSttLanguageContext['gcp']['stt'] ? uvsSttLanguageContext['gcp']['langCode'] : 'en-US';;
    369386                        recognition.start();
    370387                        ignore_onend = false;
     
    394411                        // If API system key is unavailable then acknowledge service unavailability and stop voice navigation.
    395412                        if (!(typeof (uvsXApiKey) != 'undefined' && uvsXApiKey !== null)) {
    396                             tts(uvsAlternativeResponse['unavailable'], function () { });
     413                            // Play 'unavailable' playback
     414                            uvsAudioPlayer.configure(uvsAlternativeResponse['unavailable']);
     415                            uvsAudioPlayer.play();
     416                           
    397417                            return false;
    398418                        }
     
    432452                            uvsStopAudio();
    433453
     454                            // Stop ongoing playback if nay
     455                            if (uvsAudioPlayer.isPlaying()) {
     456                                uvsAudioPlayer.stop();
     457                            }
     458
    434459                            //replace recording with mic icon
    435460                            micBtn.classList.remove('listening');
     
    438463                            inputEl.placeholder = uvsMessages['transcribeText'];
    439464
    440                             tts("", function () {
    441                                 uvsAudioRecorder.getBuffers(function (buffers) {
     465                            uvsAudioRecorder.getBuffers(function (buffers) {
     466                                if (!!uvsSttLanguageContext['ibm']['stt']) {
    442467                                    uvsAudioRecorder.exportWAV(function (blob) {
    443468                                        uvsRecIndex++;
     
    447472                                                inputEl.value = request;
    448473
    449                                                 tts(uvsAlternativeResponse['basic'], function(){
    450                                                     speechInputWrapper.submit();
     474                                                // Play 'basic' playback
     475                                                uvsAudioPlayer.configure(uvsAlternativeResponse['basic'], function(){
     476                                                    speechInputWrapper.submit();
    451477                                                });
     478                                               
     479                                                uvsAudioPlayer.play();
    452480                                            } else {
    453                                                 tts(uvsAlternativeResponse['notAudible'], function(){});
     481                                                // Play 'unavailable' playback
     482                                                uvsAudioPlayer.configure(uvsAlternativeResponse['notAudible']);
     483                                                uvsAudioPlayer.play();
     484
    454485                                                inputEl.placeholder = uvsMessages['ask'];
    455486                                            }
    456487                                        });
    457488                                    });
    458                                 });
     489                                } else if (!!uvsSttLanguageContext['gcp']['stt']) {
     490                                    uvsAudioRecorder.exportMonoWAV(function(blob){
     491                                        uvsAudioRecorder.convertBlobToBase64(blob).then(function(resultedBase64){
     492                                            uvsGcpStt(resultedBase64).then(function(transcriptResult){
     493                                                inputEl.value = transcriptResult;
     494
     495                                                // Play 'basic' playback
     496                                                uvsAudioPlayer.configure(uvsAlternativeResponse['basic'], function(){
     497                                                    speechInputWrapper.submit();
     498                                                });
     499                                                uvsAudioPlayer.play();
     500                                            }).catch(function(error) {
     501                                                // Play 'notAudible' playback
     502                                                uvsAudioPlayer.configure(uvsAlternativeResponse['notAudible']);
     503                                                uvsAudioPlayer.play();
     504
     505                                                inputEl.placeholder = uvsMessages['ask'];
     506                                            })
     507                                        }).catch(function(error){
     508                                            // Play 'notAudible' playback
     509                                            uvsAudioPlayer.configure(uvsAlternativeResponse['notAudible']);
     510                                            uvsAudioPlayer.play();
     511
     512                                            inputEl.placeholder = uvsMessages['ask'];
     513                                        });
     514                                    });
     515                                } else {
     516                                    // Play 'notAudible' playback
     517                                    uvsAudioPlayer.configure(uvsAlternativeResponse['notAudible']);
     518                                    uvsAudioPlayer.play();
     519
     520                                    inputEl.placeholder = uvsMessages['ask'];
     521                                }
    459522                            });
    460 
     523                           
    461524                            recognizing = false;
    462525                            return;
     
    465528                            event.preventDefault();
    466529
    467                             tts_stop();
     530                            // Stop ongoing playback if nay
     531                            if (uvsAudioPlayer.isPlaying()) {
     532                                uvsAudioPlayer.stop();
     533                            }
     534
    468535                            inputEl.value = finalTranscript = '';
    469536
     
    611678        let widget_ignore_onend;
    612679
    613         if ('webkitSpeechRecognition' in window) {
     680        if ('webkitSpeechRecognition' in window && uvsSttLanguageContext['ibm']['stt'] === false) {
    614681            let widgetRecognition = new webkitSpeechRecognition();
    615682            widgetRecognition.continuous = true;
     
    625692
    626693                if (event.error == 'no-speech') {
    627                     tts(uvsAlternativeResponse['notAudible'], function(){});
     694                    // Play feature unavailable playback
     695                    uvsAudioPlayer.configure(uvsAlternativeResponse['notAudible']);
     696                    uvsAudioPlayer.play();
     697
    628698                    widget_ignore_onend = true;
    629                     uvsWidgetSearch.placeholder = uvsAlternativeResponse['notAudible'];
     699                    uvsWidgetSearch.placeholder = uvsMessages['unableToHear'];
    630700                }
    631701
     
    651721                if (typeof(widgetFinalTranscript) != 'undefined' && widgetFinalTranscript.length != 0) {
    652722                    uvsWidgetSearch.value = widgetFinalTranscript;
    653                    
    654                     tts(uvsAlternativeResponse['basic'], function () {
     723
     724                    // Play 'basic' playback
     725                    uvsAudioPlayer.configure(uvsAlternativeResponse['basic'], function(){
    655726                        uvsWidgetForm.submit();
    656727                    });
     728                    uvsAudioPlayer.play();
    657729                } else {
    658                     tts(uvsAlternativeResponse['notAudible'], function(){});
     730                    // Play 'notAudible' playback
     731                    uvsAudioPlayer.configure(uvsAlternativeResponse['notAudible']);
     732                    uvsAudioPlayer.play();
     733
    659734                    uvsWidgetSearch.placeholder = uvsMessages['ask'];
    660735                }
     
    673748                    widgetRecognition.stop();
    674749                    uvsWidgetSearch.placeholder = uvsMessages['unableToHear'];
    675                     tts(uvsAlternativeResponse['micConnect'], function () { });
     750
     751                    // Play 'micConnect' playback
     752                    uvsAudioPlayer.configure(uvsAlternativeResponse['micConnect']);
     753                    uvsAudioPlayer.play();
     754
    676755                    return;
    677756                }
     
    724803
    725804                if (widgetRecognizing) {
     805                    // Stop ongoing playback if nay
     806                    if (uvsAudioPlayer.isPlaying()) {
     807                        uvsAudioPlayer.stop();
     808                    }
     809
    726810                    if (isAndroid == false) {
    727811                        widgetProcessEnd();
     
    731815                    uvsWidgetMic.classList.add('listening');
    732816                    event.preventDefault();
    733                     tts_stop();
     817
     818                    // Stop ongoing playback if nay
     819                    if (uvsAudioPlayer.isPlaying()) {
     820                        uvsAudioPlayer.stop();
     821                    }
     822
    734823                    widgetFinalTranscript = '';
    735824                    widgetRecognizing = true;
    736                     widgetRecognition.lang = uvsSelectedLang;
     825                    widgetRecognition.lang = !!uvsSttLanguageContext['gcp']['stt'] ? uvsSttLanguageContext['gcp']['langCode'] : 'en-US';
    737826                    widgetRecognition.start();
    738827                    widget_ignore_onend = false;
     
    762851                    // If API system key is unavailable then acknowledge service unavailability and stop voice navigation.
    763852                    if (!(typeof (uvsXApiKey) != 'undefined' && uvsXApiKey !== null)) {
    764                         tts(uvsAlternativeResponse['unavailable'], function () { });
     853                        // Play 'unavailable' playback
     854                        uvsAudioPlayer.configure(uvsAlternativeResponse['unavailable']);
     855                        uvsAudioPlayer.play();
     856
    765857                        return false;
    766858                    }
     
    801893                        uvsStopAudio();
    802894
     895                        // Stop ongoing playback if nay
     896                        if (uvsAudioPlayer.isPlaying()) {
     897                            uvsAudioPlayer.stop();
     898                        }
     899
    803900                        //replace recording with mic icon
    804901                        uvsWidgetMic.classList.remove('listening');
    805902
    806903                        uvsWidgetSearch.placeholder = uvsMessages['transcribeText'];
    807 
    808                         tts("", function () {
    809                             uvsAudioRecorder.getBuffers(function (buffers) {
     904                       
     905                        uvsAudioRecorder.getBuffers(function (buffers) {
     906                            if (!!uvsSttLanguageContext['ibm']['stt']) {
    810907                                uvsAudioRecorder.exportWAV(function (blob) {
    811908                                    uvsRecIndex++;
     
    815912                                            uvsWidgetSearch.value = request;
    816913
    817                                             tts(uvsAlternativeResponse['basic'], function(){
     914                                            // Play 'basic' playback
     915                                            uvsAudioPlayer.configure(uvsAlternativeResponse['basic'], function(){
    818916                                                uvsWidgetForm.submit();
    819917                                            });
     918                                            uvsAudioPlayer.play();                                           
    820919                                        } else {
    821                                             tts(uvsAlternativeResponse['notAudible'], function(){});
     920                                            // Play 'notAudible' playback
     921                                            uvsAudioPlayer.configure(uvsAlternativeResponse['notAudible']);
     922                                            uvsAudioPlayer.play();
     923
    822924                                            uvsWidgetSearch.placeholder = uvsMessages['ask'];
    823925                                        }
    824926                                    });
    825927                                });
    826                             });
     928                            } else if (!!uvsSttLanguageContext['gcp']['stt']) {
     929                                uvsAudioRecorder.exportMonoWAV(function(blob){
     930                                    uvsAudioRecorder.convertBlobToBase64(blob).then(function(resultedBase64){
     931                                        uvsGcpStt(resultedBase64).then(function(transcriptResult){
     932                                            uvsWidgetSearch.value = transcriptResult;
     933
     934                                            // Play 'basic' playback
     935                                            uvsAudioPlayer.configure(uvsAlternativeResponse['basic'], function(){
     936                                                uvsWidgetForm.submit();
     937                                            });
     938                                            uvsAudioPlayer.play();
     939                                        }).catch(function(error) {
     940                                            // Play 'notAudible' playback
     941                                            uvsAudioPlayer.configure(uvsAlternativeResponse['notAudible']);
     942                                            uvsAudioPlayer.play();
     943
     944                                            uvsWidgetSearch.placeholder = uvsMessages['ask'];
     945                                        })
     946                                    }).catch(function(error){
     947                                        // Play 'notAudible' playback
     948                                        uvsAudioPlayer.configure(uvsAlternativeResponse['notAudible']);
     949                                        uvsAudioPlayer.play();
     950
     951                                        uvsWidgetSearch.placeholder = uvsMessages['ask'];
     952                                    });
     953                                });
     954                            } else {
     955                                // Play 'notAudible' playback
     956                                uvsAudioPlayer.configure(uvsAlternativeResponse['notAudible']);
     957                                uvsAudioPlayer.play();
     958
     959                                uvsWidgetSearch.placeholder = uvsMessages['ask'];
     960                            }
    827961                        });
    828962
     
    833967                        event.preventDefault();
    834968
    835                         tts_stop();
     969                        // Stop ongoing playback if nay
     970                        if (uvsAudioPlayer.isPlaying()) {
     971                            uvsAudioPlayer.stop();
     972                        }
     973
    836974                        widgetFinalTranscript = '';
    837975
  • universal-voice-search/trunk/js/universal-voice-search.min.js

    r2207334 r2289691  
    1 (function(){'use strict';let uvsTimerID=0;var uvsMicListenAutoTimeoutDuration=null;if(typeof(uvsMicListenTimeoutDuration)!='undefined'&&uvsMicListenTimeoutDuration!==null){uvsMicListenAutoTimeoutDuration=parseInt(uvsMicListenTimeoutDuration);uvsMicListenAutoTimeoutDuration=isNaN(uvsMicListenAutoTimeoutDuration)?8:uvsMicListenAutoTimeoutDuration}else{uvsMicListenAutoTimeoutDuration=8}
    2 uvsMicListenAutoTimeoutDuration=(uvsMicListenAutoTimeoutDuration<8)?8:uvsMicListenAutoTimeoutDuration;uvsMicListenAutoTimeoutDuration=(uvsMicListenAutoTimeoutDuration>20)?20:uvsMicListenAutoTimeoutDuration;uvsMicListenAutoTimeoutDuration=uvsMicListenAutoTimeoutDuration*1000;function uvsClearTimer(timerInstance){try{if(typeof(timerInstance)!='undefined'&&timerInstance!==null&&timerInstance!=!1){clearInterval(timerInstance)}}catch(err){}}
    3 function getNumber(number){number=parseInt(number,10);return isNaN(number)||number===null||typeof(number)==='undefined'?0:number}
    4 function uvsAnyOtherMicListening(uvsExceptionBtnId=null){var uvsOneOfMicListening=!1;try{var uvsAllMicButtons=document.querySelectorAll('button.universal-voice-search-button');if(typeof(uvsAllMicButtons)=='undefined'||uvsAllMicButtons===null||uvsExceptionBtnId==null){return uvsOneOfMicListening}
    5 for(var uvsI=0;uvsI<uvsAllMicButtons.length;uvsI++){var uvsClassNames=uvsAllMicButtons[uvsI].className;var uvsBtnId=uvsAllMicButtons[uvsI].getAttribute('id');if(!(typeof(uvsClassNames)!='undefined'&&uvsClassNames.trim()!=''))continue;if(uvsClassNames.indexOf('listening')!=-1&&uvsExceptionBtnId!=uvsBtnId){uvsOneOfMicListening=!0;break}}}catch(err){uvsOneOfMicListening=!1}
    6 return uvsOneOfMicListening}
    7 var inputWrapperSelectorsToSeek=['form[role=search]','form[class=searchform]','form[class=search_form]','form[class=search-form]','form[class=searchForm]'];var searchInputSelectorsToSeek=['input[name=s]','input[name=search]','input[name=find]','input[type=search]','input[class=search-field]','input[class=search_field]','input[class=searchfield]','input[class=searchField]','input[id=search]','input[id=search-field]','input[id=search_field]','input[id=searchfield]','input[id=searchField]'];var uvsIOS=!!navigator.platform&&/iPad|iPhone|iPod/.test(navigator.platform);var uvsMicEventToListen=(uvsIOS===!0)?'touchend':'click';var ua=navigator.userAgent.toLowerCase();var isAndroid=ua.indexOf("android")>-1;var recordTimer=null;var uvsAllFormsOnPage=document.querySelectorAll('form');var speechInputWrappers=[];try{for(var vdnI=0;vdnI<inputWrapperSelectorsToSeek.length;vdnI++){speechInputWrappers=document.querySelectorAll(inputWrapperSelectorsToSeek[vdnI]);if(speechInputWrappers.length>0){break}}}catch(err){speechInputWrappers=[]}
    8 if(speechInputWrappers.length<uvsAllFormsOnPage.length){speechInputWrappers=null;speechInputWrappers=uvsAllFormsOnPage}
    9 let formElementForWidget=null;[].forEach.call(speechInputWrappers,function(speechInputWrapper,index){var inputEl=null;var recognizing=!1;try{if(index==0){formElementForWidget=speechInputWrapper}
    10 for(var uvsI=0;uvsI<searchInputSelectorsToSeek.length;uvsI++){inputEl=speechInputWrapper.querySelector(searchInputSelectorsToSeek[uvsI]);if(inputEl!==null){break}}
    11 let formSubmitBtnEl=speechInputWrapper.querySelector("input[type=submit]");if(formSubmitBtnEl===null){formSubmitBtnEl=speechInputWrapper.querySelector("button[type=submit]")}
    12 if(formSubmitBtnEl!==null){speechInputWrapper.addEventListener('submit',function(submitEvent){if(recognizing==!0){submitEvent.preventDefault()}},!1);try{let submitButtonChildNodes=formSubmitBtnEl.querySelectorAll('img, svg');for(let j=0;j<submitButtonChildNodes.length;j++){let submitBtnChildNode=submitButtonChildNodes[j];submitBtnChildNode.classList.add('uvs-hide-element')}}catch(err){}}}catch(err){inputEl=null}
    13 if(null===inputEl){return}
    14 try{var speechInputWrapperStyle=speechInputWrapper.getAttribute('style');var havingInlineStyle=(typeof(speechInputWrapperStyle)!='undefined'&&speechInputWrapperStyle!==null&&speechInputWrapperStyle.trim()!='')?!0:!1;speechInputWrapperStyle=(havingInlineStyle)?speechInputWrapperStyle+';':'';speechInputWrapper.setAttribute('style',speechInputWrapperStyle+'display: block !important');speechInputWrapper.classList.add('universal-voice-search-wrapper');speechInputWrapper.classList.add('uvs-sanitize-form-wrapper');var micBtn=document.createElement('button');micBtn.setAttribute('type','button');micBtn.setAttribute('class','universal-voice-search-button');micBtn.setAttribute('id','universal-voice-search-button'+index);micBtn.appendChild(document.createTextNode(universal_voice_search.button_message));var uvsMicIcon=document.createElement('img');uvsMicIcon.setAttribute('src',uvsImagesPath+'uvs_mic.svg');uvsMicIcon.setAttribute('class','uvs-mic-image');micBtn.appendChild(uvsMicIcon);var inputHeight=getNumber(inputEl.offsetHeight);var buttonSize=getNumber(0.8*inputHeight);if(getNumber(buttonSize)==0){inputHeight=buttonSize=35}
    15 var micbtnPositionTop=getNumber(0.1*inputHeight);var inlineStyle='top: '+micbtnPositionTop+'px; ';inlineStyle+='height: '+buttonSize+'px !important; ';inlineStyle+='width: '+buttonSize+'px !important; ';inlineStyle+='z-index: 999 !important; margin-left: 3px !important; border-radius: 50% !important;  border: 2px solid #ffff !important;';micBtn.setAttribute('style',inlineStyle);var wrapper=document.createElement('div');let inputCurrentStyle=window.getComputedStyle(inputEl);wrapper.setAttribute('class','uvs-mic-band');wrapper.setAttribute('onclick','return false');wrapper.style.width=inputCurrentStyle.width;inputEl.insertAdjacentElement('beforebegin',wrapper);var parentEl=inputEl.parentNode.nodeName;if(typeof(parentEl)!='undefined'&&parentEl!==null&&parentEl.length!=0){parentEl=parentEl.toLowerCase();if(parentEl!='form'){inputEl.parentNode.style.zIndex=1}}
    16 wrapper.appendChild(inputEl);inputEl.insertAdjacentElement('beforebegin',micBtn);inputEl.classList.add('uvs-mic-band');speechInputWrapper.setAttribute('style',speechInputWrapperStyle);var finalTranscript='';var final_transcript="";var ignore_onend;if('webkitSpeechRecognition' in window){var recognition=new webkitSpeechRecognition();recognition.continuous=!0;recognition.interimResults=!0;recognition.onstart=function(){recognizing=!0};recognition.onerror=function(event){uvsClearTimer(recordTimer);micBtn.classList.remove('listening');recognizing=!1;if(event.error=='no-speech'){inputEl.placeholder=uvsAlternativeResponse.notAudible;tts(uvsAlternativeResponse.notAudible,function(){});ignore_onend=!0}
    17 if(event.error=='audio-capture'){inputEl.placeholder=uvsMessages.micNotAccessible;ignore_onend=!0}
    18 if(event.error=='not-allowed'){inputEl.placeholder=uvsMessages.browserDenyMicAccess;micBtn.style.setProperty("color","white");ignore_onend=!0}};function processEnd(){recognizing=!1;if(ignore_onend){return}
    19 finalTranscript=final_transcript;micBtn.classList.remove('listening');micBtn.style.setProperty("color","white");if(typeof(finalTranscript)!='undefined'&&finalTranscript.length!=0){inputEl.value=final_transcript;tts(uvsAlternativeResponse.basic,function(){speechInputWrapper.submit()})}else{inputEl.placeholder=uvsMessages.ask}};recognition.onend=function(){if(isAndroid){processEnd()}};recognition.onresult=function(event){let interim_transcript='';if(typeof(event.results)=='undefined'){recognition.onend=null;recognition.stop();inputEl.placeholder=uvsMessages.unableToHear;tts(uvsAlternativeResponse.micConnect,function(){});return}
    20 for(var i=event.resultIndex;i<event.results.length;++i){if(event.results[i].isFinal){final_transcript=event.results[i][0].transcript;if(isAndroid==!1){processEnd();recognition.stop()}}else{interim_transcript+=event.results[i][0].transcript;inputEl.value=interim_transcript}}};micBtn.addEventListener(uvsMicEventToListen,function(event){if(uvsAnyOtherMicListening(micBtn.getAttribute('id'))===!0)return;var micButtonInteracted=document.getElementById("universal-voice-search-button"+index);var classNamesInContext=micButtonInteracted.className;if(!(typeof(classNamesInContext)!='undefined'&&classNamesInContext!==null&&classNamesInContext.indexOf('listening')!=-1)){recordTimer=setInterval(function(){var updatedClassNames=micButtonInteracted.className;if(typeof(updatedClassNames)!='undefined'&&updatedClassNames!==null&&updatedClassNames.indexOf('listening')!=-1){micButtonInteracted.click()}
    21 uvsClearTimer(recordTimer);recordTimer=!1},uvsMicListenAutoTimeoutDuration)}
    22 if(recognizing){if(isAndroid==!1){processEnd();recognition.stop()}}else{micBtn.classList.add('listening');event.preventDefault();tts_stop();inputEl.value=finalTranscript='';recognizing=!0;recognition.lang=uvsSelectedLang;recognition.start();ignore_onend=!1}})}else{micBtn.addEventListener(uvsMicEventToListen,function(event){if(uvsAnyOtherMicListening(micBtn.getAttribute('id'))===!0)return;if(!uvsAudioRecorder||!uvsAudioContext){uvsInitAudio(function(a){if(!uvsAudioRecorder||!uvsAudioContext){alert(uvsMessages.cantAccessMicrophone);return!1}else{listenEvent()}})}else{listenEvent()}
    23 function listenEvent(){if(!(typeof(uvsXApiKey)!='undefined'&&uvsXApiKey!==null)){tts(uvsAlternativeResponse.unavailable,function(){});return!1}
    24 var micButtonInteracted=document.getElementById("universal-voice-search-button"+index);var classNamesInContext=micButtonInteracted.className;if(!(typeof(classNamesInContext)!='undefined'&&classNamesInContext!==null&&classNamesInContext.indexOf('listening')!=-1)){recordTimer=setInterval(function(){var updatedClassNames=micButtonInteracted.className;if(typeof(updatedClassNames)!='undefined'&&updatedClassNames!==null&&updatedClassNames.indexOf('listening')!=-1){micButtonInteracted.click()}
    25 uvsClearTimer(recordTimer);recordTimer=!1},uvsMicListenAutoTimeoutDuration)}
    26 if(recognizing){uvsClearTimer(recordTimer);uvsAudioRecorder.stop();uvsStopAudio();micBtn.classList.remove('listening');micBtn.style.setProperty("color","white");inputEl.placeholder=uvsMessages.transcribeText;tts("",function(){uvsAudioRecorder.getBuffers(function(buffers){uvsAudioRecorder.exportWAV(function(blob){uvsRecIndex++;stt(blob,!1,function(request){if(typeof(request)!='undefined'&&request.length!=0){inputEl.value=request;tts(uvsAlternativeResponse.basic,function(){speechInputWrapper.submit()})}else{tts(uvsAlternativeResponse.notAudible,function(){});inputEl.placeholder=uvsMessages.ask}})})})});recognizing=!1;return}else{micBtn.classList.add('listening');event.preventDefault();tts_stop();inputEl.value=finalTranscript='';recognizing=!0;uvsAudioRecorder.clear();uvsAudioRecorder.record(micButtonInteracted)}}},!1)}}catch(err){}});if(uvsFloatingMic&&uvsFloatingMic==='yes'){let uvsDocFragment=document.createDocumentFragment();let uvsWidgetWrapper=document.createElement('div');let uvsWrapperMicPositionClass='uvs-widget-wrapper-middle-right';let uvsChatWrapperMicPositionClass='uvs-widget-chat-wrapper-middle-right';let uvsMicPosition=uvsSelectedMicPosition?uvsSelectedMicPosition.toLowerCase():'middle right';switch(uvsMicPosition){case 'middle left':uvsWrapperMicPositionClass='uvs-widget-wrapper-middle-left';uvsChatWrapperMicPositionClass='uvs-widget-chat-wrapper-middle-left';break;case 'top right':uvsWrapperMicPositionClass='uvs-widget-wrapper-top-right';uvsChatWrapperMicPositionClass='uvs-widget-chat-wrapper-top-right';break;case 'top left':uvsWrapperMicPositionClass='uvs-widget-wrapper-top-left';uvsChatWrapperMicPositionClass='uvs-widget-chat-wrapper-top-left';break;case 'bottom right':uvsWrapperMicPositionClass='uvs-widget-wrapper-bottom-right';uvsChatWrapperMicPositionClass='uvs-widget-chat-wrapper-bottom-right';break;case 'bottom left':uvsWrapperMicPositionClass='uvs-widget-wrapper-bottom-left';uvsChatWrapperMicPositionClass='uvs-widget-chat-wrapper-bottom-left';break;default:uvsWrapperMicPositionClass='uvs-widget-wrapper-middle-right';uvsChatWrapperMicPositionClass='uvs-widget-chat-wrapper-middle-right'}
    27 uvsWidgetWrapper.setAttribute('class','uvs-widget-wrapper '+uvsWrapperMicPositionClass+'');let uvsWidgetChatWrapper=document.createElement('div');uvsWidgetChatWrapper.setAttribute('class','uvs-widget-chat-wrapper '+uvsChatWrapperMicPositionClass+'');let uvsWidgetField=document.createElement('div');uvsWidgetField.setAttribute('class','uvs-widget-field');let uvsWidgetMic=document.createElement('a');uvsWidgetMic.setAttribute('id','uvsWidgetMic');uvsWidgetMic.setAttribute('class','uvs-widget-button');let uvsWidgetMicImg=document.createElement('img');uvsWidgetMicImg.setAttribute('src',uvsImagesPath+'uvs-widget-mic-black.svg');uvsWidgetMic.appendChild(uvsWidgetMicImg);let uvsWidgetSearchBtn=document.createElement('a');uvsWidgetSearchBtn.setAttribute('id','uvsWidgetSearchBtn');let uvsWidgetSearchBtnEl=document.createElement('button');uvsWidgetSearchBtnEl.setAttribute('class','uvs-widget-form-submit-btn');uvsWidgetSearchBtnEl.setAttribute('type','submit');uvsWidgetSearchBtnEl.setAttribute('alt','Go');uvsWidgetSearchBtnEl.setAttribute('title','Search');uvsWidgetSearchBtn.appendChild(uvsWidgetSearchBtnEl);let uvsWidgetForm=document.createElement('form');uvsWidgetForm.setAttribute("class","uvs-widget-form");if(formElementForWidget!==null){uvsWidgetForm.action=formElementForWidget.action;uvsWidgetForm.method=formElementForWidget.method}else{uvsWidgetForm.action=uvsGetCurrentHostURL()+'/';uvsWidgetForm.method="get"}
    28 let uvsWidgetSearch=document.createElement('input');uvsWidgetSearch.setAttribute('id','uvsWidgetSearch');uvsWidgetSearch.setAttribute('class','uvs-widget-search uvs-widget-search-text');uvsWidgetSearch.setAttribute('name','uvs-widget-search');uvsWidgetSearch.setAttribute('placeholder',uvsWidgetMessages.placeholder);uvsWidgetSearch.setAttribute('name','s');uvsWidgetForm.appendChild(uvsWidgetSearch);uvsWidgetForm.appendChild(uvsWidgetSearchBtn);uvsWidgetField.appendChild(uvsWidgetMic);uvsWidgetField.appendChild(uvsWidgetForm);uvsWidgetChatWrapper.appendChild(uvsWidgetField);let uvsWidgetToggleButton=document.createElement('a');uvsWidgetToggleButton.setAttribute('id','uvsWidgetToggleButton');uvsWidgetToggleButton.setAttribute('class','uvs-widget-button');let uvsWidgetIcon=document.createElement('div');uvsWidgetIcon.setAttribute('class','uvs-widget-icon uvs-widget-toggle-button uvs-toggle-btn-mic');uvsWidgetToggleButton.appendChild(uvsWidgetIcon);uvsWidgetWrapper.appendChild(uvsWidgetChatWrapper);uvsWidgetWrapper.appendChild(uvsWidgetToggleButton);uvsDocFragment.appendChild(uvsWidgetWrapper);document.body.appendChild(uvsDocFragment);uvsWidgetToggleButton.addEventListener('click',function(event){uvsToggleWidgetElements()});let widgetFinalTranscript='';let widgetRecognizing=!1;let widget_final_transcript="";let widget_ignore_onend;if('webkitSpeechRecognition' in window){let widgetRecognition=new webkitSpeechRecognition();widgetRecognition.continuous=!0;widgetRecognition.interimResults=!0;widgetRecognition.onstart=function(){widgetRecognizing=!0};widgetRecognition.onerror=function(event){uvsWidgetMic.classList.remove('listening');widgetRecognizing=!1;if(event.error=='no-speech'){tts(uvsAlternativeResponse.notAudible,function(){});widget_ignore_onend=!0;uvsWidgetSearch.placeholder=uvsAlternativeResponse.notAudible}
    29 if(event.error=='audio-capture'){widget_ignore_onend=!0;uvsWidgetSearch.placeholder=uvsMessages.micNotAccessible}
    30 if(event.error=='not-allowed'){widget_ignore_onend=!0;uvsWidgetSearch.placeholder=uvsMessages.browserDenyMicAccess}};function widgetProcessEnd(){widgetRecognizing=!1;if(widget_ignore_onend){return}
    31 widgetFinalTranscript=widget_final_transcript;uvsWidgetMic.classList.remove('listening');if(typeof(widgetFinalTranscript)!='undefined'&&widgetFinalTranscript.length!=0){uvsWidgetSearch.value=widgetFinalTranscript;tts(uvsAlternativeResponse.basic,function(){uvsWidgetForm.submit()})}else{tts(uvsAlternativeResponse.notAudible,function(){});uvsWidgetSearch.placeholder=uvsMessages.ask}}
    32 widgetRecognition.onend=function(){if(isAndroid){widgetProcessEnd()}};widgetRecognition.onresult=function(event){let interim_transcript='';if(typeof(event.results)=='undefined'){widgetRecognition.onend=null;widgetRecognition.stop();uvsWidgetSearch.placeholder=uvsMessages.unableToHear;tts(uvsAlternativeResponse.micConnect,function(){});return}
    33 let eventResultsLength=event.results.length;for(let i=event.resultIndex;i<eventResultsLength;++i){if(event.results[i].isFinal){widget_final_transcript=event.results[i][0].transcript;if(isAndroid==!1){widgetProcessEnd();widgetRecognition.stop()}}else{interim_transcript+=event.results[i][0].transcript}}};uvsWidgetMic.addEventListener(uvsMicEventToListen,function(event){if(uvsAnyOtherMicListening(uvsWidgetMic.getAttribute('id'),uvsWidgetMic)===!0)return;let classNamesInContext=uvsWidgetMic.className;function uvsSetTimeOut(uvsMyTimerid,uvsMicBtn,uvsTimeOutTime){return new Promise(function(resolve){setTimeout(function(){var updatedClassNames=uvsMicBtn.className;if(typeof(updatedClassNames)!='undefined'&&updatedClassNames!==null&&updatedClassNames.indexOf('listening')!=-1&&uvsMyTimerid==uvsTimerID){uvsMicBtn.click()}
    34 resolve('resolved')},uvsTimeOutTime)})}
    35 if(!(typeof(classNamesInContext)!='undefined'&&classNamesInContext!==null&&classNamesInContext.indexOf('listening')!=-1)){uvsTimerID=uvsTimerID+1;uvsSetTimeOut(uvsTimerID,uvsWidgetMic,uvsMicListenAutoTimeoutDuration)}
    36 if(widgetRecognizing){if(isAndroid==!1){widgetProcessEnd();widgetRecognition.stop()}}else{uvsWidgetMic.classList.add('listening');event.preventDefault();tts_stop();widgetFinalTranscript='';widgetRecognizing=!0;widgetRecognition.lang=uvsSelectedLang;widgetRecognition.start();widget_ignore_onend=!1}})}else{uvsWidgetMic.addEventListener(uvsMicEventToListen,function(event){if(uvsAnyOtherMicListening(uvsWidgetMic.getAttribute('id'),uvsWidgetMic)===!0)return;if(!uvsAudioRecorder||!uvsAudioContext){uvsInitAudio(function(a){if(!uvsAudioRecorder||!uvsAudioContext){uvsWidgetSearch.placeholder=uvsMessages.micNotAccessible;return!1}else{widgetListenEvent()}})}else{widgetListenEvent()}
    37 function widgetListenEvent(){if(!(typeof(uvsXApiKey)!='undefined'&&uvsXApiKey!==null)){tts(uvsAlternativeResponse.unavailable,function(){});return!1}
    38 let classNamesInContext=uvsWidgetMic.className;function uvsSetTimeOut(uvsMyTimerid,uvsMicBtn,uvsTimeOutTime){return new Promise(function(resolve){setTimeout(function(){var updatedClassNames=uvsMicBtn.className;if(typeof(updatedClassNames)!='undefined'&&updatedClassNames!==null&&updatedClassNames.indexOf('listening')!=-1&&uvsMyTimerid==uvsTimerID){uvsWidgetMic.click()}
    39 resolve('resolved')},uvsTimeOutTime)})}
    40 if(!(typeof(classNamesInContext)!='undefined'&&classNamesInContext!==null&&classNamesInContext.indexOf('listening')!=-1)){uvsTimerID=uvsTimerID+1;uvsSetTimeOut(uvsTimerID,uvsWidgetMic,uvsMicListenAutoTimeoutDuration)}
    41 if(widgetRecognizing){uvsAudioRecorder.stop();uvsStopAudio();uvsWidgetMic.classList.remove('listening');uvsWidgetSearch.placeholder=uvsMessages.transcribeText;tts("",function(){uvsAudioRecorder.getBuffers(function(buffers){uvsAudioRecorder.exportWAV(function(blob){uvsRecIndex++;stt(blob,!1,function(request){if(typeof(request)!='undefined'&&request.length!=0){uvsWidgetSearch.value=request;tts(uvsAlternativeResponse.basic,function(){uvsWidgetForm.submit()})}else{tts(uvsAlternativeResponse.notAudible,function(){});uvsWidgetSearch.placeholder=uvsMessages.ask}})})})});widgetRecognizing=!1;return}else{uvsWidgetMic.classList.add('listening');event.preventDefault();tts_stop();widgetFinalTranscript='';widgetRecognizing=!0;uvsAudioRecorder.clear();uvsAudioRecorder.record(uvsWidgetMic)}}},!1)}
    42 function uvsToggleClass(elmSelector,nameOfClass){if(!(typeof(elmSelector)!='undefined'&&elmSelector!=null&&elmSelector.length!=0))return!1;let element=document.querySelector(elmSelector);if(element.classList){element.classList.toggle(nameOfClass)}else{let classes=element.className.split(" ");let i=classes.indexOf(nameOfClass);if(i>=0){classes.splice(i,1)}else{classes.push(nameOfClass);element.className=classes.join(" ")}}}
    43 function uvsToggleWidgetElements(){uvsToggleClass('.uvs-widget-toggle-button','uvs-toggle-btn-mic');uvsToggleClass('.uvs-widget-toggle-button','uvs-toggle-btn-close');uvsToggleClass('.uvs-widget-toggle-button','uvs-widget-active');uvsToggleClass('.uvs-widget-toggle-button','uvs-widget-visible');uvsToggleClass('#uvsWidgetToggleButton','uvs-widget-float');uvsToggleClass('.uvs-widget-chat-wrapper','uvs-widget-visible');uvsToggleClass('.uvs-widget-button','uvs-widget-visible')}}})()
     1!function(){"use strict";let e=0;var t=null;function s(e){try{null!=e&&0!=e&&clearInterval(e)}catch(e){}}function i(e){return e=parseInt(e,10),isNaN(e)||null==e?0:e}function u(e=null){var t=!1;try{var s=document.querySelectorAll("button.universal-voice-search-button");if(null==s||null==e)return t;for(var i=0;i<s.length;i++){var u=s[i].className,n=s[i].getAttribute("id");if(void 0!==u&&""!=u.trim()&&(-1!=u.indexOf("listening")&&e!=n)){t=!0;break}}}catch(e){t=!1}return t}"undefined"!=typeof uvsMicListenTimeoutDuration&&null!==uvsMicListenTimeoutDuration?(t=parseInt(uvsMicListenTimeoutDuration),t=isNaN(t)?8:t):t=8,t=(t=t<8?8:t)>20?20:t,t*=1e3;var n=["form[role=search]","form[class=searchform]","form[class=search_form]","form[class=search-form]","form[class=searchForm]"],r=["input[name=s]","input[name=search]","input[name=find]","input[type=search]","input[class=search-field]","input[class=search_field]","input[class=searchfield]","input[class=searchField]","input[id=search]","input[id=search-field]","input[id=search_field]","input[id=searchfield]","input[id=searchField]"],o=!0===(!!navigator.platform&&/iPad|iPhone|iPod/.test(navigator.platform))?"touchend":"click",l=navigator.userAgent.toLowerCase().indexOf("android")>-1,a=null,c=document.querySelectorAll("form"),d=[];try{for(var v=0;v<n.length&&!((d=document.querySelectorAll(n[v])).length>0);v++);}catch(e){d=[]}d.length<c.length&&(d=null,d=c);let p=null;if([].forEach.call(d,function(e,n){var c=null,d=!1;try{0==n&&(p=e);for(var v=0;v<r.length&&null===(c=e.querySelector(r[v]));v++);let t=e.querySelector("input[type=submit]");if(null===t&&(t=e.querySelector("button[type=submit]")),null!==t){e.addEventListener("submit",function(e){1==d&&e.preventDefault()},!1);try{let e=t.querySelectorAll("img, svg");for(let t=0;t<e.length;t++){e[t].classList.add("uvs-hide-element")}}catch(e){}}}catch(e){c=null}if(null!==c)try{var g=e.getAttribute("style");g=null!=g&&""!=g.trim()?g+";":"",e.setAttribute("style",g+"display: block !important"),e.classList.add("universal-voice-search-wrapper"),e.classList.add("uvs-sanitize-form-wrapper");var A=document.createElement("button");A.setAttribute("type","button"),A.setAttribute("class","universal-voice-search-button"),A.setAttribute("id","universal-voice-search-button"+n),A.appendChild(document.createTextNode(universal_voice_search.button_message));var f=document.createElement("img");f.setAttribute("src",uvsImagesPath+"uvs_mic.svg"),f.setAttribute("class","uvs-mic-image"),A.appendChild(f);var m=i(c.offsetHeight),h=i(.8*m);0==i(h)&&(m=h=35);var b="top: "+i(.1*m)+"px; ";b+="height: "+h+"px !important; ",b+="width: "+h+"px !important; ",b+="z-index: 999 !important; margin-left: 3px !important; border-radius: 50% !important;  border: 2px solid #ffff !important;",A.setAttribute("style",b);var y=document.createElement("div");let r=window.getComputedStyle(c);y.setAttribute("class","uvs-mic-band"),y.setAttribute("onclick","return false"),y.style.width=r.width,c.insertAdjacentElement("beforebegin",y);var w=c.parentNode.nodeName;null!=w&&0!=w.length&&"form"!=(w=w.toLowerCase())&&(c.parentNode.style.zIndex=1),y.appendChild(c),c.insertAdjacentElement("beforebegin",A),c.classList.add("uvs-mic-band"),e.setAttribute("style",g);var P,R="",x="";if("webkitSpeechRecognition"in window&&!1===uvsSttLanguageContext.ibm.stt){var L=new webkitSpeechRecognition;function C(){d=!1,P||(R=x,A.classList.remove("listening"),A.style.setProperty("color","white"),void 0!==R&&0!=R.length?(c.value=x,uvsAudioPlayer.configure(uvsAlternativeResponse.basic,function(){e.submit()}),uvsAudioPlayer.play()):c.placeholder=uvsMessages.ask)}L.continuous=!0,L.interimResults=!0,L.onstart=function(){d=!0},L.onerror=function(e){s(a),A.classList.remove("listening"),d=!1,"no-speech"==e.error&&(c.placeholder=uvsMessages.unableToHear,uvsAudioPlayer.configure(uvsAlternativeResponse.notAudible),uvsAudioPlayer.play(),P=!0),"audio-capture"==e.error&&(c.placeholder=uvsMessages.micNotAccessible,P=!0),"not-allowed"==e.error&&(c.placeholder=uvsMessages.browserDenyMicAccess,A.style.setProperty("color","white"),P=!0)},L.onend=function(){l&&C()},L.onresult=function(e){let t="";if(void 0===e.results)return L.onend=null,L.stop(),c.placeholder=uvsMessages.unableToHear,uvsAudioPlayer.configure(uvsAlternativeResponse.micConnect),void uvsAudioPlayer.play();for(var s=e.resultIndex;s<e.results.length;++s)e.results[s].isFinal?(x=e.results[s][0].transcript,0==l&&(C(),L.stop())):(t+=e.results[s][0].transcript,c.value=t)},A.addEventListener(o,function(e){if(!0!==u(A.getAttribute("id"))){var i=document.getElementById("universal-voice-search-button"+n),r=i.className;null!=r&&-1!=r.indexOf("listening")||(a=setInterval(function(){var e=i.className;null!=e&&-1!=e.indexOf("listening")&&i.click(),s(a),a=!1},t)),d?(uvsAudioPlayer.isPlaying()&&uvsAudioPlayer.stop(),0==l&&(C(),L.stop())):(A.classList.add("listening"),e.preventDefault(),uvsAudioPlayer.isPlaying()&&uvsAudioPlayer.stop(),c.value=R="",d=!0,L.lang=uvsSttLanguageContext.gcp.stt?uvsSttLanguageContext.gcp.langCode:"en-US",L.start(),P=!1)}})}else A.addEventListener(o,function(i){function r(){if("undefined"==typeof uvsXApiKey||null===uvsXApiKey)return uvsAudioPlayer.configure(uvsAlternativeResponse.unavailable),uvsAudioPlayer.play(),!1;var u=document.getElementById("universal-voice-search-button"+n),r=u.className;if(null!=r&&-1!=r.indexOf("listening")||(a=setInterval(function(){var e=u.className;null!=e&&-1!=e.indexOf("listening")&&u.click(),s(a),a=!1},t)),d)return s(a),uvsAudioRecorder.stop(),uvsStopAudio(),uvsAudioPlayer.isPlaying()&&uvsAudioPlayer.stop(),A.classList.remove("listening"),A.style.setProperty("color","white"),c.placeholder=uvsMessages.transcribeText,uvsAudioRecorder.getBuffers(function(t){uvsSttLanguageContext.ibm.stt?uvsAudioRecorder.exportWAV(function(t){uvsRecIndex++,stt(t,!1,function(t){void 0!==t&&0!=t.length?(c.value=t,uvsAudioPlayer.configure(uvsAlternativeResponse.basic,function(){e.submit()}),uvsAudioPlayer.play()):(uvsAudioPlayer.configure(uvsAlternativeResponse.notAudible),uvsAudioPlayer.play(),c.placeholder=uvsMessages.ask)})}):uvsSttLanguageContext.gcp.stt?uvsAudioRecorder.exportMonoWAV(function(t){uvsAudioRecorder.convertBlobToBase64(t).then(function(t){uvsGcpStt(t).then(function(t){c.value=t,uvsAudioPlayer.configure(uvsAlternativeResponse.basic,function(){e.submit()}),uvsAudioPlayer.play()}).catch(function(e){uvsAudioPlayer.configure(uvsAlternativeResponse.notAudible),uvsAudioPlayer.play(),c.placeholder=uvsMessages.ask})}).catch(function(e){uvsAudioPlayer.configure(uvsAlternativeResponse.notAudible),uvsAudioPlayer.play(),c.placeholder=uvsMessages.ask})}):(uvsAudioPlayer.configure(uvsAlternativeResponse.notAudible),uvsAudioPlayer.play(),c.placeholder=uvsMessages.ask)}),void(d=!1);A.classList.add("listening"),i.preventDefault(),uvsAudioPlayer.isPlaying()&&uvsAudioPlayer.stop(),c.value=R="",d=!0,uvsAudioRecorder.clear(),uvsAudioRecorder.record(u)}!0!==u(A.getAttribute("id"))&&(uvsAudioRecorder&&uvsAudioContext?r():uvsInitAudio(function(e){if(!uvsAudioRecorder||!uvsAudioContext)return alert(uvsMessages.cantAccessMicrophone),!1;r()}))},!1)}catch(e){}}),uvsFloatingMic&&"yes"===uvsFloatingMic){let s=document.createDocumentFragment(),i=document.createElement("div"),n="uvs-widget-wrapper-middle-right",r="uvs-widget-chat-wrapper-middle-right";switch(uvsSelectedMicPosition?uvsSelectedMicPosition.toLowerCase():"middle right"){case"middle left":n="uvs-widget-wrapper-middle-left",r="uvs-widget-chat-wrapper-middle-left";break;case"top right":n="uvs-widget-wrapper-top-right",r="uvs-widget-chat-wrapper-top-right";break;case"top left":n="uvs-widget-wrapper-top-left",r="uvs-widget-chat-wrapper-top-left";break;case"bottom right":n="uvs-widget-wrapper-bottom-right",r="uvs-widget-chat-wrapper-bottom-right";break;case"bottom left":n="uvs-widget-wrapper-bottom-left",r="uvs-widget-chat-wrapper-bottom-left";break;default:n="uvs-widget-wrapper-middle-right",r="uvs-widget-chat-wrapper-middle-right"}i.setAttribute("class","uvs-widget-wrapper "+n);let a=document.createElement("div");a.setAttribute("class","uvs-widget-chat-wrapper "+r);let c=document.createElement("div");c.setAttribute("class","uvs-widget-field");let d=document.createElement("a");d.setAttribute("id","uvsWidgetMic"),d.setAttribute("class","uvs-widget-button");let v=document.createElement("img");v.setAttribute("src",uvsImagesPath+"uvs-widget-mic-black.svg"),d.appendChild(v);let f=document.createElement("a");f.setAttribute("id","uvsWidgetSearchBtn");let m=document.createElement("button");m.setAttribute("class","uvs-widget-form-submit-btn"),m.setAttribute("type","submit"),m.setAttribute("alt","Go"),m.setAttribute("title","Search"),f.appendChild(m);let h=document.createElement("form");h.setAttribute("class","uvs-widget-form"),null!==p?(h.action=p.action,h.method=p.method):(h.action=uvsGetCurrentHostURL()+"/",h.method="get");let b=document.createElement("input");b.setAttribute("id","uvsWidgetSearch"),b.setAttribute("class","uvs-widget-search uvs-widget-search-text"),b.setAttribute("name","uvs-widget-search"),b.setAttribute("placeholder",uvsWidgetMessages.placeholder),b.setAttribute("name","s"),h.appendChild(b),h.appendChild(f),c.appendChild(d),c.appendChild(h),a.appendChild(c);let y=document.createElement("a");y.setAttribute("id","uvsWidgetToggleButton"),y.setAttribute("class","uvs-widget-button");let w=document.createElement("div");w.setAttribute("class","uvs-widget-icon uvs-widget-toggle-button uvs-toggle-btn-mic"),y.appendChild(w),i.appendChild(a),i.appendChild(y),s.appendChild(i),document.body.appendChild(s),y.addEventListener("click",function(e){A(".uvs-widget-toggle-button","uvs-toggle-btn-mic"),A(".uvs-widget-toggle-button","uvs-toggle-btn-close"),A(".uvs-widget-toggle-button","uvs-widget-active"),A(".uvs-widget-toggle-button","uvs-widget-visible"),A("#uvsWidgetToggleButton","uvs-widget-float"),A(".uvs-widget-chat-wrapper","uvs-widget-visible"),A(".uvs-widget-button","uvs-widget-visible")});let P,R="",x=!1,L="";if("webkitSpeechRecognition"in window&&!1===uvsSttLanguageContext.ibm.stt){let s=new webkitSpeechRecognition;function g(){x=!1,P||(R=L,d.classList.remove("listening"),void 0!==R&&0!=R.length?(b.value=R,uvsAudioPlayer.configure(uvsAlternativeResponse.basic,function(){h.submit()}),uvsAudioPlayer.play()):(uvsAudioPlayer.configure(uvsAlternativeResponse.notAudible),uvsAudioPlayer.play(),b.placeholder=uvsMessages.ask))}s.continuous=!0,s.interimResults=!0,s.onstart=function(){x=!0},s.onerror=function(e){d.classList.remove("listening"),x=!1,"no-speech"==e.error&&(uvsAudioPlayer.configure(uvsAlternativeResponse.notAudible),uvsAudioPlayer.play(),P=!0,b.placeholder=uvsMessages.unableToHear),"audio-capture"==e.error&&(P=!0,b.placeholder=uvsMessages.micNotAccessible),"not-allowed"==e.error&&(P=!0,b.placeholder=uvsMessages.browserDenyMicAccess)},s.onend=function(){l&&g()},s.onresult=function(e){let t="";if(void 0===e.results)return s.onend=null,s.stop(),b.placeholder=uvsMessages.unableToHear,uvsAudioPlayer.configure(uvsAlternativeResponse.micConnect),void uvsAudioPlayer.play();let i=e.results.length;for(let u=e.resultIndex;u<i;++u)e.results[u].isFinal?(L=e.results[u][0].transcript,0==l&&(g(),s.stop())):t+=e.results[u][0].transcript},d.addEventListener(o,function(i){if(!0===u(d.getAttribute("id")))return;let n=d.className;var r,o,a;null!=n&&-1!=n.indexOf("listening")||(r=e+=1,o=d,a=t,new Promise(function(t){setTimeout(function(){var s=o.className;null!=s&&-1!=s.indexOf("listening")&&r==e&&o.click(),t("resolved")},a)})),x?(uvsAudioPlayer.isPlaying()&&uvsAudioPlayer.stop(),0==l&&(g(),s.stop())):(d.classList.add("listening"),i.preventDefault(),uvsAudioPlayer.isPlaying()&&uvsAudioPlayer.stop(),R="",x=!0,s.lang=uvsSttLanguageContext.gcp.stt?uvsSttLanguageContext.gcp.langCode:"en-US",s.start(),P=!1)})}else d.addEventListener(o,function(s){function i(){if("undefined"==typeof uvsXApiKey||null===uvsXApiKey)return uvsAudioPlayer.configure(uvsAlternativeResponse.unavailable),uvsAudioPlayer.play(),!1;let i=d.className;var u,n,r;if(null!=i&&-1!=i.indexOf("listening")||(u=e+=1,n=d,r=t,new Promise(function(t){setTimeout(function(){var s=n.className;null!=s&&-1!=s.indexOf("listening")&&u==e&&d.click(),t("resolved")},r)})),x)return uvsAudioRecorder.stop(),uvsStopAudio(),uvsAudioPlayer.isPlaying()&&uvsAudioPlayer.stop(),d.classList.remove("listening"),b.placeholder=uvsMessages.transcribeText,uvsAudioRecorder.getBuffers(function(e){uvsSttLanguageContext.ibm.stt?uvsAudioRecorder.exportWAV(function(e){uvsRecIndex++,stt(e,!1,function(e){void 0!==e&&0!=e.length?(b.value=e,uvsAudioPlayer.configure(uvsAlternativeResponse.basic,function(){h.submit()}),uvsAudioPlayer.play()):(uvsAudioPlayer.configure(uvsAlternativeResponse.notAudible),uvsAudioPlayer.play(),b.placeholder=uvsMessages.ask)})}):uvsSttLanguageContext.gcp.stt?uvsAudioRecorder.exportMonoWAV(function(e){uvsAudioRecorder.convertBlobToBase64(e).then(function(e){uvsGcpStt(e).then(function(e){b.value=e,uvsAudioPlayer.configure(uvsAlternativeResponse.basic,function(){h.submit()}),uvsAudioPlayer.play()}).catch(function(e){uvsAudioPlayer.configure(uvsAlternativeResponse.notAudible),uvsAudioPlayer.play(),b.placeholder=uvsMessages.ask})}).catch(function(e){uvsAudioPlayer.configure(uvsAlternativeResponse.notAudible),uvsAudioPlayer.play(),b.placeholder=uvsMessages.ask})}):(uvsAudioPlayer.configure(uvsAlternativeResponse.notAudible),uvsAudioPlayer.play(),b.placeholder=uvsMessages.ask)}),void(x=!1);d.classList.add("listening"),s.preventDefault(),uvsAudioPlayer.isPlaying()&&uvsAudioPlayer.stop(),R="",x=!0,uvsAudioRecorder.clear(),uvsAudioRecorder.record(d)}!0!==u(d.getAttribute("id"))&&(uvsAudioRecorder&&uvsAudioContext?i():uvsInitAudio(function(e){if(!uvsAudioRecorder||!uvsAudioContext)return b.placeholder=uvsMessages.micNotAccessible,!1;i()}))},!1);function A(e,t){if(void 0===e||null==e||0==e.length)return!1;let s=document.querySelector(e);if(s.classList)s.classList.toggle(t);else{let e=s.className.split(" "),i=e.indexOf(t);i>=0?e.splice(i,1):(e.push(t),s.className=e.join(" "))}}}}();
  • universal-voice-search/trunk/js/uvs.audio-input-handler.js

    r2176461 r2289691  
    1414uvsInputPoint       = null,
    1515uvsAudioRecorder    = null;
    16 var uvsRecIndex = 0;
    17 var uvsToken    = "";
    18 var initCB      = null;
    19 let uvsStream   = null;
     16var uvsRecIndex     = 0;
     17var initCB          = null;
     18let uvsStream       = null;
    2019
    21 function uvsGetToken() {
    22     if (!(typeof(uvsXApiKey) != 'undefined' && uvsXApiKey !== null)) return;
     20/**
     21 * Function to initialize capture audio resources
     22 *
     23 * @param { cb: function } A callback function
     24 */
     25function uvsInitAudio(cb) {
     26    initCB = cb;
    2327
    2428    // Check when last service log was updated
     
    4246        // do nothing
    4347    }
     48   
     49    uvsAudioContext = new AudioContext();
    4450
    45     // Check if token locally preserved. If yes then get it locally.
    46     var locallyPreservedToken = uvsGetLocallyPreservedToken();
    47 
    48     if (typeof(locallyPreservedToken) != 'undefined'
    49         && locallyPreservedToken !== null
    50         && locallyPreservedToken.length != 0) {
    51         uvsToken = locallyPreservedToken;
    52         return;
    53     }
    54 
    55     var xhttp = new XMLHttpRequest();
    56     xhttp.onreadystatechange = function () {
    57         if (this.readyState == 4 && this.status == 200) {
    58             //alert(this.responseText);
    59             var res = JSON.parse(this.responseText);
    60             uvsToken = res.token;
    61             // Preserve token locally
    62             uvsPreserveToken(uvsToken);
     51    navigator.mediaDevices.getUserMedia({ "audio": !0 })
     52        .then(uvsGotStream)
     53        .catch(function (e) {
     54            console.log("VF: We caught en error while gaining access to audio input due to: ", e.message);
    6355        }
    64     };
    65 
    66     try {
    67         xhttp.open("GET", uvsTokenApiUrl, true);
    68         xhttp.setRequestHeader("Content-type", "application/json");
    69         xhttp.setRequestHeader("x-api-key", uvsXApiKey);
    70         xhttp.send();
    71     } catch(err) {
    72         console.log('We had an error while availing token. Error:' + err.message);
    73     }
     56    );
    7457}
    7558
     59/**
     60 * A callback function to obtain audio stream
     61 *
     62 * @param { stream: MediaStream } An audio track
     63 */
    7664function uvsGotStream(stream) {
    7765    uvsInputPoint = uvsAudioContext.createGain();
     
    8270    uvsAudioInput     = uvsRealAudioInput;
    8371    uvsAudioInput.connect(uvsInputPoint);
    84    
     72
    8573    uvsAudioRecorder = new Recorder(uvsInputPoint);
    8674    initCB(uvsAudioRecorder);
    87 }
    88 
    89 function uvsInitAudio(cb) {
    90     uvsGetToken();
    91     initCB = cb;
    92     uvsAudioContext = new AudioContext();
    93 
    94     navigator.mediaDevices.getUserMedia({ "audio": !0 })
    95         .then(uvsGotStream)
    96         .catch(function (e) {
    97             console.log("We caught en error while gaining access to audio input", e.message);
    98         }
    99     );
    10075}
    10176
  • universal-voice-search/trunk/js/uvs.audio-input-handler.min.js

    r2176461 r2289691  
    1 window.AudioContext=window.AudioContext||window.webkitAudioContext;var uvsAudioContext=null;var uvsAudioInput=null,uvsRealAudioInput=null,uvsInputPoint=null,uvsAudioRecorder=null;var uvsRecIndex=0;var uvsToken="";var initCB=null;let uvsStream=null;function uvsGetToken(){if(!(typeof(uvsXApiKey)!='undefined'&&uvsXApiKey!==null))return;try{let uvsLastUpdatedAtTimestamp=uvsServiceLogs.updatedAt||null;if(uvsLastUpdatedAtTimestamp!==null){uvsLastUpdatedAtTimestamp=Number(uvsLastUpdatedAtTimestamp);let currentUtcTimestamp=Math.round(new Date().getTime()/1000);uvsLastUpdatedAtTimestamp=uvsLastUpdatedAtTimestamp+(24*3600);if(currentUtcTimestamp>=uvsLastUpdatedAtTimestamp){uvsLogServiceCall(1)}}}catch(err){}
    2 var locallyPreservedToken=uvsGetLocallyPreservedToken();if(typeof(locallyPreservedToken)!='undefined'&&locallyPreservedToken!==null&&locallyPreservedToken.length!=0){uvsToken=locallyPreservedToken;return}
    3 var xhttp=new XMLHttpRequest();xhttp.onreadystatechange=function(){if(this.readyState==4&&this.status==200){var res=JSON.parse(this.responseText);uvsToken=res.token;uvsPreserveToken(uvsToken)}};try{xhttp.open("GET",uvsTokenApiUrl,!0);xhttp.setRequestHeader("Content-type","application/json");xhttp.setRequestHeader("x-api-key",uvsXApiKey);xhttp.send()}catch(err){console.log('We had an error while availing token. Error:'+err.message)}}
    4 function uvsGotStream(stream){uvsInputPoint=uvsAudioContext.createGain();uvsStream=stream;uvsRealAudioInput=uvsAudioContext.createMediaStreamSource(stream);uvsAudioInput=uvsRealAudioInput;uvsAudioInput.connect(uvsInputPoint);uvsAudioRecorder=new Recorder(uvsInputPoint);initCB(uvsAudioRecorder)}
    5 function uvsInitAudio(cb){uvsGetToken();initCB=cb;uvsAudioContext=new AudioContext();navigator.mediaDevices.getUserMedia({"audio":!0}).then(uvsGotStream).catch(function(e){console.log("We caught en error while gaining access to audio input",e.message)})}
    6 function uvsStopAudio(){try{uvsStream.getTracks().forEach(function(track){track.stop()});uvsAudioContext.close();uvsAudioContext=null}catch(err){console.log('UVS Exception: Unable to release audio resource due to: '+err.message)}}
     1window.AudioContext=window.AudioContext||window.webkitAudioContext;var uvsAudioContext=null,uvsAudioInput=null,uvsRealAudioInput=null,uvsInputPoint=null,uvsAudioRecorder=null,uvsRecIndex=0,initCB=null;let uvsStream=null;function uvsInitAudio(u){initCB=u;try{let u=uvsServiceLogs.updatedAt||null;if(null!==u){u=Number(u),Math.round((new Date).getTime()/1e3)>=(u+=86400)&&uvsLogServiceCall(1)}}catch(u){}uvsAudioContext=new AudioContext,navigator.mediaDevices.getUserMedia({audio:!0}).then(uvsGotStream).catch(function(u){console.log("VF: We caught en error while gaining access to audio input due to: ",u.message)})}function uvsGotStream(u){uvsInputPoint=uvsAudioContext.createGain(),uvsStream=u,uvsRealAudioInput=uvsAudioContext.createMediaStreamSource(u),(uvsAudioInput=uvsRealAudioInput).connect(uvsInputPoint),uvsAudioRecorder=new Recorder(uvsInputPoint),initCB(uvsAudioRecorder)}function uvsStopAudio(){try{uvsStream.getTracks().forEach(function(u){u.stop()}),uvsAudioContext.close(),uvsAudioContext=null}catch(u){console.log("UVS Exception: Unable to release audio resource due to: "+u.message)}}
  • universal-voice-search/trunk/js/uvs.speech-handler.js

    r2196945 r2289691  
    1111
    1212var respTimeOut = false;
    13 var errcnt    = 0;
    14 var myStatus  = {};
    15 var myContext = {};
    16 var voice     = undefined;
    17 var win1      = -1;
    18 var win2      = -1;
    19 var isTalking = false;
    20 var isLoaded  = false;
    21 var lang      = uvsSelectedLang;
    22 
     13var errcnt = 0;
    2314let uvsHostName = typeof(uvsCurrentHostName) != 'undefined' ? uvsCurrentHostName : null;
    2415
    25 var uvsPreservedText = null, uvsPreservedCallback = null, uvsVoicesPopulated = false;
    26 
    27 var uvsDummySpeakButton = document.createElement('button');
    28 uvsDummySpeakButton.setAttribute('type', 'button');
    29 
    30 /**
    31  * Function to get availale list of voices in the browser
    32  */
    33 function uvsPopulateVoiceList() {
    34     var speechSynthesis = window.speechSynthesis;
    35 
    36     if (typeof speechSynthesis === 'undefined') { return; }
    37 
    38     voices = speechSynthesis.getVoices();
    39 
    40     // Local function to get specific voice from available voices in browser
    41     var uvsGetVoice = function(uvsVoices, uvsVoiceName = null, uvsObjProp = 'name'){
    42         var uvsFoundedVoice = null;
     16/**
     17 * An audio player handler Object
     18 *
     19 */
     20var uvsAudioPlayer = {
     21    'htmlAudioElement': document.createElement('AUDIO'),
     22    'lastFilePath': null,
     23    'antiMuteButtonPlaybacks': [uvsSilenceSoundPath],
     24    'isAntiMutePlayback': false,
     25    'configure': function(filePath = null, playbackEndedCallback = null) {
    4326        try {
    44             for (uvsI = 0; uvsI < uvsVoices.length; uvsI++) {
    45                 if (uvsVoices[uvsI][uvsObjProp].indexOf(uvsVoiceName) != -1) {
    46                     uvsFoundedVoice = uvsVoices[uvsI];
    47                     break;
     27            let pathOfFile = typeof filePath != 'undefined' && filePath ? filePath : null;
     28
     29            if (pathOfFile) {
     30                this.htmlAudioElement.src = _uvsPath + pathOfFile;
     31                this.htmlAudioElement.preload = 'auto';
     32                this.lastFilePath = pathOfFile;
     33
     34                if (this.antiMuteButtonPlaybacks.indexOf(pathOfFile) !== -1) {
     35                    this.isAntiMutePlayback = true;
     36                } else {
     37                    this.isAntiMutePlayback = false;
    4838                }
    49             }
    50         } catch (err) {
    51             uvsFoundedVoice = null;
    52         }
    53 
    54         return uvsFoundedVoice;
    55     };
    56 
    57     //$$$$$$ AS OF NOW (2019 FIRST QUARTER) FIREFOX ON LINUX ONLY SUPPORT ROBOTIC MALE VOICE
    58     //$$$$$$ THEREFORE THERE WILL ALWAYS BE A MALE VOICE ON DESKTOP LINUX AND ANDROID DEVICES
    59     switch (uvsTypeOfSelectedLanguage.toLowerCase()) {
    60         case 'german':
    61             // Windows OS
    62             voice = uvsGetVoice(voices, 'Hedda');
    63 
    64             //Chrome Browser
    65             if (typeof (voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'Google Deutsch'); }
    66 
    67             // Everything else
    68             if (typeof (voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'German'); }
    69             if (typeof (voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'german'); }
    70             if (typeof (voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'de-DE', 'lang'); }
    71             if (typeof (voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'de-DE', 'languageCode'); }
    72             if (typeof (voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'de-DE'); }
    73 
    74             break;
    75 
    76         case 'british english':
    77             // On Windows not Available
    78             // Browsers on Mac and iOS
    79             if (typeof(voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'Daniel'); } // en-GB
    80             // Linux Chrome
    81             if (typeof(voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'Google UK English Male'); }
    82             // Linux Firefox
    83             if (typeof(voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'english_rp'); } // en-GB
    84             //Android chrome
    85             if (typeof(voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'English United Kingdom'); } // en-GB
    86             if (typeof(voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'en_GB', 'lang'); }
    87             //Android Firefox
    88             if (typeof(voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'English (United Kingdom)'); } // en-GB
    89            
    90             break;
    91        
    92         default:
    93             // Do nothing for now
    94     }
    95 
    96     if (typeof(voice) == 'undefined' || voice === null) {
    97         // Browsers on Windows OS
    98         voice = uvsGetVoice(voices, 'David');
    99 
    100 
    101         // Browsers on Mac and iOS
    102         if (typeof(voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'Alex')}; // en-US
    103         if (typeof(voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'Fred')}; // en-US
    104         if (typeof(voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'Daniel')}; // en-GB
    105 
    106         // Firefox browser on Linux
    107         if (typeof(voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'english-us')}; // en-US
    108         if (typeof(voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'english_rp')}; // en-GB
    109        
    110         // Chrome Browser on any platform
    111         if (typeof(voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'Google UK English Male')};
    112     }
    113 
    114     if (!(typeof(voice) != 'undefined' && voice !== null)) {
    115         voice = uvsGetVoice(voices, 'en-US', 'lang');
    116        
    117         if (typeof(voice) == 'undefined' || voice === null) { voice = uvsGetVoice(voices, 'en_US', 'lang')}; // en_US (For android)
    118     }
    119 }
    120 
    121 uvsPopulateVoiceList();
    122 
    123 // Handle asynch behavior of Chrome browser to populate voice
    124 if (typeof speechSynthesis !== 'undefined' && speechSynthesis.onvoiceschanged !== undefined) {
    125     speechSynthesis.onvoiceschanged = function() {
    126         uvsVoicesPopulated = true;
    127         uvsPopulateVoiceList();
    128 
    129         if (typeof(uvsPreservedText) != 'undefined' && uvsPreservedText !== null) {
    130             tts(uvsPreservedText, uvsPreservedCallback);
    131         }
    132 
    133         uvsPreservedText = null;
    134         uvsPreservedCallback = null;
    135     }
    136 }
     39            } else {
     40                this.htmlAudioElement.src = '';
     41                this.isAntiMutePlayback = false;
     42            }
     43
     44            /**
     45             * The play event occurs when the audio has been started or is no longer paused.
     46             */
     47            this.htmlAudioElement.onplay = function() {
     48                // Do nothing for now
     49            }.bind(this);
     50
     51            /**
     52             * The ended event occurs when the audio has reached the end.
     53             */
     54            this.htmlAudioElement.onended = function() {
     55                this.htmlAudioElement.src = ''
     56                this.isAntiMutePlayback = false;
     57
     58                // Callback to be executed when video playback ends
     59                if (pathOfFile && (typeof playbackEndedCallback === "function")) {
     60                    playbackEndedCallback();
     61                    playbackEndedCallback = null;
     62                }
     63            }.bind(this);
     64
     65            /**
     66             * The error event occurs when an error occurred during the loading of an audio
     67             */
     68            this.htmlAudioElement.onerror = function() {
     69                this.isAntiMutePlayback = false;
     70            }.bind(this);
     71
     72            /**
     73             * The playing event occurs when the audio is playing after having been paused or stopped for buffering.
     74             */
     75            this.htmlAudioElement.onplaying = function() {
     76                // Do nothing for now
     77            }.bind(this);
     78        } catch (err) {
     79            this.clear();
     80            this.isAntiMutePlayback = false;
     81        }
     82    },
     83    'play': function() {
     84        try {
     85            if (this.htmlAudioElement && !!this.htmlAudioElement.src) {
     86                this.htmlAudioElement.play().catch(function(error){
     87                    console.log('VDN Exception: Failed to play audio.');
     88                });
     89            }
     90        } catch (err) {
     91            this.clear();
     92        }
     93    },
     94    'stop': function() {
     95        try {
     96            this.clear();
     97        } catch (err) {
     98            this.clear();
     99        }
     100    },
     101    'clear': function() {
     102        try {
     103            if (this.htmlAudioElement) {
     104                let duration = isNaN(this.htmlAudioElement.duration) ? 0 : this.htmlAudioElement.duration;
     105                this.htmlAudioElement.currentTime = duration;
     106            }
     107
     108            this.lastFilePath = null;
     109        } catch (err) {
     110            this.lastFilePath = null;
     111            this.isAntiMutePlayback = false;
     112        }
     113    },
     114    'isPlaying': function() {
     115        let currentTime = isNaN(this.htmlAudioElement.currentTime) ? 0 : this.htmlAudioElement.currentTime;
     116        let duration = isNaN(this.htmlAudioElement.duration) ? 0 : this.htmlAudioElement.duration;
     117
     118        return currentTime < duration;
     119    }
     120};
    137121
    138122function stt(blob, errorRecovery, cb) {
     123    if (!(!!uvsSttLanguageContext['ibm']['endPoint'] && !!uvsSttLanguageContext['ibm']['token'] && !!uvsSttLanguageContext['ibm']['model'])) {
     124        if (typeof cb  == 'function') cb(null);
     125        return;
     126    }
     127   
    139128    if (errorRecovery == false) {
    140129        let i = Math.floor(Math.random() * 10);
     
    142131       
    143132        if (respTimeOut == false) {
    144             tts(resp[i], function () { });
     133            // Play 'random' playback
     134            uvsAudioPlayer.configure(resp[i]);
     135            uvsAudioPlayer.play();
     136
    145137            respTimeOut = true;
    146138           
     
    150142        }
    151143    }
    152 
    153     var wsURI           = uvsWebSocketUrl.url + uvsWebSocketUrl.tokenQs + uvsToken + uvsWebSocketUrl.otherQs;
     144    let url = uvsSttLanguageContext['ibm']['endPoint'];
     145    let qs = uvsSttLanguageContext['ibm']['qs']['token'] + uvsSttLanguageContext['ibm']['token'] + uvsSttLanguageContext['ibm']['qs']['model'] + uvsSttLanguageContext['ibm']['model'];
     146
     147    var wsURI           = url + qs;
    154148    var websocket       = new WebSocket(wsURI);
    155149    websocket.onopen    = function (evt) { onOpen(evt) };
     
    204198        websocket.close();
    205199
    206         if (!(typeof(uvsXApiKey) != 'undefined' && uvsXApiKey !== null)) { return; }
     200        if (!(typeof(uvsXApiKey) != 'undefined' && uvsXApiKey !== null)) return;
    207201
    208202        if (errcnt < 2) {
    209203            //$$$$$$$$$$$$$$$ FETCH NEW TOKEN MIGHT HAVE EXPIRED $$$$$$$$$$$$$$$$$$
    210             let xhttp = new XMLHttpRequest();
    211            
    212             xhttp.onreadystatechange = function () {
    213                 if (this.readyState == 4 && this.status == 200) {
    214                     let res = JSON.parse(this.responseText);
    215                     uvsToken   = res.token;
    216 
    217                     // Preserve token locally
    218                     uvsPreserveToken(uvsToken);
    219 
    220                     stt(blob,true,cb);
     204            uvsRefreshVoiceServicesKeys().then(function(result) {
     205                uvsSttLanguageContext['ibm']['token'] = result;
     206                stt(blob,true,cb);
     207            }).catch(function(error) {
     208                alert(error);
     209            });
     210        } else {
     211            if (typeof cb  == 'function') cb(null);
     212        }
     213    }
     214
     215    function onClose(evt) { /* do nothing for now*/ }
     216}
     217
     218/**
     219 * Function to make asynch call to GCP server for STT
     220 *
     221 * @param String base64AudioStr  Base64 String representation of Audio Blob
     222 * @retur Promise
     223 *
     224 */
     225function uvsGcpStt(base64AudioStr) {
     226    return new Promise(function(resolve, reject){
     227        if (!(
     228            !!uvsSttLanguageContext['gcp']['endPoint'] &&
     229            !!uvsSttLanguageContext['gcp']['key'] &&
     230            !!uvsSttLanguageContext['gcp']['langCode'] &&
     231            typeof base64AudioStr != 'undefined' &&
     232            !!base64AudioStr
     233            ))
     234        {
     235            reject(null);
     236            return;
     237        }
     238
     239        if (errcnt == 0) {
     240            let i = Math.floor(Math.random() * 10);
     241            let resp = uvsAlternativeResponse['randomLib'];
     242
     243            // Play 'random' playback
     244            uvsAudioPlayer.configure(resp[i]);
     245            uvsAudioPlayer.play();
     246        }
     247
     248        let uvsXhr = new XMLHttpRequest();
     249
     250        uvsXhr.onreadystatechange = function () {
     251            if (this.readyState == 4) {
     252                try {
     253                    let res = JSON.parse(this.response);
     254                   
     255                    if (this.status === 200) {
     256                        errcnt = 0;
     257                        let results = typeof res != 'undefined' && res instanceof Object && 'results' in res ? res['results'] : [];
     258                        let efficientResult = !!results && results.length > 0 && results[0] instanceof Object ? results[0] : {};
     259                        let alternatives = 'alternatives' in efficientResult && !!efficientResult['alternatives'] ? efficientResult['alternatives'] : [];
     260                        let alternativeObj = alternatives.length > 0 && alternatives[0] instanceof Object ? alternatives[0] : {};
     261                        let transcript = 'transcript' in alternativeObj && !!alternativeObj['transcript'] ? alternativeObj['transcript'] : null;
     262
     263                        if (typeof transcript != 'undefined' && !!transcript) {
     264                            resolve(transcript);
     265                        } else {
     266                            reject(null);
     267                        }
     268                    } else {
     269                        // Handle response errors
     270                        let error = 'error' in res ? res['error'] : {};
     271                        let message = 'message' in error && !!error['message'] ? error['message'].toLowerCase() : '';
     272
     273                        if (errcnt < 1 && !!message && message.indexOf('api key') !== -1) {
     274                            errcnt++;
     275
     276                            //$$$$$$$$$$$$$$$ FETCH NEW TOKEN MIGHT HAVE EXPIRED $$$$$$$$$$$$$$$$$$
     277                            uvsRefreshVoiceServicesKeys().then(function(result) {
     278                                uvsSttLanguageContext['gcp']['key'] = result;
     279
     280                                // Try to transcript again with updated key
     281                                uvsGcpStt().then(function(res){
     282                                    if (!!res) {
     283                                        resolve(res);
     284                                    } else {
     285                                        errcnt = 0;
     286                                        reject(null);
     287                                    }
     288                                }).catch(function(err){
     289                                    errcnt = 0;
     290                                    reject(null);
     291                                })
     292                            }).catch(function(error) {
     293                                alert(error);
     294                                errcnt = 0;
     295                                reject(null);
     296                            });
     297                        } else {
     298                            errcnt = 0;
     299                            reject(null);
     300                        }
     301                    }
     302                } catch(err) {
     303                    reject(null);
    221304                }
    222             };
    223 
    224             try {
    225                 xhttp.open("GET", uvsTokenApiUrl, true);
    226                 xhttp.setRequestHeader("Content-type", "application/json");
    227                 xhttp.setRequestHeader("x-api-key", uvsXApiKey);
    228                 xhttp.send();
    229             } catch(err) {
    230                 console.log('We had an error while availing expired token agina. Error:' + err.message);
    231             }
    232         }
    233     }
    234 
    235     function onClose(evt) { /* do nothing for now*/ }
    236 }
    237 
    238 function tts (text, callback) {
    239     let u = new SpeechSynthesisUtterance();
    240     let speechSynthesis = window.speechSynthesis;
    241    
    242     try {
    243         var l = document.getElementById("l1");
    244 
    245         if (l) { l.textContent = text; }
    246     } catch (err) {
    247         // Do nothing
    248     }
    249 
    250     u.text = text;
    251     u.lang = lang;
    252 
    253     if (voice != 'undefined' && voice != null) { u.voice = voice; }
    254 
    255     if (uvsVoicesPopulated === false && voice === null) {
    256         uvsPreservedText = text;
    257         uvsPreservedCallback = callback;
    258         return;
    259     } else {
    260         uvsVoicesPopulated = false;
    261     }
    262 
    263     u.onend = function () {
    264         isTalking = false;
     305            }
     306        }
     307
     308        // Handle parsing or transmission errors
     309        uvsXhr.onerror = function(error) { reject(null); }
    265310       
    266         if (callback) { callback(); }
    267     };
    268 
    269     u.onerror = function (e) {
    270         // In chrome 71 and above If page is reloaded or user have not yet
    271         // interacted with page then 'not-allowed' constraint imposed.
    272         if (typeof(e.type) != 'undefined' && typeof(e.error) != 'undefined'
    273             && e.type == 'error' && e.error == 'not-allowed') {
    274             isTalking = false;
    275             console.log('speechSynthesis not available');
    276             return;
    277         }
    278 
    279         if (callback) {
    280             //alert("Unable to speak!");
    281             callback(e);
    282         }
    283     };
    284 
    285     // Starting in Chrome 71, the speech synthesis API now requires some kind of user activation on the page
    286     // before it’ll work. This brings it in line with other autoplay policies.
    287     // If you try to use it before the user has interacted with the page, it will fire an error.
    288     try {
    289         isTalking = true;
    290         uvsDummySpeakButton.onclick = function() { speechSynthesis.speak(u) };
    291         uvsDummySpeakButton.click();
    292     } catch (err) {
    293         console.log('uvs: speechSynthesis not available. Error:' + err.message);
    294     }
    295 }
    296 
    297 function tts_stop() {
    298     speechSynthesis.cancel();
    299 }
    300 
    301 /**
    302  * Function to locally preserve token
    303  *
    304  * @param uvsToken - string : Token
    305  */
    306 function uvsPreserveToken(uvsThisToken = null) {
    307     try {
    308         if (uvsThisToken === null) return;
    309 
    310         var currentUtcTimestamp = Math.round(new Date().getTime()/1000);
    311         uvsThisToken = uvsThisToken + '_uvs_ts_' + currentUtcTimestamp;
    312 
    313         window.localStorage.setItem('uvsToken', uvsThisToken);
    314     } catch (err) {
    315         console.log('uvs: Not able to preserve token. Error:' + err.message);
    316     }
    317 }
    318 
    319 /**
    320  * Function to retrieve a token from local storage
    321  *
    322  * @returns preservedToken - string: A token if preserved for more than 6 hours otherwise null.
    323  */
    324 function uvsGetLocallyPreservedToken() {
    325     var preservedToken = null;
    326 
    327     try {
    328         let localToken = window.localStorage.getItem('uvsToken');
    329 
    330         if (!(localToken !== null  && localToken.length > 0)) { return preservedToken; }
    331 
    332         let tokenData = localToken.split('_uvs_ts_');
    333 
    334         if (!(typeof(tokenData) != 'undefined' && tokenData !== null)) { return preservedToken; }
    335 
    336         if (tokenData.length < 2) { return preservedToken; }
    337 
    338         let tokenPreservanceTimestamp = tokenData[1];
    339         tokenPreservanceTimestamp     = Number(tokenPreservanceTimestamp);
    340         let currentUtcTimestamp       = Math.round(new Date().getTime()/1000);
    341 
    342         if (isNaN(tokenPreservanceTimestamp)) return preservedToken;
    343 
    344         // Add 6 hours to preservance time
    345         tokenPreservanceTimestamp = tokenPreservanceTimestamp + (6 * 3600);
    346 
    347         // Check if token has been preserved for more than 6 hours. If not then retrieve locally preserved token
    348         if (!(currentUtcTimestamp >= tokenPreservanceTimestamp)) {
    349             preservedToken = tokenData[0];
    350         } else {
    351             window.localStorage.removeItem('uvsToken');
    352         }
    353     } catch (err) {
    354         preservedToken = null;
    355     }
    356 
    357     return preservedToken;
     311        uvsXhr.open("POST", uvsSttLanguageContext['gcp']['endPoint'] + uvsSttLanguageContext['gcp']['qs']['key'] + uvsSttLanguageContext['gcp']['key'], true);
     312        uvsXhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
     313
     314        let recognitionConfig = {
     315            'config': {
     316                'encoding': 'ENCODING_UNSPECIFIED',
     317                'languageCode': uvsSttLanguageContext['gcp']['langCode'],
     318                'enableWordTimeOffsets': false,
     319            },
     320            'audio': {
     321                'content': base64AudioStr
     322            },
     323        };
     324
     325        uvsXhr.send(JSON.stringify(recognitionConfig, null, true));
     326    })
    358327}
    359328
     
    418387}
    419388
     389/**
     390 * Function to obtain voice services token and keys
     391 *
     392 */
     393function uvsRefreshVoiceServicesKeys() {   
     394    return new Promise(function(resolve, reject){
     395        let uvsXhr = new XMLHttpRequest();
     396
     397        uvsXhr.onreadystatechange = function () {
     398            if (this.readyState == 4) {
     399                if (this.status === 200) {
     400                    let res = JSON.parse(this.response);
     401
     402                    if (typeof res == 'undefined') reject(uvsErrorLibrary['outOfService']);
     403
     404                    if (!!uvsSttLanguageContext['ibm']['stt'] && 'token' in res && !!res['token']) {
     405                        resolve(res['token']);
     406                        return;
     407                    }
     408
     409                    if (!!uvsSttLanguageContext['gcp']['stt'] && 'gStt' in res && !!res['gStt']) {
     410                        resolve(res['gStt']);
     411                        return;
     412                    }
     413
     414                    reject(uvsErrorLibrary['outOfService']);
     415                } else {
     416                    // Handle response errors
     417                    reject(uvsErrorLibrary['outOfService']);
     418                }
     419            }
     420        };
     421
     422        let queryString = "?action=uvs_refresh_access_keys&_ajax_nonce=" + uvsAjaxObj.keys_nonce;
     423        uvsXhr.open("GET", uvsAjaxObj.ajax_url + queryString , true);
     424
     425        // Handle parsing or transmission errors
     426        uvsXhr.onerror = function(error) { reject(uvsErrorLibrary['outOfService']); }
     427       
     428        uvsXhr.send(null);
     429    });
     430}
     431
  • universal-voice-search/trunk/js/uvs.speech-handler.min.js

    r2196945 r2289691  
    1 if(typeof String.prototype.trim!=='function'){String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,'')}}
    2 var respTimeOut=!1;var errcnt=0;var myStatus={};var myContext={};var voice=undefined;var win1=-1;var win2=-1;var isTalking=!1;var isLoaded=!1;var lang=uvsSelectedLang;let uvsHostName=typeof(uvsCurrentHostName)!='undefined'?uvsCurrentHostName:null;var uvsPreservedText=null,uvsPreservedCallback=null,uvsVoicesPopulated=!1;var uvsDummySpeakButton=document.createElement('button');uvsDummySpeakButton.setAttribute('type','button');function uvsPopulateVoiceList(){var speechSynthesis=window.speechSynthesis;if(typeof speechSynthesis==='undefined'){return}
    3 voices=speechSynthesis.getVoices();var uvsGetVoice=function(uvsVoices,uvsVoiceName=null,uvsObjProp='name'){var uvsFoundedVoice=null;try{for(uvsI=0;uvsI<uvsVoices.length;uvsI++){if(uvsVoices[uvsI][uvsObjProp].indexOf(uvsVoiceName)!=-1){uvsFoundedVoice=uvsVoices[uvsI];break}}}catch(err){uvsFoundedVoice=null}
    4 return uvsFoundedVoice};switch(uvsTypeOfSelectedLanguage.toLowerCase()){case 'german':voice=uvsGetVoice(voices,'Hedda');if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'Google Deutsch')}
    5 if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'German')}
    6 if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'german')}
    7 if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'de-DE','lang')}
    8 if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'de-DE','languageCode')}
    9 if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'de-DE')}
    10 break;case 'british english':if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'Daniel')}
    11 if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'Google UK English Male')}
    12 if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'english_rp')}
    13 if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'English United Kingdom')}
    14 if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'en_GB','lang')}
    15 if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'English (United Kingdom)')}
    16 break;default:}
    17 if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'David');if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'Alex')};if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'Fred')};if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'Daniel')};if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'english-us')};if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'english_rp')};if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'Google UK English Male')}}
    18 if(!(typeof(voice)!='undefined'&&voice!==null)){voice=uvsGetVoice(voices,'en-US','lang');if(typeof(voice)=='undefined'||voice===null){voice=uvsGetVoice(voices,'en_US','lang')}}}
    19 uvsPopulateVoiceList();if(typeof speechSynthesis!=='undefined'&&speechSynthesis.onvoiceschanged!==undefined){speechSynthesis.onvoiceschanged=function(){uvsVoicesPopulated=!0;uvsPopulateVoiceList();if(typeof(uvsPreservedText)!='undefined'&&uvsPreservedText!==null){tts(uvsPreservedText,uvsPreservedCallback)}
    20 uvsPreservedText=null;uvsPreservedCallback=null}}
    21 function stt(blob,errorRecovery,cb){if(errorRecovery==!1){let i=Math.floor(Math.random()*10);let resp=uvsAlternativeResponse.randomLib;if(respTimeOut==!1){tts(resp[i],function(){});respTimeOut=!0;setTimeout(function(){respTimeOut=!1},6000)}}
    22 var wsURI=uvsWebSocketUrl.url+uvsWebSocketUrl.tokenQs+uvsToken+uvsWebSocketUrl.otherQs;var websocket=new WebSocket(wsURI);websocket.onopen=function(evt){onOpen(evt)};websocket.onclose=function(evt){onClose(evt)};websocket.onmessage=function(evt){onMessage(evt)};websocket.onerror=function(evt){onError(evt)};function onOpen(evt){uvsLogServiceCall();let message={'action':'start','content-type':'audio/wav','interim_results':!1,'max_alternatives':3,'smart_formatting':!0,};websocket.send(JSON.stringify(message));websocket.send(blob);websocket.send(JSON.stringify({'action':'stop'}))}
    23 function onMessage(evt){let res=JSON.parse(evt.data);if(res.results!=undefined){let msg="";var foundFinal=!1;for(var k in res.results){if(res.results[k].final==!0){msg=msg+res.results[k].alternatives[0].transcript;foundFinal=!0}}
    24 errcnt=0;if(foundFinal==!0||res.results.length==0){if(typeof(cb)==='function'){cb(msg)};websocket.close()}}}
    25 function onError(evt){errcnt++;websocket.close();if(!(typeof(uvsXApiKey)!='undefined'&&uvsXApiKey!==null)){return}
    26 if(errcnt<2){let xhttp=new XMLHttpRequest();xhttp.onreadystatechange=function(){if(this.readyState==4&&this.status==200){let res=JSON.parse(this.responseText);uvsToken=res.token;uvsPreserveToken(uvsToken);stt(blob,!0,cb)}};try{xhttp.open("GET",uvsTokenApiUrl,!0);xhttp.setRequestHeader("Content-type","application/json");xhttp.setRequestHeader("x-api-key",uvsXApiKey);xhttp.send()}catch(err){console.log('We had an error while availing expired token agina. Error:'+err.message)}}}
    27 function onClose(evt){}}
    28 function tts(text,callback){let u=new SpeechSynthesisUtterance();let speechSynthesis=window.speechSynthesis;try{var l=document.getElementById("l1");if(l){l.textContent=text}}catch(err){}
    29 u.text=text;u.lang=lang;if(voice!='undefined'&&voice!=null){u.voice=voice}
    30 if(uvsVoicesPopulated===!1&&voice===null){uvsPreservedText=text;uvsPreservedCallback=callback;return}else{uvsVoicesPopulated=!1}
    31 u.onend=function(){isTalking=!1;if(callback){callback()}};u.onerror=function(e){if(typeof(e.type)!='undefined'&&typeof(e.error)!='undefined'&&e.type=='error'&&e.error=='not-allowed'){isTalking=!1;console.log('speechSynthesis not available');return}
    32 if(callback){callback(e)}};try{isTalking=!0;uvsDummySpeakButton.onclick=function(){speechSynthesis.speak(u)};uvsDummySpeakButton.click()}catch(err){console.log('uvs: speechSynthesis not available. Error:'+err.message)}}
    33 function tts_stop(){speechSynthesis.cancel()}
    34 function uvsPreserveToken(uvsThisToken=null){try{if(uvsThisToken===null)return;var currentUtcTimestamp=Math.round(new Date().getTime()/1000);uvsThisToken=uvsThisToken+'_uvs_ts_'+currentUtcTimestamp;window.localStorage.setItem('uvsToken',uvsThisToken)}catch(err){console.log('uvs: Not able to preserve token. Error:'+err.message)}}
    35 function uvsGetLocallyPreservedToken(){var preservedToken=null;try{let localToken=window.localStorage.getItem('uvsToken');if(!(localToken!==null&&localToken.length>0)){return preservedToken}
    36 let tokenData=localToken.split('_uvs_ts_');if(!(typeof(tokenData)!='undefined'&&tokenData!==null)){return preservedToken}
    37 if(tokenData.length<2){return preservedToken}
    38 let tokenPreservanceTimestamp=tokenData[1];tokenPreservanceTimestamp=Number(tokenPreservanceTimestamp);let currentUtcTimestamp=Math.round(new Date().getTime()/1000);if(isNaN(tokenPreservanceTimestamp))return preservedToken;tokenPreservanceTimestamp=tokenPreservanceTimestamp+(6*3600);if(!(currentUtcTimestamp>=tokenPreservanceTimestamp)){preservedToken=tokenData[0]}else{window.localStorage.removeItem('uvsToken')}}catch(err){preservedToken=null}
    39 return preservedToken}
    40 function uvsLogServiceCall(uvsUpdateLastValue=0){try{let uvsXhr=new XMLHttpRequest();uvsXhr.onreadystatechange=function(){if(this.readyState==4&&this.status==200){let res=JSON.parse(this.responseText);uvsServiceLogs.updatedAt=res.updatedAt||uvsServiceLogs.updatedAt;uvsServiceLogs.currentValue=res.currentValue||uvsServiceLogs.currentValue;uvsServiceLogs.lastValue=res.lastValue||uvsServiceLogs.lastValue}};uvsXhr.open("POST",uvsAjaxObj.ajax_url,!0);uvsXhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");uvsXhr.send("action=uvs_log_service_call&_ajax_nonce="+uvsAjaxObj.nonce+"&updateLastValue="+uvsUpdateLastValue)}catch(err){}}
    41 function uvsGetCurrentHostURL(){var currentHostUrl=null;try{if(!(typeof(window.location)!='undefined'&&typeof(window.location.hostname)!='undefined'&&typeof(window.location.protocol)!='undefined')){return uvsGetHostName()}
    42 var thisProtocol=window.location.protocol;var thisHostname=window.location.hostname;currentHostUrl=thisProtocol+'//'+thisHostname}catch(err){currentHostUrl=uvsGetHostName();console.log('Something went wrong while discovering current domain.')}
    43 return currentHostUrl}
    44 function uvsGetHostName(){return uvsHostName}
     1"function"!=typeof String.prototype.trim&&(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")});var respTimeOut=!1,errcnt=0;let uvsHostName="undefined"!=typeof uvsCurrentHostName?uvsCurrentHostName:null;var uvsAudioPlayer={htmlAudioElement:document.createElement("AUDIO"),lastFilePath:null,antiMuteButtonPlaybacks:[uvsSilenceSoundPath],isAntiMutePlayback:!1,configure:function(t=null,e=null){try{let n=void 0!==t&&t?t:null;n?(this.htmlAudioElement.src=_uvsPath+n,this.htmlAudioElement.preload="auto",this.lastFilePath=n,-1!==this.antiMuteButtonPlaybacks.indexOf(n)?this.isAntiMutePlayback=!0:this.isAntiMutePlayback=!1):(this.htmlAudioElement.src="",this.isAntiMutePlayback=!1),this.htmlAudioElement.onplay=function(){}.bind(this),this.htmlAudioElement.onended=function(){this.htmlAudioElement.src="",this.isAntiMutePlayback=!1,n&&"function"==typeof e&&(e(),e=null)}.bind(this),this.htmlAudioElement.onerror=function(){this.isAntiMutePlayback=!1}.bind(this),this.htmlAudioElement.onplaying=function(){}.bind(this)}catch(t){this.clear(),this.isAntiMutePlayback=!1}},play:function(){try{this.htmlAudioElement&&this.htmlAudioElement.src&&this.htmlAudioElement.play().catch(function(t){console.log("VDN Exception: Failed to play audio.")})}catch(t){this.clear()}},stop:function(){try{this.clear()}catch(t){this.clear()}},clear:function(){try{if(this.htmlAudioElement){let t=isNaN(this.htmlAudioElement.duration)?0:this.htmlAudioElement.duration;this.htmlAudioElement.currentTime=t}this.lastFilePath=null}catch(t){this.lastFilePath=null,this.isAntiMutePlayback=!1}},isPlaying:function(){return(isNaN(this.htmlAudioElement.currentTime)?0:this.htmlAudioElement.currentTime)<(isNaN(this.htmlAudioElement.duration)?0:this.htmlAudioElement.duration)}};function stt(t,e,n){if(!(uvsSttLanguageContext.ibm.endPoint&&uvsSttLanguageContext.ibm.token&&uvsSttLanguageContext.ibm.model))return void("function"==typeof n&&n(null));if(0==e){let t=Math.floor(10*Math.random()),e=uvsAlternativeResponse.randomLib;0==respTimeOut&&(uvsAudioPlayer.configure(e[t]),uvsAudioPlayer.play(),respTimeOut=!0,setTimeout(function(){respTimeOut=!1},6e3))}let i=uvsSttLanguageContext.ibm.endPoint,o=uvsSttLanguageContext.ibm.qs.token+uvsSttLanguageContext.ibm.token+uvsSttLanguageContext.ibm.qs.model+uvsSttLanguageContext.ibm.model;var s=new WebSocket(i+o);s.onopen=function(e){!function(e){uvsLogServiceCall();s.send(JSON.stringify({action:"start","content-type":"audio/wav",interim_results:!1,max_alternatives:3,smart_formatting:!0})),s.send(t),s.send(JSON.stringify({action:"stop"}))}()},s.onclose=function(t){},s.onmessage=function(t){!function(t){let e=JSON.parse(t.data);if(null!=e.results){let t="";var i=!1;for(var o in e.results)1==e.results[o].final&&(t+=e.results[o].alternatives[0].transcript,i=!0);errcnt=0,1!=i&&0!=e.results.length||("function"==typeof n&&n(t),s.close())}}(t)},s.onerror=function(e){!function(e){if(errcnt++,s.close(),"undefined"==typeof uvsXApiKey||null===uvsXApiKey)return;errcnt<2?uvsRefreshVoiceServicesKeys().then(function(e){uvsSttLanguageContext.ibm.token=e,stt(t,!0,n)}).catch(function(t){alert(t)}):"function"==typeof n&&n(null)}()}}function uvsGcpStt(t){return new Promise(function(e,n){if(!(uvsSttLanguageContext.gcp.endPoint&&uvsSttLanguageContext.gcp.key&&uvsSttLanguageContext.gcp.langCode&&void 0!==t&&t))return void n(null);if(0==errcnt){let t=Math.floor(10*Math.random()),e=uvsAlternativeResponse.randomLib;uvsAudioPlayer.configure(e[t]),uvsAudioPlayer.play()}let i=new XMLHttpRequest;i.onreadystatechange=function(){if(4==this.readyState)try{let t=JSON.parse(this.response);if(200===this.status){errcnt=0;let i=void 0!==t&&t instanceof Object&&"results"in t?t.results:[],o=i&&i.length>0&&i[0]instanceof Object?i[0]:{},s="alternatives"in o&&o.alternatives?o.alternatives:[],u=s.length>0&&s[0]instanceof Object?s[0]:{},a="transcript"in u&&u.transcript?u.transcript:null;void 0!==a&&a?e(a):n(null)}else{let i="error"in t?t.error:{},o="message"in i&&i.message?i.message.toLowerCase():"";errcnt<1&&o&&-1!==o.indexOf("api key")?(errcnt++,uvsRefreshVoiceServicesKeys().then(function(t){uvsSttLanguageContext.gcp.key=t,uvsGcpStt().then(function(t){t?e(t):(errcnt=0,n(null))}).catch(function(t){errcnt=0,n(null)})}).catch(function(t){alert(t),errcnt=0,n(null)})):(errcnt=0,n(null))}}catch(t){n(null)}},i.onerror=function(t){n(null)},i.open("POST",uvsSttLanguageContext.gcp.endPoint+uvsSttLanguageContext.gcp.qs.key+uvsSttLanguageContext.gcp.key,!0),i.setRequestHeader("Content-Type","application/json;charset=UTF-8");let o={config:{encoding:"ENCODING_UNSPECIFIED",languageCode:uvsSttLanguageContext.gcp.langCode,enableWordTimeOffsets:!1},audio:{content:t}};i.send(JSON.stringify(o,null,!0))})}function uvsLogServiceCall(t=0){try{let e=new XMLHttpRequest;e.onreadystatechange=function(){if(4==this.readyState&&200==this.status){let t=JSON.parse(this.responseText);uvsServiceLogs.updatedAt=t.updatedAt||uvsServiceLogs.updatedAt,uvsServiceLogs.currentValue=t.currentValue||uvsServiceLogs.currentValue,uvsServiceLogs.lastValue=t.lastValue||uvsServiceLogs.lastValue}},e.open("POST",uvsAjaxObj.ajax_url,!0),e.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),e.send("action=uvs_log_service_call&_ajax_nonce="+uvsAjaxObj.nonce+"&updateLastValue="+t)}catch(t){}}function uvsGetCurrentHostURL(){var t=null;try{if(void 0===window.location||void 0===window.location.hostname||void 0===window.location.protocol)return uvsGetHostName();t=window.location.protocol+"//"+window.location.hostname}catch(e){t=uvsGetHostName(),console.log("Something went wrong while discovering current domain.")}return t}function uvsGetHostName(){return uvsHostName}function uvsRefreshVoiceServicesKeys(){return new Promise(function(t,e){let n=new XMLHttpRequest;n.onreadystatechange=function(){if(4==this.readyState)if(200===this.status){let n=JSON.parse(this.response);if(void 0===n&&e(uvsErrorLibrary.outOfService),uvsSttLanguageContext.ibm.stt&&"token"in n&&n.token)return void t(n.token);if(uvsSttLanguageContext.gcp.stt&&"gStt"in n&&n.gStt)return void t(n.gStt);e(uvsErrorLibrary.outOfService)}else e(uvsErrorLibrary.outOfService)};let i="?action=uvs_refresh_access_keys&_ajax_nonce="+uvsAjaxObj.keys_nonce;n.open("GET",uvsAjaxObj.ajax_url+i,!0),n.onerror=function(t){e(uvsErrorLibrary.outOfService)},n.send(null)})}
  • universal-voice-search/trunk/js/uvs.text-library.js

    r2196945 r2289691  
    99
    1010
    11 // Get selected language for plugin from plugin's settings/configurations
     11//####################################
     12// PLUGIN LANGUAGE
     13//####################################
    1214var uvsTypeOfSelectedLanguage = (typeof(uvsSelectedLanguage) != 'undefined' && uvsSelectedLanguage !== null) ? uvsSelectedLanguage.trim() : 'English';
     15var uvsSelectedLang = (typeof(uvsSelectedLanguage) != 'undefined' && uvsSelectedLanguage !== null) ? uvsSelectedLanguage.trim() : 'en-US';
    1316
    14 // English: Language param for speech/speaking
    15 var uvsSelectedLang = 'en-US';
     17var uvsIsSttLangCtx = typeof _uvsSttLanguageContext != 'undefined' && !!_uvsSttLanguageContext && _uvsSttLanguageContext instanceof Object ? true : false;
     18var uvsSttLanguageContext = {
     19    'ibm': {
     20        'stt': null,
     21        'endPoint': null,
     22        'token': null,
     23        'model': null,
     24        'qs': {'token': null, 'model': null}
     25    },
     26    'gcp': {
     27        'stt': null,
     28        'langCode': null,
     29        'endPoint': null,
     30        'key': null,
     31        'qs': {'key': null}
     32    }
     33}
    1634
    17 var uvsAlternativeResponse = '';
     35if (uvsIsSttLangCtx === true) {
     36    //###############################
     37    // IBM
     38    //###############################
     39    let ibm = 'ibm' in _uvsSttLanguageContext && _uvsSttLanguageContext['ibm'] instanceof Object ? _uvsSttLanguageContext['ibm'] : {};
     40    uvsSttLanguageContext['ibm']['stt'] = 'stt' in ibm && ibm['stt'] == 'Y' ? true : false;
    1841
    19 var uvsMessages = '';
    20 var uvsWidgetMessages = { 'placeholder': '' };
     42    if (!!uvsSttLanguageContext['ibm']['stt']) {
     43        uvsSttLanguageContext['ibm']['endPoint'] = 'endPoint' in ibm && typeof ibm['endPoint'] != 'undefined' && !!ibm['endPoint'] ? ibm['endPoint'] : null;
     44        uvsSttLanguageContext['ibm']['token'] = 'token' in ibm && typeof ibm['token'] != 'undefined' && !!ibm['token'] ? ibm['token'] : null;
     45        uvsSttLanguageContext['ibm']['model'] = 'model' in ibm && typeof ibm['model'] != 'undefined' && !!ibm['model'] ? ibm['model'] : null;
    2146
    22 switch (uvsTypeOfSelectedLanguage.toLowerCase()) {
    23     case 'german':
    24         uvsSelectedLang = 'de-DE';
     47        let qs = 'qs' in ibm && ibm['qs'] instanceof Object ? ibm['qs'] : {};
     48        uvsSttLanguageContext['ibm']['qs']['token'] = 'token' in qs && typeof qs['token'] != 'undefined' && !!qs['token'] ? qs['token'] : null;
     49        uvsSttLanguageContext['ibm']['qs']['model'] = 'model' in qs && typeof qs['model'] != 'undefined' && !!qs['model'] ? qs['model'] : null;
     50    }
    2551
    26         uvsAlternativeResponse = {
    27             'basic'  : 'Lass mich danach suchen.',
    28             'randomLib' : [
    29                 "Eine Sekunde bitte.",
    30                 "Ich bin dabei.",
    31                 "Kein Problem.",
    32                 "Einen Moment, ich brauche eine kurze Pause.",
    33                 "Sie scheinen zu hart zu arbeiten. Holen Sie sich einen Kaffee, und ich werde es für Sie nachschlagen.",
    34                 "Ich komme gleich.",
    35                 "Ich werde mein Bestes geben",
    36                 "Alles für dich. Ich werde gleich loslegen.",
    37                 "Daran zu arbeiten. Einen Moment bitte.",
    38                 "Beep - Beep - Beep, nur ein Scherz. Einen Moment bitte."
    39             ],
    40             'micConnect' : 'Es tut mir leid, aber ich kann nicht auf Ihr Mikrofon zugreifen. Bitte schließen Sie ein Mikrofon an oder geben Sie bei Bedarf Ihre Frage ein.',
    41             'unavailable' : 'Die Sprachnavigation ist derzeit nicht verfügbar. Bitte versuchen Sie es nach einiger Zeit erneut.',
    42             'notAudible': 'Ich kann dich nicht hören',
    43             'simonShortIntro': "Hallo, ich heiße Simon. Ich bin Ihr virtueller Webassistent."
    44         };
     52    //###############################
     53    // GCP
     54    //###############################
     55    let gcp = 'gcp' in _uvsSttLanguageContext && _uvsSttLanguageContext['gcp'] instanceof Object ? _uvsSttLanguageContext['gcp'] : {};
     56    uvsSttLanguageContext['gcp']['stt'] = 'stt' in gcp && gcp['stt'] == 'Y' ? true : false;
    4557
    46         // German: Common messages/text
    47         uvsMessages = {
    48             'micNotAccessible': 'Ich kann nicht auf das Mikrofon zugreifen.',
    49             'browserDenyMicAccess': "Ihre Browsersicherheit erlaubt mir nicht, auf das Mikrofon zuzugreifen.",
    50             'transcribeText': ' Transkribieren ....',
    51             'unableToHear': 'Ich kann dich nicht hören.',
    52             'ask': ' Sage es noch einmal ....',
    53             'cantAccessMicrophone' : 'kann nicht auf das Mikrofon zugreifen',
    54         }
     58    if (!!uvsSttLanguageContext['gcp']['stt']) {
     59        uvsSttLanguageContext['gcp']['endPoint'] = 'endPoint' in gcp && typeof gcp['endPoint'] != 'undefined' && !!gcp['endPoint'] ? gcp['endPoint'] : null;
     60        uvsSttLanguageContext['gcp']['key'] = 'key' in gcp && typeof gcp['key'] != 'undefined' && !!gcp['key'] ? gcp['key'] : null;
     61        uvsSttLanguageContext['gcp']['langCode'] = 'langCode' in gcp && typeof gcp['langCode'] != 'undefined' && !!gcp['langCode'] ? gcp['langCode'] : null;
    5562
    56         uvsWidgetMessages.placeholder = 'Geben Sie eine Abfrage ein';
    57         break;
     63        let qs = 'qs' in gcp && gcp['qs'] instanceof Object ? gcp['qs'] : {};
     64        uvsSttLanguageContext['gcp']['qs']['key'] = 'key' in qs && typeof qs['key'] != 'undefined' && !!qs['key'] ? qs['key'] : null;
     65    }
     66}
    5867
    59     case 'portuguese':
    60         uvsSelectedLang = 'pt-BR';
     68//####################################
     69// CLIENT INFO
     70//####################################
     71let uvsNavigator = { 'navigatorUserAgent': navigator.userAgent.toLowerCase(), 'navigatorPlatform': navigator.platform };
     72var uvsClientInfo = {
     73    'safari': uvsNavigator.navigatorUserAgent.indexOf('safari') > -1,
     74    'chrome': uvsIsSttLangCtx === true && 'isChrome' in _uvsSttLanguageContext && _uvsSttLanguageContext['isChrome'] === 'Y' ? true : false,
     75    'firefox': uvsNavigator.navigatorUserAgent.indexOf('firefox') > -1,
     76    'ios': !!uvsNavigator.navigatorPlatform && /iPad|iPhone|iPod/.test(uvsNavigator.navigatorPlatform),
     77    'android': uvsNavigator.navigatorUserAgent.indexOf("android") > -1,
     78    'windows': uvsNavigator.navigatorUserAgent.indexOf("windows") > -1
     79};
    6180
    62         uvsAlternativeResponse = {
    63             'basic'  : '',
    64             'randomLib' : ["","","", "","", "", "", "","",""],
    65             'micConnect' : 'I am sorry but I am unable to access your microphone. Please connect a microphone or you can also type your question if needed.',
    66             'unavailable' : 'Voice navigation is currently unavailable. Please try again after some time.',
    67             'notAudible': 'I am unable to hear you',
    68             'simonShortIntro': ""
    69         };
     81/**
     82 * Path map for audio files of short phrases
     83 *
     84 */
     85var uvsAudioShortPharasesPaths = {
     86    'root': 'short_phrases/',
     87    'voice': uvsSelectedLang + '/',
     88    'random': 'random/',
     89    'general': 'general/',
     90    'getRandomVoicesPath': function() {
     91        return this.root + this.random + this.voice + uvsSelectedLang + '_';
     92    },
     93    'getGeneralVoicesPath': function() {
     94        return this.root + this.general +  this.voice + uvsSelectedLang + '_';
     95    }
     96}
    7097
    71         uvsMessages = {   
    72             'micNotAccessible': 'Não consigo acessar o microfone.',
    73             'browserDenyMicAccess': "A segurança do seu navegador não me permite acessar o microfone.",
    74             'transcribeText': ' Transcrição ....',
    75             'unableToHear': 'Eu sou incapaz de ouvir você.',
    76             'ask': ' Diga isso de novo ....',
    77             'cantAccessMicrophone': 'não consigo acessar o microfone'
    78         };
     98let uvsRandomShortPhrasePath = uvsAudioShortPharasesPaths.getRandomVoicesPath();
     99let uvsGeneralShortPhrasePath = uvsAudioShortPharasesPaths.getGeneralVoicesPath();
     100let uvsSilenceSoundPath = uvsAudioShortPharasesPaths.root + 'silence.mp3';
    79101
    80         uvsWidgetMessages.placeholder = 'Digite uma consulta';
    81         break;
     102/**
     103 * Alternative response audio files to be played/spoken
     104 *
     105 */
     106var uvsAlternativeResponse = {
     107    /**
     108     * Text in audio file: Let me search it
     109     */
     110    'basic'  : uvsGeneralShortPhrasePath + "basic.mp3",
     111    /**
     112     * Text in audio file: I am sorry but I am unable to access your microphone, Please connect a microphone or you can also type your question if needed
     113     */
     114    'micConnect' : uvsGeneralShortPhrasePath + "mic_connect.mp3",
     115    /**
     116     * Text in audio file: Voice search is currently unavailable, Please try again after some time
     117     */
     118    'unavailable' : uvsGeneralShortPhrasePath + "unavailable.mp3",
     119    /**
     120     * Text in audio file: I am unable to hear you
     121     */
     122    'notAudible': uvsGeneralShortPhrasePath + "not_audible.mp3",
     123    'randomLib' : [
     124        /**
     125         * Text in audio file: Just a second please
     126         */
     127        uvsRandomShortPhrasePath + "0.mp3",
     128        /**
     129         * Text in audio file: I am on it
     130         */
     131        uvsRandomShortPhrasePath + "1.mp3",
     132        /**
     133         * Text in audio file: No problem
     134         */
     135        uvsRandomShortPhrasePath + "2.mp3",
     136        /**
     137         * Text in audio file: Just a moment, I need a brief rest
     138         */
     139        uvsRandomShortPhrasePath + "3.mp3",
     140        /**
     141         * Text in audio file: You seem to work too hard, Get your self a coffee and I will find it up for you
     142         */
     143        uvsRandomShortPhrasePath + "4.mp3",
     144        /**
     145         * Text in audio file: Coming right up
     146         */
     147        uvsRandomShortPhrasePath + "5.mp3",
     148        /**
     149         * Text in audio file: I will do my best
     150         */
     151        uvsRandomShortPhrasePath + "6.mp3",
     152        /**
     153         * Text in audio file: Anything for you. I will get right on it
     154         */
     155        uvsRandomShortPhrasePath + "7.mp3",
     156        /**
     157         * Text in audio file: Working on it, One moment please
     158         */
     159        uvsRandomShortPhrasePath + "8.mp3",
     160        /**
     161         * Text in audio file: Beep - Beep - Beep, just kidding, One moment please
     162         */
     163        uvsRandomShortPhrasePath + "9.mp3"
     164    ],
     165};
    82166
    83     case 'chinese':
    84         uvsSelectedLang = 'zh-CN';
    85 
    86         uvsAlternativeResponse = {
    87             'basic'  : '',
    88             'randomLib' : ["","","", "","", "", "", "","",""],
    89             'micConnect' : 'I am sorry but I am unable to access your microphone. Please connect a microphone or you can also type your question if needed.',
    90             'unavailable' : 'Voice navigation is currently unavailable. Please try again after some time.',
    91             'notAudible': 'I am unable to hear you',
    92             'simonShortIntro': ""
    93         };
    94 
    95         uvsMessages = {   
    96             'micNotAccessible': '我无法使用麦克风。',
    97             'browserDenyMicAccess': "您的浏览器安全性不允许我访问麦克风。",
    98             'transcribeText': ' 抄写....',
    99             'unableToHear': '我听不到您的声音。',
    100             'ask': ' 再说一遍 ....',
    101             'cantAccessMicrophone': '无法访问麦克风'
    102         };
    103 
    104         uvsWidgetMessages.placeholder = '输入查询';     
    105         break;
    106 
    107     case 'french':
    108         uvsSelectedLang = 'fr-FR';
    109 
    110         uvsAlternativeResponse = {
    111             'basic'  : '',
    112             'randomLib' : ["","","", "","", "", "", "","",""],
    113             'micConnect' : 'I am sorry but I am unable to access your microphone. Please connect a microphone or you can also type your question if needed.',
    114             'unavailable' : 'Voice navigation is currently unavailable. Please try again after some time.',
    115             'notAudible': 'I am unable to hear you',
    116             'simonShortIntro': ""
    117         };
    118 
    119         uvsMessages = {   
    120             'micNotAccessible': 'Je ne parviens pas à accéder au microphone.',
    121             'browserDenyMicAccess': "La sécurité de votre navigateur ne me permet pas d'accéder au micro.",
    122             'transcribeText': ' Transcription ....',
    123             'unableToHear': 'Je suis incapable de vous entendre.',
    124             'ask': ' Dis le encore ....',
    125             'cantAccessMicrophone': 'ne peut pas accéder au microphone'
    126         };
    127 
    128         uvsWidgetMessages.placeholder = 'Tapez une requête';
    129         break;
    130 
    131     case 'japanese':
    132         uvsSelectedLang = 'ja-JP';
    133 
    134         uvsAlternativeResponse = {
    135             'basic'  : '',
    136             'randomLib' : ["","","", "","", "", "", "","",""],
    137             'micConnect' : 'I am sorry but I am unable to access your microphone. Please connect a microphone or you can also type your question if needed.',
    138             'unavailable' : 'Voice navigation is currently unavailable. Please try again after some time.',
    139             'notAudible': 'I am unable to hear you',
    140             'simonShortIntro': ""
    141         };
    142 
    143         uvsMessages = {   
    144             'micNotAccessible': 'マイクにアクセスできません。',
    145             'browserDenyMicAccess': "ブラウザのセキュリティにより、マイクにアクセスできません。",
    146             'transcribeText': '転写....',
    147             'unableToHear': 'あなたの声が聞こえません。',
    148             'ask': ' もう一度言ってください ....',
    149             'cantAccessMicrophone': 'マイクにアクセスできません'
    150         };
    151 
    152         uvsWidgetMessages.placeholder = 'クエリを入力します';
    153         break;
    154 
    155     case 'korean':
    156         uvsSelectedLang = 'ko-KR';
    157 
    158         uvsAlternativeResponse = {
    159             'basic'  : '',
    160             'randomLib' : ["","","", "","", "", "", "","",""],
    161             'micConnect' : 'I am sorry but I am unable to access your microphone. Please connect a microphone or you can also type your question if needed.',
    162             'unavailable' : 'Voice navigation is currently unavailable. Please try again after some time.',
    163             'notAudible': 'I am unable to hear you',
    164             'simonShortIntro': ""
    165         };
    166 
    167         uvsMessages = {   
    168             'micNotAccessible': '마이크에 액세스 할 수 없습니다.',
    169             'browserDenyMicAccess': "브라우저 보안으로 마이크에 액세스 할 수 없습니다.",
    170             'transcribeText': ' 전사 ....',
    171             'unableToHear': '나는 당신을들을 수 없습니다.',
    172             'ask': ' 다시 말해봐 ....',
    173             'cantAccessMicrophone': '마이크에 액세스 할 수 없습니다'
    174         };
    175 
    176         uvsWidgetMessages.placeholder = '검색어를 입력하십시오';
    177         break;
    178 
    179     case 'spanish':
    180         uvsSelectedLang = 'es-ES';
    181 
    182         uvsAlternativeResponse = {
    183             'basic'  : '',
    184             'randomLib' : ["","","", "","", "", "", "","",""],
    185             'micConnect' : 'I am sorry but I am unable to access your microphone. Please connect a microphone or you can also type your question if needed.',
    186             'unavailable' : 'Voice navigation is currently unavailable. Please try again after some time.',
    187             'notAudible': 'I am unable to hear you',
    188             'simonShortIntro': ""
    189         };
    190 
    191         uvsMessages = {   
    192             'micNotAccessible': 'No puedo acceder al micrófono.',
    193             'browserDenyMicAccess': "La seguridad de su navegador no me permite acceder al micrófono.",
    194             'transcribeText': ' Transcribiendo ...',
    195             'unableToHear': 'No puedo escucharte.',
    196             'ask': ' Dilo otra vez ....',
    197             'cantAccessMicrophone': 'no puedo acceder al micrófono'
    198         };
    199 
    200         uvsWidgetMessages.placeholder = 'Escribe una consulta';
    201         break;   
    202 
    203     default:
    204         uvsSelectedLang = (uvsTypeOfSelectedLanguage.toLowerCase() === 'british english') ? 'en-GB' : 'en-US';
    205 
    206         uvsAlternativeResponse = {
    207             'basic'  : 'Let me search for that.',
    208             'randomLib' : [
    209                 "Just a second please.",
    210                 "I am on it.",
    211                 "No problem.",
    212                 "Just a moment, I need a brief rest.",
    213                 "You seem to work too hard. Get your self a coffee, and I will look it up for you.",
    214                 "Coming right up.",
    215                 "I will do my best","Anything for you. I will get right on it.",
    216                 "Working on it. One moment please.",
    217                 "Beep - Beep - Beep, just kidding. One moment please."
    218             ],
    219             'micConnect' : 'I am sorry but I am unable to acces your microphone. Please connect a microphone or you can also type your question if needed.',
    220             'unavailable' : 'Voice navigation is currently unavailable. Please try again after some time.',
    221             'notAudible': 'I am unable to hear you',
    222             'simonShortIntro': "Hello, my name is Simon. I am your web virtual assistant."
    223         };
    224 
    225         uvsMessages = {     
    226             'micNotAccessible': 'I am unable to access the microphone.',
    227             'browserDenyMicAccess': "Your browser security doesn't allow me to access the mic.",
    228             'transcribeText': ' Transcribing ....',
    229             'unableToHear': 'I am unable to hear you.',
    230             'ask': ' Say it again ....',
    231             'cantAccessMicrophone' : 'can"t access the microphone'
    232         };
    233 
    234         uvsWidgetMessages.placeholder = 'Type a query';
    235 }
     167var uvsMessages = _uvsTextPhrases['uvsMessages'];
     168var uvsErrorLibrary = _uvsTextPhrases['uvsErrorLibrary'];
     169var uvsWidgetMessages = _uvsTextPhrases['uvsWidgetMessages'];
  • universal-voice-search/trunk/js/uvs.text-library.min.js

    r2196945 r2289691  
    1 var uvsTypeOfSelectedLanguage=(typeof(uvsSelectedLanguage)!='undefined'&&uvsSelectedLanguage!==null)?uvsSelectedLanguage.trim():'English';var uvsSelectedLang='en-US';var uvsAlternativeResponse='';var uvsMessages='';var uvsWidgetMessages={'placeholder':''};switch(uvsTypeOfSelectedLanguage.toLowerCase()){case 'german':uvsSelectedLang='de-DE';uvsAlternativeResponse={'basic':'Lass mich danach suchen.','randomLib':["Eine Sekunde bitte.","Ich bin dabei.","Kein Problem.","Einen Moment, ich brauche eine kurze Pause.","Sie scheinen zu hart zu arbeiten. Holen Sie sich einen Kaffee, und ich werde es für Sie nachschlagen.","Ich komme gleich.","Ich werde mein Bestes geben","Alles für dich. Ich werde gleich loslegen.","Daran zu arbeiten. Einen Moment bitte.","Beep - Beep - Beep, nur ein Scherz. Einen Moment bitte."],'micConnect':'Es tut mir leid, aber ich kann nicht auf Ihr Mikrofon zugreifen. Bitte schließen Sie ein Mikrofon an oder geben Sie bei Bedarf Ihre Frage ein.','unavailable':'Die Sprachnavigation ist derzeit nicht verfügbar. Bitte versuchen Sie es nach einiger Zeit erneut.','notAudible':'Ich kann dich nicht hören','simonShortIntro':"Hallo, ich heiße Simon. Ich bin Ihr virtueller Webassistent."};uvsMessages={'micNotAccessible':'Ich kann nicht auf das Mikrofon zugreifen.','browserDenyMicAccess':"Ihre Browsersicherheit erlaubt mir nicht, auf das Mikrofon zuzugreifen.",'transcribeText':' Transkribieren ....','unableToHear':'Ich kann dich nicht hören.','ask':' Sage es noch einmal ....','cantAccessMicrophone':'kann nicht auf das Mikrofon zugreifen',}
    2 uvsWidgetMessages.placeholder='Geben Sie eine Abfrage ein';break;case 'portuguese':uvsSelectedLang='pt-BR';uvsAlternativeResponse={'basic':'','randomLib':["","","","","","","","","",""],'micConnect':'I am sorry but I am unable to access your microphone. Please connect a microphone or you can also type your question if needed.','unavailable':'Voice navigation is currently unavailable. Please try again after some time.','notAudible':'I am unable to hear you','simonShortIntro':""};uvsMessages={'micNotAccessible':'Não consigo acessar o microfone.','browserDenyMicAccess':"A segurança do seu navegador não me permite acessar o microfone.",'transcribeText':' Transcrição ....','unableToHear':'Eu sou incapaz de ouvir você.','ask':' Diga isso de novo ....','cantAccessMicrophone':'não consigo acessar o microfone'};uvsWidgetMessages.placeholder='Digite uma consulta';break;case 'chinese':uvsSelectedLang='zh-CN';uvsAlternativeResponse={'basic':'','randomLib':["","","","","","","","","",""],'micConnect':'I am sorry but I am unable to access your microphone. Please connect a microphone or you can also type your question if needed.','unavailable':'Voice navigation is currently unavailable. Please try again after some time.','notAudible':'I am unable to hear you','simonShortIntro':""};uvsMessages={'micNotAccessible':'我无法使用麦克风。','browserDenyMicAccess':"您的浏览器安全性不允许我访问麦克风。",'transcribeText':' 抄写....','unableToHear':'我听不到您的声音。','ask':' 再说一遍 ....','cantAccessMicrophone':'无法访问麦克风'};uvsWidgetMessages.placeholder='输入查询';break;case 'french':uvsSelectedLang='fr-FR';uvsAlternativeResponse={'basic':'','randomLib':["","","","","","","","","",""],'micConnect':'I am sorry but I am unable to access your microphone. Please connect a microphone or you can also type your question if needed.','unavailable':'Voice navigation is currently unavailable. Please try again after some time.','notAudible':'I am unable to hear you','simonShortIntro':""};uvsMessages={'micNotAccessible':'Je ne parviens pas à accéder au microphone.','browserDenyMicAccess':"La sécurité de votre navigateur ne me permet pas d'accéder au micro.",'transcribeText':' Transcription ....','unableToHear':'Je suis incapable de vous entendre.','ask':' Dis le encore ....','cantAccessMicrophone':'ne peut pas accéder au microphone'};uvsWidgetMessages.placeholder='Tapez une requête';break;case 'japanese':uvsSelectedLang='ja-JP';uvsAlternativeResponse={'basic':'','randomLib':["","","","","","","","","",""],'micConnect':'I am sorry but I am unable to access your microphone. Please connect a microphone or you can also type your question if needed.','unavailable':'Voice navigation is currently unavailable. Please try again after some time.','notAudible':'I am unable to hear you','simonShortIntro':""};uvsMessages={'micNotAccessible':'マイクにアクセスできません。','browserDenyMicAccess':"ブラウザのセキュリティにより、マイクにアクセスできません。",'transcribeText':'転写....','unableToHear':'あなたの声が聞こえません。','ask':' もう一度言ってください ....','cantAccessMicrophone':'マイクにアクセスできません'};uvsWidgetMessages.placeholder='クエリを入力します';break;case 'korean':uvsSelectedLang='ko-KR';uvsAlternativeResponse={'basic':'','randomLib':["","","","","","","","","",""],'micConnect':'I am sorry but I am unable to access your microphone. Please connect a microphone or you can also type your question if needed.','unavailable':'Voice navigation is currently unavailable. Please try again after some time.','notAudible':'I am unable to hear you','simonShortIntro':""};uvsMessages={'micNotAccessible':'마이크에 액세스 할 수 없습니다.','browserDenyMicAccess':"브라우저 보안으로 마이크에 액세스 할 수 없습니다.",'transcribeText':' 전사 ....','unableToHear':'나는 당신을들을 수 없습니다.','ask':' 다시 말해봐 ....','cantAccessMicrophone':'마이크에 액세스 할 수 없습니다'};uvsWidgetMessages.placeholder='검색어를 입력하십시오';break;case 'spanish':uvsSelectedLang='es-ES';uvsAlternativeResponse={'basic':'','randomLib':["","","","","","","","","",""],'micConnect':'I am sorry but I am unable to access your microphone. Please connect a microphone or you can also type your question if needed.','unavailable':'Voice navigation is currently unavailable. Please try again after some time.','notAudible':'I am unable to hear you','simonShortIntro':""};uvsMessages={'micNotAccessible':'No puedo acceder al micrófono.','browserDenyMicAccess':"La seguridad de su navegador no me permite acceder al micrófono.",'transcribeText':' Transcribiendo ...','unableToHear':'No puedo escucharte.','ask':' Dilo otra vez ....','cantAccessMicrophone':'no puedo acceder al micrófono'};uvsWidgetMessages.placeholder='Escribe una consulta';break;default:uvsSelectedLang=(uvsTypeOfSelectedLanguage.toLowerCase()==='british english')?'en-GB':'en-US';uvsAlternativeResponse={'basic':'Let me search for that.','randomLib':["Just a second please.","I am on it.","No problem.","Just a moment, I need a brief rest.","You seem to work too hard. Get your self a coffee, and I will look it up for you.","Coming right up.","I will do my best","Anything for you. I will get right on it.","Working on it. One moment please.","Beep - Beep - Beep, just kidding. One moment please."],'micConnect':'I am sorry but I am unable to acces your microphone. Please connect a microphone or you can also type your question if needed.','unavailable':'Voice navigation is currently unavailable. Please try again after some time.','notAudible':'I am unable to hear you','simonShortIntro':"Hello, my name is Simon. I am your web virtual assistant."};uvsMessages={'micNotAccessible':'I am unable to access the microphone.','browserDenyMicAccess':"Your browser security doesn't allow me to access the mic.",'transcribeText':' Transcribing ....','unableToHear':'I am unable to hear you.','ask':' Say it again ....','cantAccessMicrophone':'can"t access the microphone'};uvsWidgetMessages.placeholder='Type a query'}
     1var uvsTypeOfSelectedLanguage="undefined"!=typeof uvsSelectedLanguage&&null!==uvsSelectedLanguage?uvsSelectedLanguage.trim():"English",uvsSelectedLang="undefined"!=typeof uvsSelectedLanguage&&null!==uvsSelectedLanguage?uvsSelectedLanguage.trim():"en-US",uvsIsSttLangCtx=!!("undefined"!=typeof _uvsSttLanguageContext&&_uvsSttLanguageContext&&_uvsSttLanguageContext instanceof Object),uvsSttLanguageContext={ibm:{stt:null,endPoint:null,token:null,model:null,qs:{token:null,model:null}},gcp:{stt:null,langCode:null,endPoint:null,key:null,qs:{key:null}}};if(!0===uvsIsSttLangCtx){let t="ibm"in _uvsSttLanguageContext&&_uvsSttLanguageContext.ibm instanceof Object?_uvsSttLanguageContext.ibm:{};if(uvsSttLanguageContext.ibm.stt="stt"in t&&"Y"==t.stt,uvsSttLanguageContext.ibm.stt){uvsSttLanguageContext.ibm.endPoint="endPoint"in t&&void 0!==t.endPoint&&t.endPoint?t.endPoint:null,uvsSttLanguageContext.ibm.token="token"in t&&void 0!==t.token&&t.token?t.token:null,uvsSttLanguageContext.ibm.model="model"in t&&void 0!==t.model&&t.model?t.model:null;let e="qs"in t&&t.qs instanceof Object?t.qs:{};uvsSttLanguageContext.ibm.qs.token="token"in e&&void 0!==e.token&&e.token?e.token:null,uvsSttLanguageContext.ibm.qs.model="model"in e&&void 0!==e.model&&e.model?e.model:null}let e="gcp"in _uvsSttLanguageContext&&_uvsSttLanguageContext.gcp instanceof Object?_uvsSttLanguageContext.gcp:{};if(uvsSttLanguageContext.gcp.stt="stt"in e&&"Y"==e.stt,uvsSttLanguageContext.gcp.stt){uvsSttLanguageContext.gcp.endPoint="endPoint"in e&&void 0!==e.endPoint&&e.endPoint?e.endPoint:null,uvsSttLanguageContext.gcp.key="key"in e&&void 0!==e.key&&e.key?e.key:null,uvsSttLanguageContext.gcp.langCode="langCode"in e&&void 0!==e.langCode&&e.langCode?e.langCode:null;let t="qs"in e&&e.qs instanceof Object?e.qs:{};uvsSttLanguageContext.gcp.qs.key="key"in t&&void 0!==t.key&&t.key?t.key:null}}let uvsNavigator={navigatorUserAgent:navigator.userAgent.toLowerCase(),navigatorPlatform:navigator.platform};var uvsClientInfo={safari:uvsNavigator.navigatorUserAgent.indexOf("safari")>-1,chrome:!0===uvsIsSttLangCtx&&"isChrome"in _uvsSttLanguageContext&&"Y"===_uvsSttLanguageContext.isChrome,firefox:uvsNavigator.navigatorUserAgent.indexOf("firefox")>-1,ios:!!uvsNavigator.navigatorPlatform&&/iPad|iPhone|iPod/.test(uvsNavigator.navigatorPlatform),android:uvsNavigator.navigatorUserAgent.indexOf("android")>-1,windows:uvsNavigator.navigatorUserAgent.indexOf("windows")>-1},uvsAudioShortPharasesPaths={root:"short_phrases/",voice:uvsSelectedLang+"/",random:"random/",general:"general/",getRandomVoicesPath:function(){return this.root+this.random+this.voice+uvsSelectedLang+"_"},getGeneralVoicesPath:function(){return this.root+this.general+this.voice+uvsSelectedLang+"_"}};let uvsRandomShortPhrasePath=uvsAudioShortPharasesPaths.getRandomVoicesPath(),uvsGeneralShortPhrasePath=uvsAudioShortPharasesPaths.getGeneralVoicesPath(),uvsSilenceSoundPath=uvsAudioShortPharasesPaths.root+"silence.mp3";var uvsAlternativeResponse={basic:uvsGeneralShortPhrasePath+"basic.mp3",micConnect:uvsGeneralShortPhrasePath+"mic_connect.mp3",unavailable:uvsGeneralShortPhrasePath+"unavailable.mp3",notAudible:uvsGeneralShortPhrasePath+"not_audible.mp3",randomLib:[uvsRandomShortPhrasePath+"0.mp3",uvsRandomShortPhrasePath+"1.mp3",uvsRandomShortPhrasePath+"2.mp3",uvsRandomShortPhrasePath+"3.mp3",uvsRandomShortPhrasePath+"4.mp3",uvsRandomShortPhrasePath+"5.mp3",uvsRandomShortPhrasePath+"6.mp3",uvsRandomShortPhrasePath+"7.mp3",uvsRandomShortPhrasePath+"8.mp3",uvsRandomShortPhrasePath+"9.mp3"]},uvsMessages=_uvsTextPhrases.uvsMessages,uvsErrorLibrary=_uvsTextPhrases.uvsErrorLibrary,uvsWidgetMessages=_uvsTextPhrases.uvsWidgetMessages;
  • universal-voice-search/trunk/readme.txt

    r2225505 r2289691  
    55Tested up to:      5.3.2 
    66Requires PHP:      5.3
    7 Stable tag:        1.1.4
     7Stable tag:        2.0.0
    88License:           GPLv2 or later 
    99License URI:       http://www.gnu.org/licenses/gpl-2.0.html 
     
    2626
    2727== Supported Languages ==
    28 This plugin support multiple languges.
     28This plugin supports 130 different languges.
    2929PLEASE MAKE SURE TO SELECT the languge that matches your web page.
    30 Languages:
     30Example languages supported:
    3131*   English
    3232*   German
     
    3737*   Korean
    3838*   Spanish
     39*   Arabic
     40*   Danish
     41*   Dutch
     42*   Norwegian
     43*   Hindi
     44*   Polish
     45*   Russian
     46*   and many more
    3947
    4048
     
    191199= 1.1.4 =
    192200* Auto detect language settings and default search languge to page settings
     201
     202= 2.0.0 =
     203* Addes support for 130 languages
     204* Added high quality voice audio response
  • universal-voice-search/trunk/universal-voice-search.php

    r2225505 r2289691  
    33 * Plugin Name: Universal Voice Search
    44 * Description: Allows any serach box on the page to be searchable via voice.
    5  * Version:     1.1.4
     5 * Version:     2.0.0
    66 * Author:      speak2web
    77 * Author URI:  https://speak2web.com/
     
    4040
    4141if ( $universal_voice_search_requirements_check->passes() ) {
     42    // To get all active plugins.
     43    $uvs_all_active_plugins = (array) null;
     44
    4245    // Get selected language from DB and load local translation library
    43     $uvs_selected_language = get_option( 'uvs_selected_language', 'english' );
    44     $uvs_selected_language = empty($uvs_selected_language) ? 'english' : trim($uvs_selected_language);
    45     $uvs_language_file_name = strtolower($uvs_selected_language) === 'german' ? 'uvs_de_DE' : 'uvs_en_EN';
     46    $uvs_selected_language = get_option( 'uvs_selected_language', 'en-US' );
     47    $uvs_selected_language = empty($uvs_selected_language) ? 'en-US' : trim($uvs_selected_language);
     48    $uvs_language_file_name = strtolower($uvs_selected_language) === 'de-DE' ? 'uvs_de_DE' : 'uvs_en_EN';
    4649    include( dirname( __FILE__ ) . '/classes/plugin-languages/'.$uvs_language_file_name.'.php');
    4750
    4851     try {
    4952        switch (strtolower($uvs_selected_language)) {
    50             case 'german':
     53            case 'de-DE':
    5154                define('UVS_LANGUAGE_LIBRARY', uvs_de_DE::UVS_LANGUAGE_LIB);
    5255                break;
     
    5861    }
    5962
     63    define('UVS_PLUGIN', array(
     64        'ABS_PATH' => plugin_dir_path(__FILE__),
     65        'ABS_URL' => plugin_dir_url(__FILE__),
     66        'BASE_NAME' => plugin_basename( __FILE__ ),
     67        'SHORT_PHRASES' => array('root' => 'short_phrases/', 'general' => 'general/', 'random' => 'random/')
     68    ));
     69
    6070    // Pull in the plugin classes and initialize
    6171    include( dirname( __FILE__ ) . '/lib/wp-stack-plugin.php' );
    6272    include( dirname( __FILE__ ) . '/classes/uvs-admin-notices.php');
     73    include( dirname( __FILE__ ) . '/classes/languages/languages.php');
    6374    include( dirname( __FILE__ ) . '/classes/plugin.php' );
    6475    include( dirname( __FILE__ ) . '/classes/settings-page.php' );
     
    8495    // Hook into plugin activation
    8596    register_activation_hook(__FILE__, function() {
    86         $vdn_path   = 'voice-dialog-navigation/voice-dialog-navigation.php';
    87         $vf_path    = 'voice-forms/voice-forms.php';
    88         $plugin_url = plugin_dir_url(__FILE__ );
     97        $uvs_setting_update_ts = Universal_Voice_Search_Settings_Page::uvs_settings_modified_timestamp('set');
     98        unset($uvs_setting_update_ts);
    8999
    90         if (is_plugin_active($vf_path) || is_plugin_active($vdn_path)) {
    91             wp_die(Uvs_Admin_Notices::uvs_denied_activation_notice($plugin_url));
     100        // Get active plugins
     101        $uvs_all_active_plugins = get_option('active_plugins');
     102       
     103        // Get higher version active plugins path
     104        $vdn_path = uvs_get_active_plugin_path('voice-dialog-navigation', $uvs_all_active_plugins);
     105        $vf_path = uvs_get_active_plugin_path('voice-forms', $uvs_all_active_plugins);
     106       
     107        $uvs_plugin_url = plugin_dir_url(__FILE__ );
     108
     109        // Display activation denied notice and stop activating this plugin
     110        if (
     111            (!empty($vf_path) && is_plugin_active($vf_path))
     112            || (!empty($vdn_path) && is_plugin_active($vdn_path))
     113        ) {
     114            wp_die(Uvs_Admin_Notices::uvs_denied_activation_notice($uvs_plugin_url));
     115        }
     116
     117        //###########################################################################################################################################
     118        // Transition code to preserve admin's language choice before upgrading/updating to additional 130 language support feature
     119        //
     120        // Here admin's language choice is check against fallback array which maps the old way of storing language name as value with language code
     121        //###########################################################################################################################################
     122        $uvs_selected_language = get_option(Universal_Voice_Search_Settings_Page::BASIC_CONFIG_OPTION_NAMES['selected_language'], 'en-US');
     123        $uvs_selected_language = isset($uvs_selected_language) && !empty($uvs_selected_language) ? $uvs_selected_language : 'en-US';
     124
     125        if (in_array($uvs_selected_language, Universal_Voice_Search_Plugin::$uvs_fallback_lang_map)) {
     126            $uvs_lang_code = array_search($uvs_selected_language, Universal_Voice_Search_Plugin::$uvs_fallback_lang_map);
     127            update_option(Universal_Voice_Search_Settings_Page::BASIC_CONFIG_OPTION_NAMES['selected_language'], $uvs_lang_code);
    92128        }
    93129
     
    95131        Universal_Voice_Search_Plugin::uvs_register_plugin();
    96132    });
     133
     134    /**
     135     * Function to get path of active plugin
     136     *
     137     * @param $uvs_plugin_file_name  String  Name of the plugin file (Without extension)
     138     * @param $uvs_active_plugins  Array  Array of active plugins path
     139     *
     140     * @return $uvs_active_plugin_path  String  Path of active plugin otherwise NULL
     141     *
     142     */
     143    function uvs_get_active_plugin_path($uvs_plugin_file_name = "", $uvs_active_plugins = array()) {
     144        $uvs_active_plugin_path = null;
     145
     146        try {
     147            if (!!$uvs_active_plugins && !!$uvs_plugin_file_name) {
     148                $uvs_plugin_file_name = trim($uvs_plugin_file_name);
     149
     150                foreach ($uvs_active_plugins as $key => $active_plugin) {
     151                    $plugin_name_pos = stripos($active_plugin, $uvs_plugin_file_name.".php");
     152
     153                    if ($plugin_name_pos !== false) {
     154                        $uvs_active_plugin_path = $active_plugin;
     155                        break;
     156                    }
     157                }
     158            }
     159        } catch(\Exception $ex) {
     160            $uvs_active_plugin_path = null;
     161        }
     162       
     163        return $uvs_active_plugin_path;
     164    }
    97165}
    98166
Note: See TracChangeset for help on using the changeset viewer.