Skip to content

Instantly share code, notes, and snippets.

@cokealmonacid
Last active April 17, 2018 09:48
Show Gist options
  • Save cokealmonacid/f15459ea5425f67c6cee09c527117ddc to your computer and use it in GitHub Desktop.
Save cokealmonacid/f15459ea5425f67c6cee09c527117ddc to your computer and use it in GitHub Desktop.
AudioRecorder
'use strict';
import React, { Component } from 'react';
import { View, Text, TouchableOpacity, Platform, Alert, PermissionsAndroid, TextInput } from 'react-native';
import Sound from 'react-native-sound';
import { AudioRecorder, AudioUtils } from 'react-native-audio';
import RNFetchBlob from 'react-native-fetch-blob';
import Icon from 'react-native-vector-icons/Entypo';
import RNPickerSelect from 'react-native-picker-select';
import Spinner from 'react-native-loading-spinner-overlay';
import Header from '../../components/Header2/header';
import API from './../API/ApiComm';
import Styles from './styles';
export default class Record extends Component {
constructor(props) {
super(props);
this.state = {
icon: "controller-play",
text_show: 'Reproducir',
record: false,
play: false,
currentTime: 0,
recording: false,
stoppedRecording: false,
finished: false,
audioPath: AudioUtils.DocumentDirectoryPath + '/test.aac',
hasPermission: undefined,
hasBeenRecorded: false,
code_transformer: null,
seconds: '00:00',
items: [],
selected_id: null,
visible_spinner: false
}
}
componentWillMount() {
this.setState({ visible_spinner: true });
API.getTransformers().then(json => {
let transformers = [];
let data = json.transformers;
data.forEach(function(item){
transformers.push({
label: item.brand+' '+item.model,
value: item.id
});
});
this.setState({ items: transformers });
this.setState({ visible_spinner: false });
}).catch(error => {
this.setState({ visible_spinner: false });
alert('Se ha producido un error');
console.log(error);
});
}
prepareRecordingPath(audioPath){
AudioRecorder.prepareRecordingAtPath(audioPath, {
SampleRate: 22050,
Channels: 1,
AudioQuality: "Low",
AudioEncoding: "aac",
AudioEncodingBitRate: 32000
});
}
componentDidMount() {
this._checkPermission().then((hasPermission) => {
this.setState({ hasPermission });
if (!hasPermission) return;
this.prepareRecordingPath(this.state.audioPath);
AudioRecorder.onProgress = (data) => {
let seconds = Math.floor(data.currentTime);
if (seconds < 10) {
seconds = '00:0'+seconds;
} else {
seconds = '00:'+seconds;
}
this.setState({seconds: seconds});
};
AudioRecorder.onFinished = (data) => {
// Android callback comes in the form of a promise instead.
if (Platform.OS === 'ios') {
this._finishRecording(data.status === "OK", data.audioFileURL);
}
};
});
}
_checkPermission() {
if (Platform.OS !== 'android') {
return Promise.resolve(true);
}
const rationale = {
'title': 'Microphone Permission',
'message': 'AudioExample needs access to your microphone so you can record audio.'
};
return PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.RECORD_AUDIO, rationale)
.then((result) => {
console.log('Permission result:', result);
return (result === true || result === PermissionsAndroid.RESULTS.GRANTED);
});
}
startRecording() {
this.setState({ record: !this.state.record });
if (this.state.record) {
this._pause();
} else {
this._record();
this.setState({ hasBeenRecorded: true });
}
}
async _record() {
if (this.state.recording) {
console.warn('Already recording!');
return;
}
if (!this.state.hasPermission) {
console.warn('Can\'t record, no permission granted!');
return;
}
console.log(this.state.audioPath);
if(this.state.stoppedRecording){
this.prepareRecordingPath(this.state.audioPath);
}
this.setState({recording: true});
try {
const filePath = await AudioRecorder.startRecording();
} catch (error) {
console.error(error);
}
}
async _pause() {
if (!this.state.recording) {
console.warn('Can\'t pause, not recording!');
return;
}
this.setState({stoppedRecording: true, recording: false});
try {
const filePath = await AudioRecorder.pauseRecording();
// Pause is currently equivalent to stop on Android.
if (Platform.OS === 'android') {
this._finishRecording(true, filePath);
}
} catch (error) {
console.error(error);
}
}
async _play() {
if (this.state.recording) {
await this._stop();
}
setTimeout(() => {
var sound = new Sound(this.state.audioPath, '', (error) => {
if (error) {
console.log('failed to load the sound', error);
}
});
setTimeout(() => {
sound.play((success) => {
if (success) {
this.setState({ play: false, icon: 'controller-play', text_show: 'Reproducir' });
console.log('successfully finished playing');
} else {
console.log('playback failed due to audio decoding errors');
}
});
}, 100);
}, 100);
}
async _stop() {
if (!this.state.recording) {
console.warn('Can\'t stop, not recording!');
return;
}
this.setState({stoppedRecording: true, recording: false});
try {
const filePath = await AudioRecorder.stopRecording();
if (Platform.OS === 'android') {
this._finishRecording(true, filePath);
}
this.setState({ record: !this.state.record });
return filePath;
} catch (error) {
console.error(error);
}
}
_finishRecording(didSucceed, filePath) {
this.setState({ finished: didSucceed });
}
showAudio(){
if (!this.state.play && this.state.hasBeenRecorded) {
this.setState({ play: true, icon: 'controller-stop', text_show: 'Detener' });
this._play();
}
}
uploadRecord(){
let code = this.state.code_transformer;
let transformer_id = this.state.selected_id;
let response_alert = '';
if (code == null || transformer_id == null ) {
response_alert = 'Todos los campos son obligatorios\n';
}
if (this.state.hasBeenRecorded != true) {
response_alert += 'Debes grabar un audio antes de almacenar';
}
if (response_alert != '') {
Alert.alert(
'Error',
response_alert
)
}
RNFetchBlob.fs.readFile(this.state.audioPath, 'base64')
.then((data) => {
var audio = data;
if (audio.length != 0) {
var d = new Date();
var data = {
content : audio,
code : code,
TransformerId : transformer_id
}
API.saveRecord(data).then( json => {
Alert.alert(
'Grabación',
'La grabación ha sido almacenada',
false
)
}).catch(error => {
Alert.alert(
'Grabación',
'Se ha producido un error',
false
)
});
}
}, error => {
console.log(error);
});
}
render() {
return(
<View style={Styles.container}>
<Spinner visible={this.state.visible_spinner} overlayColor="rgba(0, 0, 0, .8)" textStyle={{color: '#FFF'}} />
<Header title="Grabar"/>
<View style={Styles.container_buttons}>
<View style={Styles.container_record}>
<Text style={{fontWeight:'bold', textAlign:'center'}}>{this.state.seconds}</Text>
<TouchableOpacity style={Styles.record} onPress={() => this.startRecording()}>
<Icon name="controller-record" size={150} style={[this.state.record ? {color:'red'} : {color:'#000000'}]}/>
</TouchableOpacity>
<Icon.Button size={30} name={this.state.icon} style={[this.state.play ? {backgroundColor:'#3C3C3C'} : {backgroundColor:'#007EF9'}]} color="#FFFFFF" onPress={() => this.showAudio()}>
<Text style={{fontWeight: 'bold', color: '#FFFFFF'}}>{this.state.text_show}</Text>
</Icon.Button>
</View>
<View style={Styles.container_data}>
<TextInput
style={Styles.dataInput}
placeholder="Codigo Transformador"
underlineColorAndroid='transparent'
autoCapitalize='none'
onChangeText={ (text) => this.setState( {code_transformer: text} ) }
/>
<View style={Styles.picker_container}>
<RNPickerSelect
items={this.state.items}
placeholder={{label: 'Selecciona un Transformador', value: null}}
onValueChange={ (item) => this.setState({ selected_id: item }) }>
</RNPickerSelect>
</View>
</View>
<View style={Styles.container_save}>
<TouchableOpacity style={Styles.save_button} onPress={() => this.uploadRecord()}>
<Text style={{fontWeight: 'bold', fontSize: 16, color: '#FFFFFF'}}>Almacenar</Text>
</TouchableOpacity>
</View>
</View>
</View>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment