UNPKG

react-native-beautiful-video-recorder

Version:
216 lines (198 loc) 5.42 kB
import React, { Component } from 'react'; import { Modal, View, TouchableWithoutFeedback, TouchableOpacity, Text, InteractionManager, } from 'react-native'; import PropTypes from 'prop-types' import moment from 'moment'; import { RNCamera } from 'react-native-camera'; import RecordingButton from './RecordingButton'; import styles, { buttonClose, durationText, renderClose, renderDone } from './style'; export default class VideoRecorder extends Component { static propTypes = { isOpen: PropTypes.bool, runAfterInteractions: PropTypes.bool, cameraOptions: PropTypes.shape({}), recordOptions: PropTypes.shape({}), buttonCloseStyle: PropTypes.shape({}), durationTextStyle: PropTypes.shape({}), renderClose: PropTypes.func, renderDone: PropTypes.func, } static defaultProps = { isOpen: false, runAfterInteractions: true, cameraOptions: {}, recordOptions: {}, buttonCloseStyle: buttonClose, durationTextStyle: durationText, renderClose, renderDone, } constructor(...props) { super(...props); this.state = { isOpen: this.props.isOpen, loading: true, time: 0, recorded: false, recordedData: null }; } componentDidMount() { const doPostMount = () => this.setState({ loading: false }); if (this.props.runAfterInteractions) { InteractionManager.runAfterInteractions(doPostMount); } else { doPostMount(); } } onSave = () => { if (this.callback) { this.callback(this.state.recordedData); } this.close(); } open = (options, callback) => { this.callback = callback; this.setState({ maxLength: -1, ...options, isOpen: true, isRecording: false, time: 0, recorded: false, recordedData: null, converting: false, }); } close = () => { this.setState({ isOpen: false }); } startCapture = () => { const shouldStartCapture = () => { this.camera.recordAsync(this.props.recordOptions) .then((data) => { console.log('video capture', data); this.setState({ recorded: true, recordedData: data, }); }).catch(err => console.error(err)); setTimeout(() => { this.startTimer(); this.setState({ isRecording: true, recorded: false, recordedData: null, time: 0, }); }); }; if ((this.state.maxLength > 0) || (this.state.maxLength < 0)) { if (this.props.runAfterInteractions) { InteractionManager.runAfterInteractions(shouldStartCapture); } else { shouldStartCapture(); } } } stopCapture = () => { const shouldStopCapture = () => { this.stopTimer(); this.camera.stopRecording(); this.setState({ isRecording: false, }); }; if (this.props.runAfterInteractions) { InteractionManager.runAfterInteractions(shouldStopCapture); } else { shouldStopCapture(); } } startTimer = () => { this.timer = setInterval(() => { const time = this.state.time + 1; this.setState({ time }); if (this.state.maxLength > 0 && time >= this.state.maxLength) { this.stopCapture(); } }, 1000); } stopTimer = () => { if (this.timer) clearInterval(this.timer); } convertTimeString = (time) => { return moment().startOf('day').seconds(time).format('mm:ss'); } renderTimer() { const { isRecording, time, recorded } = this.state; return ( <View> { (recorded || isRecording) && <Text style={this.props.durationTextStyle}> <Text style={styles.dotText}>●</Text> {this.convertTimeString(time)} </Text> } </View> ); } renderContent() { const { isRecording, recorded } = this.state; return ( <View style={styles.controlLayer}> {this.renderTimer()} <View style={[styles.controls]}> <RecordingButton style={styles.recodingButton} isRecording={isRecording} onStartPress={this.startCapture} onStopPress={this.stopCapture} /> { recorded && <TouchableOpacity onPress={this.onSave} style={styles.btnUse}> {this.props.renderDone()} </TouchableOpacity> } </View> </View> ); } renderCamera() { return ( <RNCamera ref={(cam) => { this.camera = cam; }} style={styles.preview} {...this.props.cameraOptions} captureAudio > {this.renderContent()} </RNCamera> ); } render() { const { loading, isOpen } = this.state; if (loading) return <View />; return ( <Modal visible={isOpen} transparent animationType="fade" onRequestClose={this.close}> <View style={styles.modal}> <TouchableWithoutFeedback onPress={this.close}> <View style={styles.backdrop} /> </TouchableWithoutFeedback> <View style={styles.container}> <View style={styles.content}> {this.renderCamera()} </View> <TouchableOpacity onPress={this.close} style={this.props.buttonCloseStyle}> {this.props.renderClose()} </TouchableOpacity> </View> </View> </Modal> ); } }