Drag/Click on Audio Seekbar always pointed back to start of the audio element (React Js)

Tags: ,



I am new to React and currently developing the music player using React Js. The idea is to change the seek-bar as the song plays and the user can change the track position using seek-bar(like any other media players). I have the JSX audio tag to play the song and input tag as a seek-bar. Please refer to the below code segments.

        {/* audio tag */}
        <audio ref={songRef} type="audio/mpeg" preload="true"
         onTimeUpdate={ e => setCurrentTime(e.target.value) }
         onCanPlay={ e => setDuration(e.target.duration) }
         onEnded={ e => next_song(e, allSong.indexOf(currentSong) + 1, state) }
         src={ currentSong && `${dev_url}${currentSong.id}` }
        />
            
        {/* audio seek-bar */}
        { (currentSong || pSong) && 
         <input type="range" style={styles.progress}
          value={duration ? (currentTime * 100)/duration : 0} 
          onChange={onChangeProgress}/>}

Everything works well except the onChange event on seek-bar. Every time I triggered the onChange function (i.e; when I’m trying to change the track position using seek-bar), the song goes back to the start (00:00), instead of the desired position. Below is my onChangeHandler which is used to update seek-bar and track position.

function onChangeProgress(event) {
       let time = (event.target.value * duration) / 100;
       setCurrentTime(time);
       songRef.current.currentTime = time;
    }

I have been stuck here for few days already. Please help me?

Answer

The problem is that when the client seeks to new playback position, it sends the bytes range requests to the server, and the server must be able to respond to those requests.

The ideal solution is to configure the web server to accept bytes range requests and responds persistant connection.

You can take the status code of request header as a reference to check whether the server is responding persistant connection or not. If the server response is persistant connection, the status code will be *206 Partial Content.

The alternate solution will be getting the audio/song file as a blob type and convert them to ObjectUrl.

const response = await axios.get(url, {
            responseType: 'arraybuffer',
            headers: {
                'Content-Type': 'audio/mp3'
            }
        });
        
        const blob = new Blob([response.data], {
            type: 'audio/mpeg'
        });
        const bloburl = URL.createObjectURL(blob);

Then we can use it as src for audio and play around.

Please check the below stackoverflow answers for more info.



Source: stackoverflow