I am using both react-native-voice and expo-speech libraries to transcript my voice and to convert a text to a speech. The problem is, when i end registering my voice and start a speech with expo-voice, there is no sound. It seems like react-native-voice completly mutes the audio when the voice recording is ended. The speech starts, but i must press on the mic button (activating the voice recognition) to hear it.
The only way i found to make everything work together is by stopping the voice recording after the text to speech has ended. Here is a part of the code :
const startRecognizing = async () => {
setButtonColor('#38b000');
// Starts listening for speech for a specific locale
try {
await Voice.start('en-EN');
} catch (e) {
console.error(e);
}
};
const destroyRecognizer = async () => {
//Destroys the current SpeechRecognizer instance
try {
await Voice.destroy();
} catch (e) {
console.error(e);
}
};
const stopRecognizing = async () => {
setButtonColor('#344E41');
setTimeout(() => {
Speech.speak("I did not understand, can you repeat please ?", {
language: 'en-EN',
onDone: () => {
setTimeout(
async() => {
await destroyRecognizer();
}, 1000);
},
});
}, 1000);
};
return (
<View style={styles.microphoneButtonContainer}>
<TouchableOpacity
onPressIn={startRecognizing}
onPressOut={stopRecognizing}>
<Image
style={styles.microphoneButton}
source={require('../img/microphone-icon.png')}
/>
</TouchableOpacity>
</View>
);
This solution brings a lot of edgecases so i can't work with it. None of the methods given to stop the recording solve the issue. And i did not found any help in the libraries docs. Is there a solution to this ? Thank you for your help !
Because there was no way to solve the issue with react-native-voice methods, i had the idea to go search directly in the library if i can modify the native code. For ios the code is in ios/voice/Voice.m. I found this :
- (void) teardown {
self.isTearingDown = YES;
[self.recognitionTask cancel];
self.recognitionTask = nil;
// Set back audio session category
[self resetAudioSession];
So i tried to comment out [self resetAudioSession];, i then rebuilt the packages with npx-pod-install (i use cocoapod), and it worked!
Doing this may cause edgecases, i did not fully test the methods yet, and i did not try for android.
Related
I am new to react-native, so there are still some blank spaces. But I am trying to fill them by developing projects. In my current project, I am trying to develop an app which can support the vocabulary learning for English learners. In one screen, user sees a definition of the word and tries to guess the word by giving an input and pressing enter key on the keyboard. The issue is, whenever i guess the word incorrectly, it sends the toast and plays the sound so it works on incorrect guessing. But when i guess it correctly, it also sends the toast and plays the incorrect sound. Here is what I did:
Here is my textinput(from react native paper) code:
<TextInputGuess
label="Guess!"
mode="outlined"
onEndEditing={checkWord}
onChangeText={text => setInput(text)}
/>
Then, here is the checkWord function, which checks the input and compares the real answer and the input:
const checkWord = () => {
console.log(currentCard.word, input)
if (currentCard.word.trim().toLowerCase() === input.trim().toLowerCase() ) {
CorrectWord();
} else {
WrongWord();
}
};
And the WrongWord and CorrectWord functions:
const CorrectWord = () => {
playCorrectSound()
};
const WrongWord = () => {
toast.show('Oops, the word is not correct. Please try again', 500);
playSound();
};
And here is the sound function for the wrong answer and correct answer, respectively:
const [sound, setSound] = React.useState();
async function playSound() {
//console.log('Loading Sound');
const { sound } = await Audio.Sound.createAsync( require('../../../assets/sounds/incorrect.mp3')
);
setSound(sound);
//console.log('Playing Sound');
await sound.playAsync();
React.useEffect(() => {
return sound
? () => {
console.log('Unloading Sound');
sound.unloadAsync();
}
: undefined;
}, [sound]);
};
const [correctSound, setCorrectSound] = React.useState();
async function playCorrectSound() {
console.log('Loading Sound');
const { correctSound } = await Audio.Sound.createAsync( require('../../../assets/sounds/positive-beeps.mp3')
);
setSound(correctSound);
console.log('Playing Sound');
await correctSound.playAsync();
React.useEffect(() => {
return correctSound
? () => {
console.log('Unloading Sound');
correctSound.unloadAsync();
}
: undefined;
}, [correctSound]);
};
Thank you to everyone in advance who spares their time. If you feel like you need more information, please ask me to send them.
I couldn't do so many things because my knowledge is limited. I mainly utilized the code that I found from internet for example sound playing functions. That is why i couldn't do so much. Instead, I tried to get help from a friend and he also couldn't provide any solution.
I'm a beginner at React Native.
I am trying to access a native(built-in) camera app on Android device.
I used React-Native-Image-Picker to open the camera app but I would like to record a video somehow automatically(?) I mean not using my finger.
I need codes that make it to record and stop the video.
(I don't mean to give me a code rather, please advise if it is even possible?)
Any help would be very appreciated.
Thank you!
It is possible.
Package: https://github.com/mrousavy/react-native-vision-camera
Review the API and Guide section to see how to start and stop recording programmatically.
They also show an example app that demonstrates different types of capture including video recording, ref: https://github.com/mrousavy/react-native-vision-camera/blob/28fc6a68a5744efc85b532a338e2ab1bc8fa45fe/example/src/views/CaptureButton.tsx
...
const onStoppedRecording = useCallback(() => {
isRecording.current = false;
cancelAnimation(recordingProgress);
console.log('stopped recording video!');
}, [recordingProgress]);
const stopRecording = useCallback(async () => {
try {
if (camera.current == null) throw new Error('Camera ref is null!');
console.log('calling stopRecording()...');
await camera.current.stopRecording();
console.log('called stopRecording()!');
} catch (e) {
console.error('failed to stop recording!', e);
}
}, [camera]);
const startRecording = useCallback(() => {
try {
if (camera.current == null) throw new Error('Camera ref is null!');
console.log('calling startRecording()...');
camera.current.startRecording({
flash: flash,
onRecordingError: (error) => {
console.error('Recording failed!', error);
onStoppedRecording();
},
onRecordingFinished: (video) => {
console.log(`Recording successfully finished! ${video.path}`);
onMediaCaptured(video, 'video');
onStoppedRecording();
},
});
// TODO: wait until startRecording returns to actually find out if the recording has successfully started
console.log('called startRecording()!');
isRecording.current = true;
} catch (e) {
console.error('failed to start recording!', e, 'camera');
}
}, [camera, flash, onMediaCaptured, onStoppedRecording]);
//#endregion
...
I've recently been producing an app on a real-native basis. I also put in an ad banner using Google's admob There is no advertisement that used to appear until a few days ago.
Setting the admob props below will result in an error.
<AdMobBanner
bannerSize="banner"
adUnitID="ca-app-pub-#######"
testDeviceID="EMULATOR"
servePersonalizedAds = {true}
onDidFailToReceiveAdWithError={this.bannerError}
/>
The errors are as follows.
The `testDeviceID` prop of AdMobBanner is deprecated. Test device IDs are now set globally. Use AdMob.setTestDeviceIDAsync instead.
I'd appreciate it if you could help me.
I had the same problem, They should update the information on the Expo site. I believe this should work for the banner as well.
Import:
import {
setTestDeviceIDAsync, //<--- I forgot this first time
AdMobInterstitial
}from 'expo-ads-admob';
init after mount:
componentDidMount(){
this.initAds().catch((error) => console.log(error));
}
initAds = async () => {
AdMobInterstitial.setAdUnitID('ca-app-pub-3940256099942544/1033173712') //test id
await setTestDeviceIDAsync('EMULATOR');
}
Trigger this function from a button or what ever you like:
_openInterstitial = async () => {
try {
this.setState({ disableInterstitialBtn: true })
await AdMobInterstitial.requestAdAsync()
await AdMobInterstitial.showAdAsync()
} catch (error) {
console.error(error)
} finally {
this.setState({ disableInterstitialBtn: false })
}
}
In React native, when I start speech recognition it gives beep sound.
Code that I used to start recognition :
_startRecognizing = async() => {
try {
await Voice.start();
} catch (e) {
console.log(e);
}
};
Library used : https://github.com/react-native-community/react-native-voice
Is there any way to mute this Beep sound in android?
There seems to be no solution to this request yet
See here
Here is some of my code:
<TouchableOpacity
style={styles.button}
onPress={this.onPress}
>
<Text> Play Sound </Text>
</TouchableOpacity>
I want to write a function "onPress" which will play an .mp3 sound.
I have already imported react-native-sound and have my .mp3 file ready to go, I just don't know how to play the sound once the onPress function is called.
In my opinion, if you want to listen the sound, you can try this.
Syntax = react.
Import Sound from "react-native-sound";
Sound.setCategory('Playback');
const whoosh = new Sound('whoosh.mp3', Sound.MAIN_BUNDLE, (error) => {
if (error) {
console.log('failed to load the sound', error);
return;
};
whoosh.play((success) => {
if (success) {
console.log('successfully finished playing');
} else {
console.log('playback failed due to audio decoding errors');
reset the player to its uninitialized state (android only)
whoosh.reset();
}
The easiest way is First to create a new instance like Following.
create this in a constructor to load it when the component mount
Note: please put your mp3 or wav file in android/app/src/main/res/raw
const whoosh = new Sound('swoosh.mp3', Sound.MAIN_BUNDLE);
just call it in your function
whoosh.play()
npm install react-native-sound and link with your project.
Import sound from react-native-sound
// or
import Sound from 'react-native-sound';
Put your mp3 file inside the folder and mention the path:
const requireAudio = require('./xyz.mp3');
Place this code inside your "onPress" function.
const s = new Sound(requireAudio, (e) => {
if (e) {
console.log('Error in SOUND', e);
return;
}
s.play(() => s.release());
});