expotext-to-speech

Expo-speech not working on some iOS devices


I'm using expo-speech in my app but the text is not read out in some iOS devices. From getting my friends to test it the results I have are:

Works:

Not working:

It also works fine in every iOS simulator that Ive tried when developing locally.

Ive created a very simple repo (link below) to test it out with this code:

import React from 'react';
import * as Speech from "expo-speech";
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  setInterval(()=>{
    Speech.speak(`I am a test`);
  }, 2000);

  return (
     <View style={styles.container}>
      <Text>Open up App.tsx to start working on your app!</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

https://snack.expo.io/@jamesweblondon/sound-test

Using the Expo app to test it on an iPhone 8 13.4.1 it's also not working.

UPDATE: It turns out that it's silent mode that's causing this: https://github.com/expo/expo/issues/8235

The ideal solution would be to make the sound play anyway as YouTube etc does.

Second best would be to detect silent mode in iOS so I can at least notify the user that this feature won't work and how to fix it.


Solution

  • I was facing the same issue on my workout-time app because of silent mode.

    Expo Solution:

    we can use expo-av expo library to play speech on slient mode by playsInSilentModeIOS: true

    in expo text to speech is working when other sound is in playing mode. So you can attach empty sound

    download empty sound from here

    import React, { useEffect } from "react";
    import * as Speech from "expo-speech";
    import { StyleSheet, Text, View, Platform } from "react-native";
    import { Audio } from "expo-av";
    const soundObject = new Audio.Sound();
    
    export default function App() {
      useEffect(() => {
        const enableSound = async () => {
          if (Platform.OS === "ios") {
            await Audio.setAudioModeAsync({
              playsInSilentModeIOS: true,
            });
            await soundObject.loadAsync(require("./soundFile.mp3"));
            await soundObject.playAsync();
          }
    
          setInterval(() => {
            Speech.speak(`I am a test`);
          }, 1000);
        };
        enableSound();
      });
    
      return (
        <View style={styles.container}>
          <Text>Open up App.tsx to start working on your app!</Text>
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: "#fff",
        alignItems: "center",
        justifyContent: "center",
      },
    });
    
    

    React-Native Solution:

    var Sound = require('react-native-sound');
    
    Sound.setCategory('Playback'); // this will enable sound on silent mode