AudioWorkletの使い方 [Web Audio API]
AudioWorkletとAudioWorkletProcessorの使い方です。
AudioWorkletProcessorでは波形の生データをリアルタイムで編集可能です。Web Workerのようになっていますのでメインスレッドとは別のスレッドで実行されます。メッセージ(変数)の受け渡しも可能です。
デモ
リアルタイムに波形データを編集して音量を変更します。
再生ボタンを押した後に次を操作してださい。
5
ソースコード
ローカル環境でこのコードを実行するとエラーになります。ソースコードはサーバにアップロードして下さい。また、コードを変更した場合は「Ctrl+F5」で完全にキャッシュを削除してからテストしてください。
[demo.html]
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<audio id="myAudio" src="voice.mp3"></audio>
<button onclick="play();">再 生</button> <button onclick="stop();">停 止</button><br>
<br>再生ボタンを押した後に次を操作してださい。<br>
<input type="range" id="range_myParam" min="1" max="10" value="5" onchange="onChange();"> <span id="msg_myParam">5</span><br>
<br>
<button onclick="add();">AudioWorkletProcessorで3 +5をしてみる</button>
<script>
var audioCtx;
var audioSourceNode;
var workletNode;
var tracks;
var audioEle;
var wm = new WeakMap();
var firstFlag = true;
window.onload = function(){
audioEle = document.getElementById('myAudio');
}
function play(){
if(firstFlag){
// AudioContextの生成
audioCtx = new AudioContext();
firstFlag = false;
if ('audioWorklet' in audioCtx){
}else{
alert('お使いのブラウザはAudioWorkletに対応していません。');
}
}
modann();
}
function stop(){
audioEle.pause();
if(workletNode){
workletNode.port.postMessage({"state":"exit"});
}
}
async function modann(stream){
// MediaElementAudioSourceNodeの生成
if(audioSourceNode){
audioSourceNode.disconnect();
}
if (wm.has(audioEle)) {
audioSourceNode = wm.get(audioEle);
} else {
console.log(1);
audioSourceNode = audioCtx.createMediaElementSource(audioEle);
wm.set(audioEle, audioSourceNode);
}
// AudioWorkletの読み込み
await audioCtx.audioWorklet.addModule("modan.js");
// AudioWorkletNodeを取得する
if(workletNode){
workletNode.disconnect();
}
workletNode = new AudioWorkletNode(audioCtx,"MyWorklet");
// メッセージの受け取り
workletNode.port.onmessage = function(e){
alert(e.data.result);
console.log(e.data);
};
workletNode.port.start();
workletNode.port.postMessage({"state":"init","sampleRate":audioCtx.sampleRate,
"myParam":document.getElementById('range_myParam').value});
audioSourceNode.connect(workletNode);
workletNode.connect(audioCtx.destination);
audioEle.play();
}
function onChange(){
document.getElementById('msg_myParam').innerHTML = document.getElementById('range_myParam').value;
if(workletNode){
workletNode.port.postMessage({"myParam":document.getElementById('range_myParam').value});
}
}
function add(){
if(workletNode){
workletNode.port.postMessage({"state":"add","a":3,"b":5});
}
}
</script>
</body>
</html>
[modan.js]
class MyWorklet extends AudioWorkletProcessor {
// コントラスタ
constructor (options) {
super(options);
this.port.onmessage = event => {
if (event.data.state){
this.state = event.data.state;
}
if (event.data.sampleRate){
this.sampleRate = event.data.sampleRate;
}
if (event.data.a){
this.a = event.data.a;
}
if (event.data.state){
this.b = event.data.b;
}
if (event.data.myParam){
this.myParam = event.data.myParam;
}
}
this.port.start();
}
// ココに波形の生データが出力される
process (inputs, outputs, parameters) {
console.log("実行中");
// 波形データの編集
let input = inputs[0];
let output = outputs[0];
for (let channel = 0; channel < output.length; ++channel) {
for (let i = 0; i < output[channel].length; ++i) {
output[channel][i] = input[channel][i] * this.myParam/10;
}
}
// メソッドのテスト
if (this.state == "add"){
this.port.postMessage({'result': this.add(this.a,this.b)});
this.state = "";
}
// 終了判定
if (this.state == "exit"){
console.log("終了");
// 終了
return false;
}else{
// 次の生データを受け取る
return true;
}
}
// オリジナルのメソッド
add(a,b) {
return a + b;
}
}
// プロセッサーの登録
registerProcessor("MyWorklet", MyWorklet);
注意事項
AudioWorkletは2019年2月現在ではChromeのみ対応しています。
パソコン内の音声を録音する音声録音くんを製作中にAudioWorklet/AudioWorkletProcessorをテストしていたのですが、稀にわかずかな音が途切れるバグがあるようです。現状ではcreateScriptProcessor(scriptProcessorNode)の方が安定しています。
プログラム上ではcreateScriptProcessor()を優先して、廃止された場合は自動的にAudioWorklet/AudioWorkletProcessorを使用するようにした方が良いです。
参考サイト
スポンサーリンク
関連記事
| 前の記事: | Failed to execute 'createMediaElementSource' on 'AudioContext': HTMLMediaElement already connected previously to a different MediaElementSourceNode |
| 次の記事: | Waveファイルのボリューム(音量)を変更する [WAVE.js] |
公開日:2019年02月15日
記事NO:02730
プチモンテ ※この記事を書いた人
![]() | |
![]() | 💻 ITスキル・経験 サーバー構築からWebアプリケーション開発。IoTをはじめとする電子工作、ロボット、人工知能やスマホ/OSアプリまで分野問わず経験。 画像処理/音声処理/アニメーション、3Dゲーム、会計ソフト、PDF作成/編集、逆アセンブラ、EXE/DLLファイルの書き換えなどのアプリを公開。詳しくは自己紹介へ |
| 🎵 音楽制作 BGMは楽器(音源)さえあれば、何でも制作可能。歌モノは主にロック、バラード、ポップスを制作。歌詞は抒情詩、抒情的な楽曲が多い。楽曲制作は🔰2023年12月中旬 ~ | |









