React Web Audio API - 播放、暂停和导出加载的音频文件
React Web Audio API - Play, pause and export loaded audio file
我的目的是使用 WEB 音频上传和收听音频文件 API。我在选择音频文件时能够听到它,但在暂停和播放之后遇到问题。我还需要将文件导出为 WAV 格式。我创建了一个简单的例子,任何帮助将不胜感激
加载音频并从文件输入播放
const onFileChange = (e) => {
let file = e.target.files[0];
console.log(file);
setFile(file);
let fileReader = new FileReader();
fileReader.onload = function (ev) {
audioContext.decodeAudioData(ev.target.result).then(function (buffer) {
playSound(buffer);
});
};
fileReader.readAsArrayBuffer(file);
};
使用缓冲源播放声音
const playSound = (buffer, time) => {
source = audioContext.createBufferSource();
source.buffer = buffer;
source.connect(audioContext.destination);
source.start(time);
setIsPlaying(true);
};
我在暂停和播放时遇到问题:
const onPlayPause = (e) => {
console.log("audioState", audioContext.state);
console.log("duration", audioContext.currentTime);
if (!isPlaying) {
//source.start();
setIsPlaying(true);
} else if (audioContext.state === "running") {
setPlayDuration(audioContext.currentTime);
audioContext.suspend();
setIsPlaying(false);
} else if (audioContext.state === "suspended") {
audioContext.resume();
}
};
导出音频:
const exportAudioFile = () => {
offlineContext.render().then((buffer) => {
setRenderState('encoding');
const handleMessage = ({ data }) => {
var blob = new window.Blob([new DataView(data)], {
type: 'audio/wav',
});
//blob = new Blob([buffer], { type: "audio/wav" });
const url = window.URL.createObjectURL(blob);
}
window.URL.revokeObjectURL(url);
})};
代码和框链接:
https://codesandbox.io/s/react-audiocontext-pause-play-fw20u?file=/src/App.js
我对 React 功能组件中的持久化问题感到相当头疼。幸运的是,useRef 是一个很棒的工具:
https://reactjs.org/docs/hooks-reference.html#useref
正如文档所说,它本质上是 returns 一个容器,.current
属性 持续存在 跨重新渲染 。
我将你的代码分叉到 useRef 中:
https://codesandbox.io/s/react-audiocontext-pause-play-forked-si59u?file=/src/App.js:120-159
基本上,当您加载文件时,将闪亮的新 AudioContext
存储在 ref 的 .current
字段中,并在整个组件的其余部分引用它。您可以稍微清理一下,IE 将 .current
存储在一个常量范围内,以供您在其中使用它的函数使用。
两个关键点:
export default function App() {
const audioCtxContainer = useRef(null);
...
和
audioCtxContainer.current = new AudioContext();
audioCtxContainer.current
.decodeAudioData(ev.target.result)
.then(function (buffer) {
playSound(buffer);
});
useRef 对于您希望在组件的生命周期内保留的任何可变对象都很有用。
如果有帮助请告诉我!
我的目的是使用 WEB 音频上传和收听音频文件 API。我在选择音频文件时能够听到它,但在暂停和播放之后遇到问题。我还需要将文件导出为 WAV 格式。我创建了一个简单的例子,任何帮助将不胜感激
加载音频并从文件输入播放
const onFileChange = (e) => {
let file = e.target.files[0];
console.log(file);
setFile(file);
let fileReader = new FileReader();
fileReader.onload = function (ev) {
audioContext.decodeAudioData(ev.target.result).then(function (buffer) {
playSound(buffer);
});
};
fileReader.readAsArrayBuffer(file);
};
使用缓冲源播放声音
const playSound = (buffer, time) => {
source = audioContext.createBufferSource();
source.buffer = buffer;
source.connect(audioContext.destination);
source.start(time);
setIsPlaying(true);
};
我在暂停和播放时遇到问题:
const onPlayPause = (e) => {
console.log("audioState", audioContext.state);
console.log("duration", audioContext.currentTime);
if (!isPlaying) {
//source.start();
setIsPlaying(true);
} else if (audioContext.state === "running") {
setPlayDuration(audioContext.currentTime);
audioContext.suspend();
setIsPlaying(false);
} else if (audioContext.state === "suspended") {
audioContext.resume();
}
};
导出音频:
const exportAudioFile = () => {
offlineContext.render().then((buffer) => {
setRenderState('encoding');
const handleMessage = ({ data }) => {
var blob = new window.Blob([new DataView(data)], {
type: 'audio/wav',
});
//blob = new Blob([buffer], { type: "audio/wav" });
const url = window.URL.createObjectURL(blob);
}
window.URL.revokeObjectURL(url);
})};
代码和框链接: https://codesandbox.io/s/react-audiocontext-pause-play-fw20u?file=/src/App.js
我对 React 功能组件中的持久化问题感到相当头疼。幸运的是,useRef 是一个很棒的工具:
https://reactjs.org/docs/hooks-reference.html#useref
正如文档所说,它本质上是 returns 一个容器,.current
属性 持续存在 跨重新渲染 。
我将你的代码分叉到 useRef 中:
https://codesandbox.io/s/react-audiocontext-pause-play-forked-si59u?file=/src/App.js:120-159
基本上,当您加载文件时,将闪亮的新 AudioContext
存储在 ref 的 .current
字段中,并在整个组件的其余部分引用它。您可以稍微清理一下,IE 将 .current
存储在一个常量范围内,以供您在其中使用它的函数使用。
两个关键点:
export default function App() {
const audioCtxContainer = useRef(null);
...
和
audioCtxContainer.current = new AudioContext();
audioCtxContainer.current
.decodeAudioData(ev.target.result)
.then(function (buffer) {
playSound(buffer);
});
useRef 对于您希望在组件的生命周期内保留的任何可变对象都很有用。
如果有帮助请告诉我!