Skip to content

Commit

Permalink
feat: record and play audio
Browse files Browse the repository at this point in the history
  • Loading branch information
hyochan committed May 24, 2024
1 parent eb2e92f commit dab04a3
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 1 deletion.
7 changes: 7 additions & 0 deletions app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ export default ({config}: ConfigContext): ExpoConfig => ({
],
},
],
[
'expo-av',
{
microphonePermission:
'$(PRODUCT_NAME)은(는) 음성 녹음 및 오디오 입력 기능을 제공하기 위해 마이크 접근 권한이 필요합니다. 이러한 기능을 계속 사용하려면 마이크 접근을 허용해 주세요.',
},
],
],
experiments: {
typedRoutes: true,
Expand Down
108 changes: 108 additions & 0 deletions app/audio.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import {useEffect, useState} from 'react';
import {SafeAreaView, View} from 'react-native';
import {css} from '@emotion/native';
import {IconButton, Typography} from 'dooboo-ui';
import {Audio} from 'expo-av';

export default function AudioPage(): JSX.Element {
const [permissionResponse, requestPermission] = Audio.usePermissions();
const [recording, setRecording] = useState<Audio.Recording>();
const [uri, setUri] = useState<string>();
const [sound, setSound] = useState<Audio.Sound>();
const [isPlaying, setIsPlaying] = useState(false);

const _playBack: Audio.Sound['_onPlaybackStatusUpdate'] = (status) => {
if (status.isLoaded) {
if (status.didJustFinish) {
setIsPlaying(false);
}
}
};

useEffect(() => {
return sound
? () => {
sound.unloadAsync();
}
: undefined;
}, [sound]);

const startRecording = async (): Promise<void> => {
try {
if (permissionResponse?.status !== 'granted') {
console.log('Requesting permission..');

Check warning on line 33 in app/audio.tsx

View workflow job for this annotation

GitHub Actions / build

Unexpected console statement
await requestPermission();
}

await Audio.setAudioModeAsync({
allowsRecordingIOS: true,
playsInSilentModeIOS: true,
});

console.log('Starting recording..');

Check warning on line 42 in app/audio.tsx

View workflow job for this annotation

GitHub Actions / build

Unexpected console statement

const {recording: recorded} = await Audio.Recording.createAsync(
Audio.RecordingOptionsPresets.HIGH_QUALITY,
);
setRecording(recorded);
console.log('Recording started');

Check warning on line 48 in app/audio.tsx

View workflow job for this annotation

GitHub Actions / build

Unexpected console statement
} catch (err) {
console.error('Failed to start recording', err);

Check warning on line 50 in app/audio.tsx

View workflow job for this annotation

GitHub Actions / build

Unexpected console statement
}
};

const stopRecording = async (): Promise<void> => {
console.log('Stopping recoasync async recording..');

Check warning on line 55 in app/audio.tsx

View workflow job for this annotation

GitHub Actions / build

Unexpected console statement
setRecording(undefined);
await recording?.stopAndUnloadAsync();
await Audio.setAudioModeAsync({allowsRecordingIOS: false});

const recordingUri = recording?.getURI();
recordingUri && setUri(recordingUri);
};

const playSound = async (): Promise<void> => {
if (uri) {
setIsPlaying(true);

const {sound: audioSound} = await Audio.Sound.createAsync(
{uri},
{},
_playBack,
);
setSound(audioSound);

console.log('Playing Sound');

Check warning on line 75 in app/audio.tsx

View workflow job for this annotation

GitHub Actions / build

Unexpected console statement
await audioSound.playAsync();
}
};

return (
<SafeAreaView
style={css`
flex: 1;
justify-content: center;
align-items: center;
gap: 12px;
`}
>
<Typography.Heading3>Record</Typography.Heading3>
<IconButton
icon={recording ? 'Stop' : 'Microphone'}
onPress={recording ? stopRecording : startRecording}
size={40}
/>
<Typography.Heading3>Play</Typography.Heading3>
<IconButton
icon={isPlaying ? 'Stop' : uri ? 'Play' : 'Question'}
onPress={uri ? (isPlaying ? sound?.stopAsync : playSound) : undefined}
size={40}
/>
<View
style={css`
height: 80px;
`}
/>
</SafeAreaView>
);
}
14 changes: 13 additions & 1 deletion app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ export default function Index(): JSX.Element {
onPress={() => push('/details')}
style={css`
margin-top: 28px;
margin-bottom: 40px;
`}
styles={{
text: css`
Expand All @@ -103,6 +102,19 @@ export default function Index(): JSX.Element {
}}
text={t('SEE_DETAILS')}
/>
<Button
onPress={() => push('/audio')}
style={css`
margin-top: 28px;
margin-bottom: 40px;
`}
styles={{
text: css`
font-family: Pretendard-Bold;
`,
}}
text="음성 녹음"
/>
</Content>
</Container>
);
Expand Down
Binary file modified bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"date-fns": "^3.6.0",
"dooboo-ui": "^0.2.31",
"expo": "~51.0.8",
"expo-av": "~14.0.5",
"expo-constants": "~16.0.1",
"expo-dev-client": "~4.0.14",
"expo-device": "~6.0.2",
Expand Down

0 comments on commit dab04a3

Please sign in to comment.