Skip to content

Instantly share code, notes, and snippets.

@lek890
Created July 8, 2021 14:20
Show Gist options
  • Save lek890/f862fae593b2e49752b59ce97cd29605 to your computer and use it in GitHub Desktop.
Save lek890/f862fae593b2e49752b59ce97cd29605 to your computer and use it in GitHub Desktop.
import React from "react";
import Controls from "./Controls";
const tracks = [
"bensound-acousticbreeze.mp3",
"https://rss.art19.com/episodes/f806adfc-e38a-45ae-8816-ab94beaa7dd1.mp3?rss_browser=BAhJIglGWUVPBjoGRVQ%3D–b8c3f2cb22145d5584957642b8314a01f09a8949"
];
function App(props) {
const [track, setTrack] = React.useState(tracks[0]);
const audioRef = React.useRef(new Audio(track));
const [isPlaying, setIsPlaying] = React.useState(false);
const intervalRef = React.useRef();
const [progress, setProgress] = React.useState(0);
const isReady = React.useRef(false);
React.useEffect(() => {
if (isPlaying) {
const promise = audioRef.current.play();
promise.then().catch((err) => console.log("error--", err));
} else {
audioRef.current.pause();
}
}, [isPlaying]);
const togglePlaying = () => {
setIsPlaying((isPlaying) => !isPlaying);
};
const onSeek = (value) => {
if (audioRef?.current) {
clearInterval(intervalRef.current);
audioRef.current.currentTime = value;
setProgress(audioRef.current.currentTime);
}
};
const startOver = () => {
if (audioRef?.current) {
audioRef.current.currentTime = 0;
setProgress(0);
setIsPlaying(true);
}
};
const skipToEnd = () => {
if (audioRef?.current) {
const { duration } = audioRef.current;
audioRef.current.currentTime = duration;
setProgress(duration);
setIsPlaying(false);
}
};
const startTimer = () => {
// Clear any timers already running
clearInterval(intervalRef.current);
intervalRef.current = setInterval(() => {
if (audioRef.current.ended) {
setIsPlaying(false);
} else {
setProgress(audioRef.current.currentTime);
}
}, [1000]);
};
const onSeekEnd = () => {
if (!isPlaying) {
setIsPlaying(true);
}
startTimer();
};
const rewindTrack = () => {
let newPosition = audioRef.current.currentTime - 15;
if (newPosition < 0) {
newPosition = 0;
}
audioRef.current.currentTime = newPosition;
setProgress(newPosition);
if (!isPlaying) {
setIsPlaying(true);
}
};
const { duration } = audioRef.current;
const forwardTrack = () => {
let newPosition = audioRef.current.currentTime + 30;
if (newPosition > duration) {
newPosition = duration;
}
audioRef.current.currentTime = newPosition;
setProgress(newPosition);
};
const increasePlayBackRate = (multiplier) => {
audioRef.current.playbackRate = multiplier;
};
const adjustVolume = (volume) => {
if (audioRef?.current) {
audioRef.current.volume = volume;
}
};
React.useEffect(() => {
if (audioRef?.current) {
audioRef.current.pause();
audioRef.current = new Audio(track);
setProgress(audioRef.current.currentTime);
if (isReady.current) {
setIsPlaying(true);
audioRef.current.play();
startTimer();
} else {
isReady.current = true;
}
}
}, [track]);
const playSomething = (type) => {
if (tracks[type] === track && !isPlaying) {
setIsPlaying(true);
audioRef.current.play();
} else {
setTrack(tracks[type]);
}
};
//cleanup
React.useEffect(() => {
startTimer();
return () => {
audioRef.current.pause();
clearInterval(intervalRef.current);
};
}, []);
return (
<>
<Controls
togglePlaying={togglePlaying}
startOver={startOver}
skipToEnd={skipToEnd}
rewindTrack={rewindTrack}
forwardTrack={forwardTrack}
increasePlayBackRate={increasePlayBackRate}
adjustVolume={adjustVolume}
playSomething={playSomething}
/>
<input
type="range"
value={progress}
step="1"
min="0"
max={duration ? duration : `${duration}`}
className="progress"
onChange={(e) => onSeek(e.target.value)}
onMouseUp={onSeekEnd}
onKeyUp={onSeekEnd}
/>
<div>
{isPlaying ? "playing" : "paused"} at {progress} seconds on{" "}
{audioRef?.current?.volume} volume
<br />
playback speed : {audioRef?.current?.playbackRate}
</div>
</>
);
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment