0

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?

  • Can you log the value of time in your `onChangeProgress` function to verify it's a valid entry? – technicallynick Sep 14 '20 at 15:46
  • @technicallynick Yes, I can log the time value and it’s valid entry. However, when I tried to log the songRef.current.currentTime at the end of onChangeProgress Function, I always get zero, regardless of time value. – Kyaw Thit Lwin Sep 14 '20 at 23:34
  • Can you post more of your code? Or even better, create a codesandbox so I can take a look? – technicallynick Sep 15 '20 at 15:20
  • @technicallynick Hi bro, I just found out the root cause. In my case, I was playing the songs, directly from Flask Web Server. The problem is that the client sends **bytes range requests** to the server while seeking to new playback position, and my web server is not configured for those requests. The ideal solution is I need to configure my server for **bytes range requests**. The alternate will be request the song files as a blob, convert into URL objects and play the songs. – Kyaw Thit Lwin Sep 16 '20 at 00:23
  • That's great! Glad you were able to pinpoint the problem! – technicallynick Sep 16 '20 at 16:22

1 Answers1

1

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.