tchvu3 / capacitor-voice-recorder

Capacitor plugin for voice recording
69 stars 57 forks source link

"ERR_REQUEST_RANGE_NOT_SATISFIABLE" error on stopRecording() #25

Closed philipinf closed 1 year ago

philipinf commented 1 year ago

Hi,

I'm trying to record some audio in a web app and sometimes when I call stopRecording the error below appears.

image

I made sure that the recorder was running before pausing by checking if getCurrentStatus() returns 'RECORDING' or 'PAUSED'. This behaviour seems random because it is sometimes working and sometimes not. The error also doesn't get caught by any of the error listeners for the provided functions.

My Setup: Chrome 107.0.5304.107 (Official build) (64-Bit) "@capacitor/core": "^4.5.0" "capacitor-voice-recorder": "^4.0.0"

Thanks for the help in advance Philip

tchvu3 commented 1 year ago

Do you have any more information that can help me reproduce this error? was the recording long or short (can be approx)? did you notice if the error occurred under certain situations? any additional information will be helpful

philipinf commented 1 year ago

Hello, thanks for the quick reply :) The error seems to occur randomly. It happened when I pressed record and then stop immediately after, when I pressed start and after a few seconds / a few more seconds again stop and also when I first pressed start then pause and then stop at different recording lengths. Here is a trimmed-down version of the vue (v2.6.14) code that I've written

<template>
    <div>
        <div v-if="canRecordAudio && hasRecordingPermission">
            <button v-if="!isRecording" @click="startRecording">Record</button>
            <button v-if="isRecording && currentStatus == 'PAUSED'" @click="resumeRecording">Resume</button>
            <button v-if="isRecording && currentStatus == 'RECORDING'" @click="pauseRecording">Pause</button>
            <button v-if="isRecording && currentStatus" @click="stopRecording">Finish</button>
        </div>
    </div>
</template>

<script>
import { VoiceRecorder } from 'capacitor-voice-recorder';
export default {
    name: 'AudioRecorder',
    data() {
        return {
            canRecordAudio: false,
            hasRecordingPermission: false,
            isRecording: false,
            currentStatus: null,
            statusInterval: null,
        };
    },
    created() {
        this.setupRecorder();
        window.addEventListener('unhandledrejection', this.handleUnexpectedError);
    },
    beforeDestroy() {
        this.stopRecording();
        window.removeEventListener('unhandledrejection', this.handleUnexpectedError);
    },
    methods: {
        handleUnexpectedError(e) {
            this.resetRecorder();
        },
        setupRecorder() {
            try {
                VoiceRecorder.canDeviceVoiceRecord().then((result) => {
                    this.canRecordAudio = result.value;
                    if (this.canRecordAudio) {
                        VoiceRecorder.hasAudioRecordingPermission().then((result) => {
                            this.hasRecordingPermission = result.value;
                            if (!result.value) this.checkPermission();
                        });
                    }
                });
            } catch (error) {
                this.resetRecorder();
            }
        },
        checkPermission() {
            try {
                VoiceRecorder.requestAudioRecordingPermission().then((result) => {
                    if (result.value) this.hasRecordingPermission = true;
                });
            } catch (error) {
                this.resetRecorder();
            }
        },
        startRecording() {
            try {
                VoiceRecorder.startRecording()
                    .then((result) => {
                        this.createStatusInterval();
                    })
                    .catch((error) => {
                        this.resetRecorder();
                    });
            } catch (error) {
                this.resetRecorder();
            }
        },
        pauseRecording() {
            try {
                VoiceRecorder.pauseRecording()
                    .then((result) => {})
                    .catch((error) => {
                        this.resetRecorder();
                    });
            } catch (error) {
                this.resetRecorder();
            }
        },
        resumeRecording() {
            try {
                VoiceRecorder.resumeRecording()
                    .then((result) => {})
                    .catch((error) => {
                        this.resetRecorder();
                    });
            } catch (error) {
                this.resetRecorder();
            }
        },
        stopRecording() {
            try {
                if (this.currentStatus == 'RECORDING' || this.currentStatus == 'PAUSED') {
                    this.destroyStatusInterval();
                    VoiceRecorder.stopRecording()
                        .then((result) => {
                            this.isRecording = false;
                        })
                        .catch((error) => {
                            this.resetRecorder();
                        });
                }
            } catch (error) {
                this.resetRecorder();
            }
        },
        createStatusInterval() {
            try {
                this.statusInterval = window.setInterval(function () {
                    VoiceRecorder.getCurrentStatus()
                        .then((result) => {
                            if (result.status == 'NONE') {
                                this.currentStatus = null;
                                this.isRecording = false;
                            } else if (result.status == 'RECORDING') {
                                this.isRecording = true;
                                this.currentStatus = result.status;
                            } else if (result.status == 'PAUSED') {
                                this.isRecording = false;
                                this.currentStatus = result.status;
                            }
                        })
                        .catch((error) => {
                            this.resetRecorder();
                        });
                }, 10);
            } catch (error) {
                this.resetRecorder();
            }
        },
        destroyStatusInterval() {
            if (this.statusInterval) clearInterval(this.statusInterval);
            this.statusInterval = null;
        },
        resetRecorder() {
            this.destroyStatusInterval();
            this.currentStatus = null;
            this.isRecording = false;
        },
    },
};
</script>

<style scoped></style>

I hope this information does help you

tchvu3 commented 1 year ago

I've fixed the issue and updated the version to 4.0.1 please let me know if the problem still persists. now when the recording is length 0 or non-existing the promise will reject with "EMPTY_RECORDING"