Javascript 为什么在使用handlebackpress方法进行控制台操作时,即使在执行clearInterval之后,计时器也不会回到零位?如何避免丢失帧
我试图自动启动视频,但在此之前,实现计时器并清除计时器是我的目标。倒计时正在被清除,但即使在被清除后,处于“我的设置间隔”被分配状态的计时器仍会继续增加。此外,在每次切换时都会有大量的帧丢失和口吃,即使我的代码变得太混乱,我也非常感谢任何帮助,帮助我改进我的混乱代码并避免丢失的帧 多谢各位Javascript 为什么在使用handlebackpress方法进行控制台操作时,即使在执行clearInterval之后,计时器也不会回到零位?如何避免丢失帧,javascript,react-native,Javascript,React Native,我试图自动启动视频,但在此之前,实现计时器并清除计时器是我的目标。倒计时正在被清除,但即使在被清除后,处于“我的设置间隔”被分配状态的计时器仍会继续增加。此外,在每次切换时都会有大量的帧丢失和口吃,即使我的代码变得太混乱,我也非常感谢任何帮助,帮助我改进我的混乱代码并避免丢失的帧 多谢各位 import React, { Component } from 'react'; import { Platform, StyleSheet,
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
BackHandler,
TouchableOpacity,
View,
Alert,
PermissionsAndroid,
CameraRoll,
} from 'react-native';
import { RNCamera } from 'react-native-camera';
import RNFetchBlob from 'rn-fetch-blob';
const url = 'MY API';
export default class App extends Component {
constructor() {
super();
this.state = {
showCamera: false,
cameraType: RNCamera.Constants.Type.front,
recording: false,
timer: null,
count: null
};
}
componentDidMount() {
this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
this.permissionRequest();
}
componentWillUnmount() {
this.backHandler.remove();
}
async permissionRequest() {
try {
const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
'title': 'Require Permission for Storage',
'message': 'Storage permisson is required to store your photos in the gallery'
});
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('granted', PermissionsAndroid.RESULTS);
} else {
console.warn('denied', PermissionsAndroid.RESULTS);
}
} catch (err) {
console.warn('err', err);
}
}
handleBackPress = async () => {
if (this.state.showCamera === true) {
await this.setState({ showCamera: false });
clearInterval(this.state.timer);
console.log('this.state.timer', this.state.timer);
// this.setState({ count: null });
console.log('this.state.timer after', this.state.timer, this.state.count);
} else {
BackHandler.exitApp();
}
}
async toggleCamera() {
// console.log(this,'this');
await this.setState({ showCamera: !this.state.showCamera });
console.warn(this.state.showCamera, 'checking status');
if (this.state.showCamera === true) {
this.setState({ count: 10 });
let timer = setInterval(this.tickingTimer, 1000);
this.setState({ timer });
}
}
tickingTimer = () => {
if (this.state.count > 0) {
this.setState({ count: this.state.count -1 });
console.log(this.state.count);
}
}
async takePicture() {
if (this.camera) {
const options = { quality: 0.9, base64: true };
const data = await this.camera.takePictureAsync(options);
CameraRoll.saveToCameraRoll(data.uri)
.then(resp => {
console.log('resp', resp);
})
.catch(err => {
console.log('err', err);
});
console.log(data);
}
}
async recordVideo() {
if (this.camera) {
this.setState({ recording: true });
const options = { quality: 'RNCamera.Constants.VideoQuality.480p', maxDuration: 2 };
const {uri, codec = 'mp4' } = await this.camera.recordAsync(options);
this.setState({ recording: false });
const type = `video/${codec}`;
CameraRoll.saveToCameraRoll(uri)
.then(resp => {
console.log('video resp', resp)
})
.catch(err => {
console.log('err Video', err);
})
RNFetchBlob.fetch('POST', url + 'upload', {
},
[
{
name: 'file',
filename: 'filename.mp4',
data: RNFetchBlob.wrap(uri),
type
}
]
)
.uploadProgress({ interval : 200 }, (written, total) => {
console.log('progress', written, total, written / total)
})
.then(res => JSON.parse(res.data))
.then((res) => {
console.log(' server', res.file.URL);
})
.catch((err) => {
console.log('error ', err);
});
}
}
async stopVideo() {
if (this.camera) {
await this.camera.stopRecording();
this.setState({ recording: false });
}
}
swapCamera() {
const { cameraType } = this.state;
let newType;
if (this.camera) {
cameraType === RNCamera.Constants.Type.front ? newType = RNCamera.Constants.Type.back : newType = RNCamera.Constants.Type.front;
}
this.setState({ cameraType: newType });
}
render() {
const { showCamera, recording, cameraType, count } = this.state;
return (
<View style={styles.container}>
{
showCamera === false ?
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<TouchableOpacity style={{ height: 50, width: 80, marginVertical: 5, justifyContent: 'center', alignItems: 'center', borderRadius: 5, backgroundColor: 'rgba(52,130,116,0.9)' }} onPress={() => this.toggleCamera()}>
<Text style={{ color: 'white', textAlign: 'center' }}>Open Camera</Text>
</TouchableOpacity>
<TouchableOpacity style={{ height: 50, width: 80, marginVertical: 5, justifyContent: 'center', alignItems: 'center', borderRadius: 5, backgroundColor: 'rgba(52,130,116,0.9)' }} onPress={() => this.toggleCamera()}>
<Text style={{ color: 'white', textAlign: 'center' }}>Record Video</Text>
</TouchableOpacity>
</View>
:
<RNCamera style={{ flex: 1, alignItems: 'center', justifyContent: 'flex-end' }} ref={ref => { this.camera = ref }} flashMode={RNCamera.Constants.FlashMode.auto} captureAudio = {true} type={cameraType}>
<View style={{ flexDirection: 'row', marginVertical: 20 }}>
<View style={{ flex: 0.3, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ color: 'white' }}>starts in <Text style={{color: 'red', fontWeight: 'bold', fontSize: 16 }}>{count}</Text></Text>
</View>
<View style={{ flex: 0.3, justifyContent: 'center', alignItems: 'center' }}>
<View style={{ height: 60, width: 60, marginHorizontal: 5, borderRadius: 30, padding: 5, borderWidth: 2, borderColor: 'white' }}>
{recording === false ?
<TouchableOpacity disabled={this.state.count !== 0} onPress={() => this.recordVideo()} style={{ flex: 1, borderRadius: 30, backgroundColor: 'white', alignItems: 'center', justifyContent: 'center' }} /> :
<TouchableOpacity onPress={() => this.stopVideo()} style={{ flex: 1, borderRadius: 30, backgroundColor: 'red', alignItems: 'center', justifyContent: 'flex-end' }} />
}
</View>
</View>
<View style={{ flex: 0.4 }}>
<TouchableOpacity onPress={() => this.swapCamera()} style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ color: 'white' }}>Swap</Text>
</TouchableOpacity>
</View>
</View>
</RNCamera>
}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
capture: {
flex: 0,
backgroundColor: '#fff',
borderRadius: 5,
padding: 15,
paddingHorizontal: 20,
alignSelf: 'center',
margin: 20
}
});
// This is my package.json file
{
"name": "newApp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.3.1",
"react-native": "0.55.4",
"react-native-camera": "git+https://git@github.com/react-native-community/react-native-camera",
"react-native-easy-toast": "^1.1.0",
"react-native-progress-circle": "^2.0.0",
"rn-fetch-blob": "^0.10.13"
},
"devDependencies": {
"babel-jest": "22.4.4",
"babel-preset-react-native": "4.0.0",
"jest": "22.4.4",
"react-test-renderer": "16.3.1"
},
"jest": {
"preset": "react-native"
}
}
import React,{Component}来自'React';
进口{
平台,
样式表,
文本,
后台处理程序,
可触摸不透明度,
看法
警觉的,
许可证Sandroid,
摄影师,
}从“反应本机”;
从“react native camera”导入{RNCamera};
从“rn fetch blob”导入RNFETCH blob;
consturl='myapi';
导出默认类应用程序扩展组件{
构造函数(){
超级();
此.state={
摄像机:错,
cameraType:RNCamera.Constants.Type.front,
录音:错,
计时器:空,
计数:空
};
}
componentDidMount(){
this.backHandler=backHandler.addEventListener('hardwareBackPress',this.handleBackPress');
此.permissionRequest();
}
组件将卸载(){
this.backHandler.remove();
}
异步许可请求(){
试一试{
const grated=wait PERMISSIONS和roid.request(PERMISSIONS和roid.PERMISSIONS.WRITE\u外部存储、,
{
“标题”:“需要存储权限”,
“消息”:“在库中存储照片需要存储许可证”
});
如果(已授予===权限sandroid.RESULTS.已授予){
console.log('prograted',PermissionsAndroid.RESULTS);
}否则{
console.warn('denied',PermissionsAndroid.RESULTS);
}
}捕捉(错误){
console.warn('err',err);
}
}
handleBackPress=async()=>{
if(this.state.showCamera===true){
等待此.setState({showCamera:false});
clearInterval(this.state.timer);
log('this.state.timer',this.state.timer);
//this.setState({count:null});
log('this.state.timer after',this.state.timer,this.state.count);
}否则{
BackHandler.exitApp();
}
}
异步切换摄影机(){
//log(this,'this');
等待此.setState({showCamera:!this.state.showCamera});
console.warn(this.state.showCamera,“检查状态”);
if(this.state.showCamera===true){
this.setState({count:10});
让定时器=设置间隔(this.tickingTimer,1000);
this.setState({timer});
}
}
滴答时间=()=>{
如果(this.state.count>0){
this.setState({count:this.state.count-1});
console.log(this.state.count);
}
}
异步takePicture(){
如果(这个相机){
const options={quality:0.9,base64:true};
const data=wait this.camera.takePictureAsync(选项);
CameraRoll.saveToCameraRoll(data.uri)
。然后(resp=>{
控制台日志('resp',resp);
})
.catch(错误=>{
console.log('err',err);
});
控制台日志(数据);
}
}
异步录制视频(){
如果(这个相机){
this.setState({recording:true});
const options={quality:'RNCamera.Constants.VideoQuality.480p',maxDuration:2};
const{uri,codec='mp4'}=wait this.camera.recordAsync(选项);
this.setState({recording:false});
const type=`video/${codec}`;
CameraRoll.saveToCameraRoll(uri)
。然后(resp=>{
console.log('video resp',resp)
})
.catch(错误=>{
console.log('err Video',err);
})
RNFetchBlob.fetch('POST',url+'upload'{
},
[
{
名称:'文件',
filename:'filename.mp4',
数据:RNFetchBlob.wrap(uri),
类型
}
]
)
.uploadProgress({interval:200},(已写入,总计)=>{
console.log(‘进度’、已写入、总计、已写入/总计)
})
.then(res=>JSON.parse(res.data))
。然后((res)=>{
log('server',res.file.URL);
})
.catch((错误)=>{
console.log('error',err);
});
}
}
异步停止视频(){
如果(这个相机){
等待此消息。照相机。停止录制();
this.setState({recording:false});
}
}
swapCamera(){
const{cameraType}=this.state;
让新类型;
如果(这个相机){
cameraType===RNCamera.Constants.Type.front?newType=RNCamera.Constants.Type.back:newType=RNCamera.Constants.Type.front;
}
this.setState({cameraType:newType});
}
render(){
const{showCamera,recording,cameraType,count}=this.state;
返回(
{
showCamera==假?
this.setState({ showCamera: false }, () => {
clearInterval(this.timer);
});