首页 > 解决方案 > 拖动/单击 Audio Seekbar 始终指向音频元素的开始(React Js)

问题描述

我是 React 新手,目前正在使用 React Js 开发音乐播放器。这个想法是在歌曲播放时更改搜索栏,用户可以使用搜索栏更改曲目位置(就像任何其他媒体播放器一样)。我有 JSX 音频标签来播放歌曲和输入标签作为搜索栏。请参考以下代码段。


        {/* 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}/>}

除了seek-bar 上的 onChange 事件之外,一切都运行良好。每次我触发 onChange 函数时(即,当我尝试使用搜索栏更改曲目位置时),歌曲都会回到开头(00:00),而不是所需的位置。下面是我的 onChangeHandler 用于更新搜索栏和跟踪位置。

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

我已经被困在这里几天了。请帮我?

标签: javascriptreactjs

解决方案


问题是当客户端寻找新的播放位置时,它会向服务器发送字节范围请求,服务器必须能够响应这些请求。

理想的解决方案是将 Web 服务器配置为接受字节范围请求并响应持久连接。

您可以将请求头的状态码作为参考来检查服务器是否响应持久连接。如果服务器响应是持久连接,则状态码将为 * 206 Partial Content

另一种解决方案是将音频/歌曲文件作为 blob 类型并将它们转换为 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);

然后我们可以将它用作音频的 src 并播放。

请查看以下 stackoverflow 答案以获取更多信息。


推荐阅读