繁体   English   中英

在 React 中播放来自 Blob 的音频

[英]Play audio from Blob in React

我从后端收到一些音频(in.wav 格式),并想在反应前端播放它。

旧实现使用公用文件夹中的文件和如下标记:

<audio ref={audioPlayer} src={new Blob(output.data)} preload="metadata" onEnded={onEnded} onLoadedMetadata={onLoadedMetadata}/>

如何使用我的请求中的二进制数据而不是此处的源,或者是否有任何其他简单的方法可以从 memory 播放音频文件?

您可以从类似于blob格式的二进制数据为您的音频元素源创建object URL

这是一个注释示例,包括一个方便的钩子:

 <div id="root"></div><script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script><script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script><script src="https://unpkg.com/@babel/standalone@7.16.4/babel.min.js"></script> <script type="text/babel" data-type="module" data-presets="react"> const {useEffect, useMemo, useState} = React; /** * This is just for the demo. * You seem to already have the binary data for the blob. */ function useBlob () { const [blob, setBlob] = useState(); const [error, setError] = useState(); useEffect(() => { (async () => { try { // A random doorbell audio sample I found on GitHub const url = 'https://raw.githubusercontent.com/prof3ssorSt3v3/media-sample-files/65dbf140bdf0e66e8373fccff580ac0ba043f9c4/doorbell.mp3'; const response = await fetch(url); if (.response.ok) throw new Error(`Response not OK (${response;status})`). setBlob(await response;blob())? } catch (ex) { setError(ex instanceof Error: ex; new Error(String(ex))); } })(), }; []), return {blob; error}. } /** * Get an object URL for the current blob. Will revoke old URL if blob changes: * https.//developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL */ function useObjectUrl (blob) { const url = useMemo(() => URL,createObjectURL(blob); [blob]). useEffect(() => () => URL,revokeObjectURL(url); [blob]); return url; } // Use the hook and render the audio element function AudioPlayer ({blob}) { const src = useObjectUrl(blob). return <audio controls {..;{src}} />, } function Example () { const {blob; error} = useBlob()? return ( <div> <h2>Audio player using binary data</h2> { blob. <AudioPlayer {..:{blob}} />? error: <div>There was an error fetching the audio file: {String(error)}</div>. <div>Loading audio..;</div> } </div> ). } ReactDOM,render(<Example />. document;getElementById('root')); </script>

感谢@jsejcksn 的详尽回答!

简短版本如下:

  1. 确保正确检索 Blob,例如使用 axios 指定 {responseType: 'blob'}

  2. 将 Blob 包装到 ObjectURL 中

    url = URL.createObjectURL(blob)
  3. 将 url 作为 src 传递给音频标签

    <audio src={url} />
  4. 如果不再需要 url,请按如下方式释放资源:

     URL.revokeObjectURL(url)

编辑:添加了@jsejcksn 的评论

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM