
如何快速實現REST API集成以優化業務流程
const audioContext = new AudioContext();
// 獲取設備麥克風流
stream = await navigator.mediaDevices
.getUserMedia({ audio: true})
.catch(function (error) {
console.log(error);
});
// 創建來自麥克風的流的聲音源
const sourceNode = audioContext.createMediaStreamSource(stream);
// 將聲音連接的揚聲器
sourceNode.connect(audioContext.destination);
就可以對著麥克風說話聽到自己的聲音了。對上述來源數據流的處理被設計成一個個的節點(Node),具有模塊化路由的特點,需要添加什么樣的效果添加什么樣的node,例如一個最常見的操作是通過把輸入的采樣數據放大來達到擴音器的作用(GainNode
),示例代碼:
// 創建音頻上下文
const audioContext = new AudioContext();
// 創建一個增益Node
const gainNode = audioCtx.createGain();
// 獲取設備麥克風流
stream = await navigator.mediaDevices
.getUserMedia({ audio: true})
.catch(function (error) {
console.log(error);
});
// 創建來自麥克風的流的聲音源
const sourceNode = audioContext.createMediaStreamSource(stream);
// 將聲音經過gainNode處理
sourceNode.connect(gainNode);
// 將聲音連接的揚聲器
gainNode.connect(audioContext.destination);
// 設置聲音增益,放大聲音
gainNode.gain.value = 2.0;
以上只是連接了聲音放大的node,如果想要增加其它效果,可以繼續往上添加node連接connect,例如濾波器(BiquadFilterNode
)、立體聲控制(StereoPannerNode
)、對信號進行扭曲(WaveShaperNode
)等等。這種模塊化設計提供了靈活的創建動態效果和復合音頻的方法,是不是有種變魔法的感覺,哪里修改點哪里(添加Node)非常方便。例如,以下展示了一個利用?AudioContext
?創建四項濾波器節點(Biquad filter node
)的例子:
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// 創建多個不同作用功能的node節點
var analyser = audioCtx.createAnalyser();
var distortion = audioCtx.createWaveShaper();
var gainNode = audioCtx.createGain();
var biquadFilter = audioCtx.createBiquadFilter();
var convolver = audioCtx.createConvolver();
// 將所有節點連接在一起
source = audioCtx.createMediaStreamSource(stream);
source.connect(analyser);
analyser.connect(distortion);
distortion.connect(biquadFilter);
biquadFilter.connect(convolver);
convolver.connect(gainNode);
gainNode.connect(audioCtx.destination);
// 控制雙二階濾波器
biquadFilter.type = "lowshelf";
biquadFilter.frequency.value = 1000;
biquadFilter.gain.value = 25;
可以看到為聲音流添加處理效果就像穿項鏈一樣,一個接一個,最后得到最終效果,實現效果可以參考官方樣例voice-change-o-matic。一個簡單而典型的 web audio 流程如下:
首先回顧一下聲音的基礎知識,聲音是由物體振動產生的機械波,常接觸到的有以下三個特性:
這里說的變聲效果是改變聲音的音調,變聲效果根據不同的場景可以分為變速不變調、變調不變速以及變調又變速 3 種。變速是指把一個語音在時域上拉長或縮短,而聲音的采樣率、基頻以及共振峰都沒有發生變化。變調是指把語音的基因頻率降低或升高,共振峰做出相應的改變,采樣頻率不變。各種方案應用場景如下:
前兩種實現都要求對聲音知識領域有更深的了解,聲音時域、頻域,信號的傅里葉變換變化都要去重新去復習一下,學習成本比較高,這里使用第3種方式,比較好接入。要改變聲音的播放速率,Web Audio API中提供了AudioBufferSourceNode
有playbackRate
屬性,可以設置音頻的播放速率,使用音頻上下文AudioContext.createBufferSource
獲得實例,示例代碼如下:
const play = ()=> {
const audioSrc = ref("src/assets/sample_orig.mp3")
const url = audioSrc.value
const request = new XMLHttpRequest()
request.open('GET', url, true)
request.responseType = 'arraybuffer'
request.onload = function() {
const audioData = request.response
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
audioCtx.decodeAudioData(audioData, (audioBuffer) => {
let source = audioCtx.createBufferSource();
source.buffer = audioBuffer;
// 改變聲音播放速率,2倍播放
source.playbackRate.value = 2;
source.connect(audioCtx.destination);
source.start(0);
});
}
request.send()
}
可以調整source.playbackRate.value
的值來改變音調,大于1提高音調,小于1降低音調。
雖然實現了變聲效果,但是這種方式只適合播放音頻文件,或者能獲取到完整音頻流的情況,對于獲取麥克風這種持續輸入的聲音流并不適用,類似的還有SoundTouchJS,它是某大佬實現的SoundTouch
的JS版本,使用也是要獲取完整音頻的數據流,作者也做了相應的解釋,參考鏈接
如何處理麥克風獲取的實時音頻流呢,這里可以借助Web Audio API中的ScriptProcessorNode
,它允許使用 JavaScript 生成、處理、分析音頻。處理流程圖如下:
利用它將實時音頻流數據處理一下,得到慢放或加速的聲音流數據。示例代碼如下:
const audioprocess = async () => {
const audioContext = new AudioContext();
// 采集麥克風輸入聲音流
let stream = await navigator.mediaDevices
.getUserMedia({ audio: true})
.catch(function (error) {
console.log(error);
});
const sourceNode = audioContext.createMediaStreamSource(stream);
const processor = audioContext.createScriptProcessor(4096, 1, 1);
processor.onaudioprocess = async event => {
// 處理回調中拿到輸入聲音數據
const inputBuffer = event.inputBuffer;
// 創建新的輸出源
const outputSource = audioContext.createMediaStreamDestination();
const audioBuffer = audioContext.createBufferSource();
audioBuffer.buffer = inputBuffer;
// 設置聲音加粗,慢放0.7倍
audioBuffer.playbackRate.value = 0.7
audioBuffer.connect(outputSource);
audioBuffer.start();
// 返回新的 MediaStream
const newStream = outputSource.stream;
const node = audioContext.createMediaStreamSource(newStream)
// 連接到揚聲器播放
node.connect(audioContext.destination)
};
// 添加處理節點
sourceNode.connect(processor);
processor.connect(audioContext.destination)
}
另外,還有一個利用Google開源jungle實現的改變音調的庫,并且還有各種混響效果,音頻可視化等炫酷功能,也是使用的Web Audio API實現,github鏈接地址放在這里了,有興趣也可以體驗下,畫面長這樣
以上就是對Web Audio API的簡單介紹和使用的分析,以及采用Web Audio API實現聲音簡單變聲效果的幾種實現,大家有哪些更好的實現方案歡迎評論區一起交流!
https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API
https://github.com/cwilso/Audio-Input-Effects
https://mdn.github.io/voice-change-o-matic/
https://github.com/cutterbl/SoundTouchJS
https://cloud.tencent.com/developer/news/818606
https://zhuanlan.zhihu.com/p/110278983
https://www.nxrte.com/jishu/3146.html
文章轉自微信公眾號@奇舞精選