Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keep recording after the phone is locked #566

Open
imoxto opened this issue Oct 23, 2023 · 7 comments
Open

Keep recording after the phone is locked #566

imoxto opened this issue Oct 23, 2023 · 7 comments

Comments

@imoxto
Copy link

imoxto commented Oct 23, 2023

Hello, I basically want to run the recording for a while even after the phone is locked. But i couldnt find any ideas on how to go about it in the docs. Any help is appreciated.

Version of react-native-audio-recorder-player

3.6.0

Version of React Native

0.72.4

Platforms you faced the error (IOS or Android or both?)

Android

Expected behavior

Press a button to start recording audio. Then lock the phone. I want to be able to record audio always after the app is locked.

Actual behavior

After locking the phone, it records for about 1 to 3 minutess after locking screen. but afterwards it doesn't record anymore untill the lock is lifted.

Steps to reproduce the behavior

Press a button to start recording audio. Then lock the phone and keep talking for 3 mins. Turn on the phone and stop recording and observe the playback file.

The following is the rough code i used:

import {View, PermissionsAndroid, Alert, Platform} from 'react-native';

import AudioRecorderPlayer, {
  AVEncoderAudioQualityIOSType,
  AVEncodingOption,
  AudioEncoderAndroidType,
  AudioSourceAndroidType,
  OutputFormatAndroidType,
} from 'react-native-audio-recorder-player';
import type {
  AudioSet,
  RecordBackType,
} from 'react-native-audio-recorder-player';

import {IconButton, Text} from 'react-native-paper';
import RNFetchBlob from 'rn-fetch-blob';
import {useUserStore} from '../utils/services';

import {useEffect, useState} from 'react';
import {formatTime} from '../utils';
import Toast from 'react-native-toast-message';

const permissions = [
  PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
  PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
  PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
];

const audioRecorderPlayer = new AudioRecorderPlayer();
audioRecorderPlayer.setSubscriptionDuration(0.5);

const LiveRecord = () => {
  const [permissionGranted, setPermissionGranted] = useState(false);
  const [isRecording, setIsRecording] = useState(false);
  const userId = useUserStore(state => state.user?.uid);

  const [recordTime, setRecordTime] = useState(0);

  useEffect(() => {
    const getPermissions = async () => {
      const granted = await PermissionsAndroid.requestMultiple(permissions);
      const recordAudioGranted =
        granted[PermissionsAndroid.PERMISSIONS.RECORD_AUDIO] === 'granted';

      const externalStorageWriteGranted =
        granted[PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE] ===
        'granted';
      const externalStorageReadGranted =
        granted[PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE] ===
        'granted';

      if (
        !(
          recordAudioGranted ||
          externalStorageWriteGranted ||
          externalStorageReadGranted
        )
      ) {
        Alert.alert('Permissions not granted');
      } else {
        setPermissionGranted(true);
      }
    };

    if (Platform.OS === 'android') {
      getPermissions();
    } else {
      setPermissionGranted(true);
    }
  }, []);

  useEffect(() => {
    if (!permissionGranted) {
      return;
    }
  }, [permissionGranted]);

  const startRecording = async () => {
    const dirs = RNFetchBlob.fs.dirs;
    const path = Platform.select({
      android: `${dirs.CacheDir}/record-${userId}-${new Date().getTime()}.mp3`,
    });
    const audioSet: AudioSet = {
      AudioEncoderAndroid: AudioEncoderAndroidType.AAC,
      AudioSourceAndroid: AudioSourceAndroidType.MIC,
      AVEncoderAudioQualityKeyIOS: AVEncoderAudioQualityIOSType.low,
      AVNumberOfChannelsKeyIOS: 2,
      AVFormatIDKeyIOS: AVEncodingOption.aac,
      OutputFormatAndroid: OutputFormatAndroidType.AAC_ADTS,
    };
    audioRecorderPlayer.removeRecordBackListener();
    audioRecorderPlayer.startRecorder(path, audioSet);
    audioRecorderPlayer.addRecordBackListener((e: RecordBackType) => {
      setRecordTime(e.currentPosition);
    });
    setIsRecording(true);
  };

  const onStopRecord = async () => {
    try {
      const result = await audioRecorderPlayer.stopRecorder();
      audioRecorderPlayer.removeRecordBackListener();
      console.log(result);
    } catch (err) {
      console.error(err);
      Toast.show({
        type: 'error',
        text1: 'Unxpected Error',
        text2: 'Please try again.',
      });
    }
    setIsRecording(false);
    setRecordTime(0);
  };

  return (
    <View style={{flex: 1, backgroundColor: '#1b1e2b'}}>
      <View className="flex flex-col items-center mt-10">
        <View
          className="rounded-full"
          style={{
            elevation: 20,
            shadowColor: '#000000',
            shadowOffset: {
              width: 0,
              height: 10,
            },
            shadowOpacity: 0.3,
            shadowRadius: 10,
            margin: 15,
            // borderRadius: 100,
            backgroundColor: '#2e3246',
          }}>
          {isRecording ? (
            <IconButton
              onPress={onStopRecord}
              icon="microphone"
              size={200}
              iconColor={'#e60000'}
            />
          ) : (
            <IconButton
              onPress={startRecording}
              icon="microphone"
              size={200}
              iconColor={'#613eea'}
            />
          )}
        </View>
      </View>
      <Text
        className="text-center text-5xl pt-10 pb-5 tracking-wider font-normal"
        style={{
          color: isRecording ? '#ffffff' : '#7878A3',
        }}>
        {formatTime(recordTime)}
      </Text>
    </View>
  );
};

export default LiveRecord;
@rohitashPrajapati
Copy link

Hi, have you figured out any workaround for this?

@imoxto
Copy link
Author

imoxto commented Nov 6, 2023

Hi, have you figured out any workaround for this?

For now im just keeping the screen awake while recording

@vijaystroup
Copy link

vijaystroup commented Jan 3, 2024

+1

Submitted this a few days ago as well.

@TheScalion
Copy link

TheScalion commented Jan 8, 2024

Does this NPM supports android API level 33

@Fabian15-03
Copy link

Al parecer no es un tema de la librería como tal, creería que es debido a como el SO lo cataloga. Al usarlo en React Native y tenerlo en segundo plano puede ser que sea menos prioritario que una llamada telefónica que también usa el micrófono pero en una app nativa. De todas formas también tengo el mismo problema (+1). Veo como solución usar un modulo nativo de Kotlin y hacer un bridge a mi app de React Native.

@samadRopstam
Copy link

samadRopstam commented Mar 28, 2024

have you enabled "Audio, AirPlay, and Picture in Picture" option in xcode> Signing&Capabilities > Background Modes?

@jondrews
Copy link

jondrews commented Apr 10, 2024

+1 Experiencing basically the same issue here. Audio keeps recording when the device is locked, but a short time after locking (usually 30secs to 2mins) the audio levels become zero - it just records silence. The audio file then continues to be created, recording silence while the device is locked. When the device is later unlocked, the audio file continues to be created, and instead of recording silence the audio signal is restored to normal expected behaviour.

Any suggestions for improving this behaviour (other than keeping the screen unlocked)?

react-native version: 0.72.4
react-native-audio-recorder-player version: 3.6.0
release build tested on Oppo A52 (CPH2069) w/ Android 11, ColorOS v11.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants