fbpixel
Etiquetas: , ,

Neste tutorial, vamos ver como dar uma voz ao seu dispositivo Android utilizando uma biblioteca Text to Speech (TTS). Quer esteja a desenvolver aplicações para pessoas com deficiência visual ou a tentar animar o seu sistema Android, dar uma voz ao seu projeto pode ser uma funcionalidade interessante. Para isso, vamos integrar a biblioteca react-native-tts numa aplicação Android desenvolvida com React Native.

Hardware

  • Dispositivo Android
  • Computador para programação
  • Um cabo USB para ligar o dispositivo Android ao PC

Configurar o projeto React Native

A biblioteca de conversão de texto em fala react-native-tts permite-lhe utilizar as vozes, ou modelos de conversão de texto em fala, disponíveis no seu dispositivo Android para ler texto.

npm install react-native-tts --save

Utilizamos uma lista pendente para selecionar a voz pretendida.

npm install react-native-dropdown-select-list --save

Utilizar a biblioteca react-native-tts

Em primeiro lugar, importamos a biblioteca TextToSpeech para o código, juntamente com a lista pendente

import Tts from 'react-native-tts'
import { SelectList } from 'react-native-dropdown-select-list'

Numa componente funcional, adicionamos os estados que nos interessam:

  • voz selecionada
  • mudança selecionada
  • lista de votação
  • lista de equipamentos

Há outros parâmetros que podem valer a pena testar

  • defaultLanguage
  • defaultPitch define o tom da voz (alto ou baixo)
  • defaultRate define a velocidade de reprodução de voz

Num gancho useEffect, inicializamos as listas de vozes e equipamentos e, em seguida, atribuímos a voz e o equipamento seleccionados por defeito.

Nota: Utilizamos a promessa resultante da inicialização do motor TextToSpeech para garantir que está disponível quando o componente é inicializado (Tts.getInitStatus().then((() => {)

  useEffect(() => {    

   //console.log("init availableVoice",availableVoice)
   if(availableVoice.length === 0){
    console.log("No data found")
    Tts.getInitStatus().then(() => {
    
      Tts.voices().then(voices =>  {
        voicesList = voices.map((voice,index) => {
          //console.log(voice);
          return {key: index, value: voice.name+"("+voice.language+")", disabled: voice.notInstalled==true ? true:false}
        }) ;
        langList =  voices.map((voice,index) => {
          return {key: index, value: voice.language, disabled: voice.notInstalled==true ? true:false}
        }) ;
        //console.log("voicesList", voicesList)
        setAvailableVoice(voicesList);
      }, (err) => {console.log("no voice loaded")}); //see all supported voices 
    
    
      Tts.engines().then(engines =>  {
        engList = engines.map((engine,index) => {
          return {key: index, value: engine.name}
        });
    
        //console.log("engList", engList)
        setAvailableEng(engList);
      }); //see all supported voices 
      
    
    
      }, (err) => {
        console.log("TTS not loaded");
        if (err.code === 'no_engine') {
          Tts.requestInstallEngine();
        }
      });

   }
    

    if(voice !== ""){
      Tts.setDefaultVoice(voice);
    }

    if(lang !== ""){
      Tts.setDefaultLanguage(lang);
    }
    
	}, [availableVoice,availableEng, voice,lang, eng]);

Por fim, devolvemos a renderização, que é incluída na encomenda:

  • a lista pendente de vozes disponíveis
  • a lista pendente de equipamentos disponíveis
  • uma caixa de texto para escrever o texto a ser lido
  • um botão para ler o texto
  return (
    <View style={{ flexGrow: 1, flex: 1 }}>
      <Text style={styles.mainTitle}>AC Text to Speech</Text>

      <View style={styles.inputBar}>
            <SelectList 
              setSelected={(val: React.SetStateAction<string>) => setVoice(val)} 
              data={availableVoice} 
              save="value"
          />
      </View>

     {/*} <View style={styles.inputBar}>
            <SelectList 
              setSelected={(val: React.SetStateAction<string>) => setLang(val)} 
              data={availableLang} 
              save="value"
          />
  </View>*/}

      <View style={styles.inputBar}>
            <SelectList 
              setSelected={(val: React.SetStateAction<string>) => setEng(val)} 
              data={availableEng} 
              save="value"
          />
      </View>

      <View
              style={styles.inputBar}>        
              <TextInput
                style={styles.textInput}
                placeholder="Enter a message"
                value={msgText}
                onChangeText={(text) =>    setMsgText(text)
                }
              />
              <TouchableOpacity
                        onPress={() => Tts.speak(msgText, {
  androidParams: {
    KEY_PARAM_PAN: -1,
    KEY_PARAM_VOLUME: 0.5,
    KEY_PARAM_STREAM: 'STREAM_MUSIC',
  },
})
                        }
                        style={[styles.sendButton]}>
                        <Text
                          style={styles.buttonText}>
                          Speak
                        </Text>
                      </TouchableOpacity>
        </View>
      {/*<Text>{currentDate}</Text>*/}
      <View style={{flex: 1 }}>

      </View>
    </View>

  )

Resultados

Depois de o código ter sido compilado e instalado no seu dispositivo, pode selecionar e testar as vozes disponíveis (as vozes não instaladas estão a cinzento). Introduza um texto e prima o botão “Falar” para fazer a sua aplicação falar.

android-app-react-native-tts Dê uma voz ao seu dispositivo Android com o React Native TTS

Código fonte completo: Text To Speech

/**
 * npm install react-native-tts --save
 * https://www.netguru.com/blog/react-native-text-to-speech
 * https://www.npmjs.com/package/react-native-tts
 * 
 * npm install react-native-dropdown-select-list --save
 */
 
import React, { useEffect, useState } from 'react'
import { Text, View, StyleSheet, TextInput, TouchableOpacity } from 'react-native'
import Tts from 'react-native-tts'
import { SelectList } from 'react-native-dropdown-select-list'

//Tts.setDefaultLanguage('en-GB')
Tts.setDefaultLanguage('fr-FR')
//Tts.setDefaultVoice('com.apple.ttsbundle.Daniel-compact')
//Tts.setDefaultRate(0.6);
//Tts.setDefaultPitch(1.5);
//Tts.setDefaultEngine('engineName');

//request install. app need reinstall after
let voicesList: { key: number; value: string; disabled: boolean }[] | ((prevState: never[]) => never[])= []
let langList = []
let engList: { key: number; value: string }[] | ((prevState: never[]) => never[]) = []


const App = () =>  {
  const [msgText, setMsgText] = useState("");
  const [voice, setVoice] = useState("")
  const [lang, setLang] = useState("")
  const [eng, setEng] = useState("")
  
  const [availableVoice, setAvailableVoice] = useState([])
  const [availableLang, setAvailableLang] = useState([])
  const [availableEng, setAvailableEng] = useState([])

  
  useEffect(() => {    

   //console.log("init availableVoice",availableVoice)
   if(availableVoice.length === 0){
    console.log("No data found")
    Tts.getInitStatus().then(() => {
    
      Tts.voices().then(voices =>  {
        voicesList = voices.map((voice,index) => {
          //console.log(voice);
          return {key: index, value: voice.name+"("+voice.language+")", disabled: voice.notInstalled==true ? true:false}
        }) ;
        langList =  voices.map((voice,index) => {
          return {key: index, value: voice.language, disabled: voice.notInstalled==true ? true:false}
        }) ;
        //console.log("voicesList", voicesList)
        setAvailableVoice(voicesList);
      }, (err) => {console.log("no voice loaded")}); //see all supported voices 
    
    
      Tts.engines().then(engines =>  {
        engList = engines.map((engine,index) => {
          return {key: index, value: engine.name}
        });
    
        //console.log("engList", engList)
        setAvailableEng(engList);
      }); //see all supported voices 
      
    
    
      }, (err) => {
        console.log("TTS not loaded");
        if (err.code === 'no_engine') {
          Tts.requestInstallEngine();
        }
      });

   }
    

    if(voice !== ""){
      Tts.setDefaultVoice(voice);
    }

    if(lang !== ""){
      Tts.setDefaultLanguage(lang);
    }
    
	}, [availableVoice,availableEng, voice,lang, eng]);

  return (
    <View style={{ flexGrow: 1, flex: 1 }}>
      <Text style={styles.mainTitle}>AC Text to Speech</Text>

      <View style={styles.inputBar}>
            <SelectList 
              setSelected={(val: React.SetStateAction<string>) => setVoice(val)} 
              data={availableVoice} 
              save="value"
          />
      </View>

     {/*} <View style={styles.inputBar}>
            <SelectList 
              setSelected={(val: React.SetStateAction<string>) => setLang(val)} 
              data={availableLang} 
              save="value"
          />
  </View>*/}

      <View style={styles.inputBar}>
            <SelectList 
              setSelected={(val: React.SetStateAction<string>) => setEng(val)} 
              data={availableEng} 
              save="value"
          />
      </View>

      <View
              style={styles.inputBar}>        
              <TextInput
                style={styles.textInput}
                placeholder="Enter a message"
                value={msgText}
                onChangeText={(text) =>    setMsgText(text)
                }
              />
              <TouchableOpacity
                        onPress={() => Tts.speak(msgText, {
  androidParams: {
    KEY_PARAM_PAN: -1,
    KEY_PARAM_VOLUME: 0.5,
    KEY_PARAM_STREAM: 'STREAM_MUSIC',
  },
})
                        }
                        style={[styles.sendButton]}>
                        <Text
                          style={styles.buttonText}>
                          Speak
                        </Text>
                      </TouchableOpacity>
        </View>
      {/*<Text>{currentDate}</Text>*/}
      <View style={{flex: 1 }}>

      </View>
    </View>

  )

}

export default App;

let BACKGROUND_COLOR = "#161616"; //191A19
let BUTTON_COLOR = "#346751"; //1E5128
let ERROR_COLOR = "#C84B31"; //4E9F3D
let TEXT_COLOR = "#ECDBBA"; //D8E9A8
var styles = StyleSheet.create({
  mainTitle:{
    color: TEXT_COLOR,
    fontSize: 30,
    textAlign: 'center',
    borderBottomWidth: 2,
    borderBottomColor: ERROR_COLOR,
  },

  backgroundVideo: {
    borderWidth: 2,
    borderColor: 'red',
    position: 'absolute',
    top: 0,
    left: 0,
    bottom: 0,
    right: 0,
  },

  webVideo: {
    borderWidth: 2,
    borderColor: 'green',
    position: 'absolute',
    top: 0,
    left: 0,
    bottom: 0,
    right: 0,
  },

  buttonText: {
    color: TEXT_COLOR,
    fontWeight: 'bold',
    fontSize: 12,
	  textAlign: 'center',
    textAlignVertical: 'center',
  },

  sendButton: {
    backgroundColor: BUTTON_COLOR,
    padding: 15,
    borderRadius: 15,
    margin: 2,
    paddingHorizontal: 20,
    },

  inputBar:{
    flexDirection: 'row',
    justifyContent: 'space-between',
    margin: 5,
  },  

  textInput:{
    backgroundColor: '#888888',
    margin: 2,
    borderRadius: 15,
    flex:3,
  },
});

Aplicações

  • Faça o seu sistema Android falar, quer se trate de um telefone, de um carro ou de um robô!

Fontes