I’m working on a custom audio player in React with Bootstrap, and I want to make it possible to fast forward or rewind the playback by 5 seconds.
I also want to be able to change the time using a slider.
This somehow does not work.
CURRENTLY the code behaves in such a way that if I fast forward or rewind 5 seconds the MP-3 starts again.
App.js
import "bootstrap/dist/css/bootstrap.min.css";
import "./index.scss";
import { Button, Card, Container, ProgressBar } from "react-bootstrap";
import AudioPlayer from "./components/AudioPlayer";
export default function App() {
return (
<div className="App">
<Container>
<h1>Hello CodeSandbox</h1>
<Card>
<Card.Header> Audio </Card.Header>
<Card.Body>
<AudioPlayer
audioSrc="/assets/Test_ogg_mp3_48kbps.wav.ogg"
name="Lehrpfad Audio 1"
/>
</Card.Body>
</Card>
</Container>
</div>
);
}
AudioPlayer
import React from "react";
import { Button, ProgressBar, InputGroup, FormControl } from "react-bootstrap";
import {
PlayCircleFill,
PauseCircleFill,
VolumeMuteFill,
VolumeDownFill,
VolumeUpFill,
} from "react-bootstrap-icons";
class AudioPlayer extends React.Component {
constructor(props) {
super(props);
this.audioRef = React.createRef();
this.audioSrc = props.audioSrc;
this.state = {
isPlaying: false,
currentTime: 0,
volume: 1, // Range between 0 and 1
progress: 0,
};
}
togglePlayPause() {
const { isPlaying } = this.state;
const audio = this.audioRef.current;
if (isPlaying) {
audio.pause();
} else {
audio.play();
}
this.setState({ isPlaying: !isPlaying });
}
handleTimeUpdate() {
const audio = this.audioRef.current;
if (audio && !isNaN(audio.duration)) {
const progressPercentage = (audio.currentTime / audio.duration) * 100;
this.setState({ progress: progressPercentage });
if (progressPercentage >= 100) {
this.setState({ isPlaying: false, progress: 0 });
}
}
}
getVolumeIcon() {
const { volume } = this.state;
if (volume <= 0) {
return <VolumeMuteFill />;
} else if (volume > 0 && volume <= 0.5) {
return <VolumeDownFill />;
} else {
return <VolumeUpFill />;
}
}
handleVolumeChange(e) {
const newVolume = e.target.value;
this.setState({ volume: newVolume });
if (this.audioRef.current) {
this.audioRef.current.volume = newVolume;
}
}
skipTime(seconds) {
const player = document.getElementById("Player");
if (player && !isNaN(player.currentTime)) {
player.currentTime += seconds;
this.setState();
}
}
render() {
const { isPlaying, progress, volume } = this.state;
return (
<div className="container mt-5 audio-player">
<audio
id="Player"
ref={this.audioRef}
src={this.audioSrc} // Ersetze dies durch den Pfad zu deiner Audiodatei
onTimeUpdate={this.handleTimeUpdate.bind(this)}
onEnded={() => this.setState({ isPlaying: false })}
/>
<div className="d-flex align-items-center">
<Button variant="primary" onClick={() => this.skipTime(-5)}>
{" "}
-5s{" "}
</Button>
<Button
variant="primary"
onClick={this.togglePlayPause.bind(this)}
className="mx-2"
>
{isPlaying ? <PauseCircleFill /> : <PlayCircleFill />}
</Button>
<Button variant="primary" onClick={() => this.skipTime(5)}>
{" "}
+5s{" "}
</Button>
</div>
<ProgressBar
striped
variant="success"
now={progress}
label={`${Math.round(progress)}%`}
/>
<InputGroup className="mt-3">
<InputGroup.Text>{this.getVolumeIcon()}</InputGroup.Text>
<FormControl
type="range"
min="0"
max="1"
step="0.1"
value={volume}
onChange={this.handleVolumeChange.bind(this)}
/>
</InputGroup>
</div>
);
}
}
export default AudioPlayer;
I tried everything that came into my mind but i was not sucessfull.
I did accept that a method would change the time.
codesandbox.io snippet
2
Answers