I have this implementation where the backend strams audio files. And I want an approach that enables fast loading and playing of the audio file : Everything works as intended but there seem to be erratic behaviour where it takes very long time to load on my web page:
I am new to React Js .
import React, { useState,useEffect, useRef } from 'react';
import { Icon } from '@iconify/react';
import { podcastIcons } from '@/db/data';
import axios from 'axios';
import WaveSurfer from 'wavesurfer.js';
const PlayFile: React.FC = () => {
const [linkName, setLinkName] = useState<string>(''); // State for link name
const [audioURL, setAudioURL] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(false);
const waveformRef = useRef<HTMLDivElement | null>(null); // Reference to the waveform container
const waveSurfer = useRef<WaveSurfer | null>(null); // Reference to the WaveSurfer instance
const handleSubmit = async (event: React.FormEvent) => {
event.preventDefault();
const formData = new FormData();
formData.append('link_name', linkName);
try {
const response = await axios.post('http://localhost:8000/submitform/', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
const audioBlob = new Blob([response.data], { type: 'audio/mpeg' });
const audioUrl = URL.createObjectURL(audioBlob);
setAudioURL(audioUrl); // Set audio UR
// Initialize Wavesurfer after the audio is set
console.log('checking waveform');
if (waveformRef.current && waveSurfer.current === null) {
waveSurfer.current = WaveSurfer.create({
container: waveformRef.current,
waveColor: '#ddd',
progressColor: '#333',
cursorColor: '#333',
height: 64,
barWidth: 1,
responsive: true,
// backend: 'MediaElement'
});
}
// Load the audio file into Wavesurfer
console.log('after checking ...');
if (waveSurfer.current && audioUrl) {
console.log('Waveform loaded with audio URL:', audioUrl);
waveSurfer.current.load(audioUrl);
}
// } catch (error) {
// console.error('Error generating the podcast:', error);
// }
} catch (error) {
console.error('Error submitting the form', error);
}finally {
setIsLoading(false);
}
};
);
return (
<form onSubmit={handleSubmit} className=" bg-gradient-to-r from-emerald-100 to-lime-200 flex text-black flex-col lg:flex-row lg:space-x-8 p-6 font-sans py-12 px-6">
</div>
{/* Link Name Input Field */}
<div className="mb-6">
<label className="font-semibold mb-2">Document Link</label>
<input
type="Document link"
value={linkName}
onChange={(e) => setLinkName(e.target.value)}
className="border rounded w-full py-2 px-3"
placeholder="Link to Document"
/>
</div>
<button className="bg-black text-white py-3 px-8 rounded w-full">
Create podcast
</button>
{/* Show the audio player and waveform if the audio URL is available */}
{audioURL && (
<div className="mt-4">
<div className="waveform" ref={waveformRef}></div> {/* Waveform container */}
<div className="mt-2 flex gap-4">
<button onClick={() => waveSurfer.current?.playPause()} className="bg-green-500 text-white py-2 px-4 rounded">
{waveSurfer.current?.isPlaying() ? 'Pause' : 'Play'}
</button>
<button onClick={() => waveSurfer.current?.stop()} className="bg-red-500 text-white py-2 px-4 rounded">
Stop
</button>
</div>
</div>
)}
</div>
</form>
);
};
export default PlayFile;
I have tried the code above and it works sometimes and other times it does not. I am looking for wats of optimizing the code and gaining hands-on-experience in handling audio rendering on frontnd in a scalable way. Examples illustrating best practices will be well appreciated. SOlution using peaks.js, howler and other similar libraries that are optimized for performance is also welcomed.