React Audio Player Component
Build a functional audio player component in React using TypeScript. This component will allow users to play, pause, seek, and control the volume of an audio file, providing a common and essential feature for many web applications.
Problem Description
Your task is to create a reusable AudioPlayer React component. This component should accept an audio file URL as a prop and provide standard playback controls.
Key Requirements:
- Play/Pause Button: A button to toggle between playing and pausing the audio. The button's appearance should visually indicate the current state (e.g., "Play" icon when paused, "Pause" icon when playing).
- Progress Bar (Seek Bar): A visual representation of the audio's current playback progress. Users should be able to click or drag on this bar to seek to a specific point in the audio. The bar should update in real-time as the audio plays.
- Current Time / Duration Display: Display the current playback time and the total duration of the audio in a user-friendly format (e.g.,
MM:SS). - Volume Control: A slider or input field to adjust the audio volume.
- Mute/Unmute Button: A button to quickly mute or unmute the audio. The button's appearance should indicate the mute state.
- Loading State: Handle cases where the audio file is still loading. You might display a placeholder or a loading spinner.
- Error Handling: Gracefully handle potential errors during audio loading or playback.
Expected Behavior:
- When the component mounts, the audio should be loaded but not playing by default.
- Clicking the play button should start playback and change the button to a pause icon.
- Clicking the pause button should pause playback and change the button to a play icon.
- The progress bar should accurately reflect the playback position.
- Interacting with the progress bar should update the playback position.
- The time displays should update as the audio plays.
- Adjusting the volume slider should change the audio's volume.
- Clicking the mute button should toggle mute on/off, and the button's appearance should reflect this.
Edge Cases:
- Audio file fails to load.
- Very short or very long audio files.
- Rapidly clicking play/pause.
- Seeking beyond the end of the audio.
Examples
Example 1: Basic Playback
- Input:
AudioPlayercomponent withsrc="https://example.com/audio.mp3" - Output: A functional audio player UI with a play/pause button, a progress bar, time displays, and a volume control.
- Explanation: The component successfully loads the audio and provides interactive controls for playback.
Example 2: Seeking and Volume Control
- Input: The audio is playing. The user clicks on the progress bar at 50% of its length. Then, the user drags the volume slider to half.
- Output: The audio jumps to the halfway point of its duration. The audio's volume is reduced by half.
- Explanation: The seeking and volume controls function as expected.
Example 3: Mute Functionality
- Input: The audio is playing. The user clicks the mute button. Then clicks it again.
- Output: The audio is muted. The mute button shows an "unmute" icon. The user clicks again, and the audio becomes audible again. The mute button shows a "mute" icon.
- Explanation: The mute/unmute functionality works correctly, with visual feedback on the button.
Constraints
- The
AudioPlayercomponent must be implemented in TypeScript. - The component should accept a single prop:
src(string), representing the URL of the audio file. - The component should not rely on any external UI libraries (e.g., Material UI, Ant Design) for its core functionality, but you can use them for styling if you wish.
- The audio element should be managed internally by the component.
- Performance: The component should be reasonably performant, especially the real-time updates of the progress bar and time displays.
Notes
- You will likely need to use the
useRefhook to get direct access to the HTML<audio>element. - The
audioelement has several helpful event listeners (onplay,onpause,ontimeupdate,onloadedmetadata,onerror, etc.) that you can leverage. - Consider how you will format the time display (e.g., seconds to
MM:SS). A helper function for this would be beneficial. - The progress bar can be implemented using a simple
divwith a background, or a more sophisticated SVG. - Think about accessibility. Ensure your controls are keyboard-navigable and have appropriate ARIA attributes.