Student starter code (30% baseline)
index.html- Main HTML pagescript.js- JavaScript logicstyles.css- Styling and layoutpackage.json- Dependenciessetup.sh- Setup scriptREADME.md- Instructions (below)๐ก Download the ZIP, extract it, and follow the instructions below to get started!
By completing this activity, you will:
# Install dependencies
npm install --legacy-peer-deps
# Start the development server
npm start
What You'll Experience:
This activity transforms a broken timer into a fully functional voice recording studio.
โ Fully Functional:
โ ๏ธ Needs Implementation (Your TODOs):
Goal: Complete the timer system so users can track recording duration in real-time!
File: App.js (line ~36)
The recording starts but the duration stays at 00:00! Implement a timer that counts up every second:
// TODO: Start duration timer
// Inside startRecording() function, after setDuration(0):
const intervalId = setInterval(() => {
setDuration(prevDuration => prevDuration + 1);
}, 1000);
// Store the interval ID so you can clear it later
// You'll need to use useRef to store this across renders
Success Criteria:
Why: setInterval runs a function repeatedly. We use prevDuration => prevDuration + 1 to safely increment based on the previous state.
Expected Output: While recording, you'll see duration increment: 1, 2, 3, 4...
File: App.js (line ~50)
When you stop recording, the timer keeps running in the background! Clear the interval:
// TODO: Stop the duration timer
// Inside stopRecording() function:
clearInterval(intervalId); // Clear the interval you created in startRecording
Success Criteria:
Why: clearInterval stops the repeating function. Without this, the timer keeps running even after recording stops, causing memory leaks and incorrect values.
Expected Behavior: Timer stops immediately when you press "Stop Recording".
File: App.js (line ~80)
Durations show as "00:00" instead of "05:32". Format seconds into MM:SS:
function formatDuration(seconds) {
// TODO: Format duration as MM:SS
const minutes = Math.floor(seconds / 60);
const remainingSeconds = seconds % 60;
// Add leading zeros: 5 becomes "05"
const formattedMinutes = String(minutes).padStart(2, '0');
const formattedSeconds = String(remainingSeconds).padStart(2, '0');
return `${formattedMinutes}:${formattedSeconds}`;
}
Success Criteria:
Why:
Math.floor(seconds / 60) gets whole minutes (e.g., 65 seconds = 1 minute)seconds % 60 gets remaining seconds (e.g., 65 % 60 = 5 seconds)padStart(2, '0') adds leading zero if neededExamples:
Expected: Real-time timer showing accurate duration
Expected: Timer freezes at the correct value
Expected: Each recording saves its duration correctly
Expected: Audio plays successfully
For students who want to go beyond:
Add ability to pause recording without stopping:
Hint: Use recording.pauseAsync() and recording.startAsync()
Let users trim recordings after saving:
Hint: Explore expo-av's Audio.Sound methods for position control
Add audio effects to recordings:
Hint: Use Audio.Sound's setRateAsync() for speed, explore native audio libraries for effects
Record multiple audio tracks and mix them:
Hint: You'll need to play existing audio while recording new audio simultaneously
Transcribe recordings to text:
Hint: Integrate with Expo Speech Recognition or cloud services like Google Speech-to-Text
Show visual waveform while recording:
Hint: Use recording.setOnRecordingStatusUpdate() to get audio metering data
setInterval(): Run function repeatedly every X millisecondsclearInterval(): Stop a running intervalMath.floor(): Round down to get whole minutes%): Get remainder (for seconds)padStart(): Add leading zeros to stringsAudio.requestPermissionsAsync()Audio.setAudioModeAsync()This recording functionality is used in:
Voice Memo Apps
Podcast Apps
Language Learning
Music Apps
Interview Apps
Meditation Apps
setInterval() in startRecording()setDuration(prev => prev + 1)clearInterval(intervalId) in stopRecording()useRef to persist the interval ID between rendersduration state is initialized to 0formatDuration()parseInt() or Math.floor() for calculationssetAudioModeAsync()Sound.createAsync() receives valid URIawait sound.playAsync() to start playbackBefore submitting, ensure:
Need Help? Review Concept 16: Sound Recording, or ask in the course discussion forum!