Last active
April 17, 2018 09:48
-
-
Save cokealmonacid/f15459ea5425f67c6cee09c527117ddc to your computer and use it in GitHub Desktop.
AudioRecorder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'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