前提
Web Audio APIを用いて、録音した音声の周波数を取得したい。
WebAudioAPIを用いて、録音した周波数を取得するシステムを作っています。
実現したいこと
ここに実現したいことを箇条書きで書いてください。
- 録音機能を実装する
- 録音した音声を解析して、周波数を取得する。
発生している問題・エラーメッセージ
録音しているにも関わらず、onAudioProcessが起動せず、音声を解析することができません。
起動していないだけで、エラーメッセージ は発生していません。
該当のソースコード
html
1<button id="startRecording">解析開始</button> 2 3<button id="endRecording">解析終了</button> 4<canvas id="canvas" width="500" height="500"></canvas>
javascript
1document.addEventListener('DOMContentLoaded', function() { 2// クロスブラウザ定義 3navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; 4 5// 変数定義 6var localMediaStream = null; 7var localScriptProcessor = null; 8var bufferSize = 1024; 9var audioData = []; // 録音データ 10var recordingFlg = false; 11const audioContext = new AudioContext(); 12 13// キャンバス 14var canvas = document.getElementById('canvas'); 15var canvasContext = canvas.getContext("2d"); 16 17// 音声解析 18var audioAnalyser = null; 19 20 21// 録音バッファ作成(録音中自動で繰り返し呼び出される) 22var onAudioProcess = function(e) { 23 console.log("OK2"); 24 if (!recordingFlg) return; 25 26 // 音声のバッファを作成 27 var input = e.inputBuffer.getChannelData(0); 28 var bufferData = new Float32Array(bufferSize); 29 for (var i = 0; i < bufferSize; i++) { 30 bufferData[i] = input[i]; 31 } 32 audioData.push(bufferData); 33 // 波形を解析 34 analyseVoice(); 35}; 36 37// 解析用処理 38var analyseVoice = function() { 39 var fsDivN = audioContext.sampleRate / audioAnalyser.fftSize; 40 var spectrums = new Uint8Array(audioAnalyser.frequencyBinCount); 41 audioAnalyser.getByteFrequencyData(spectrums); 42 canvasContext.clearRect(0, 0, canvas.width, canvas.height); 43 var bufLen = analyser.frequencyBinCount; 44 var data = new Uint8Array(bufLen); 45 console.log(data); 46 canvasContext.beginPath(); 47 48 for (var i = 0, len = spectrums.length; i < len; i++) { 49 //canvasにおさまるように線を描画 50 var x = (i / len) * canvas.width; 51 var y = (1 - (spectrums[i] / 255)) * canvas.height; 52 if (i === 0) { 53 canvasContext.moveTo(x, y); 54 } else { 55 canvasContext.lineTo(x, y); 56 } 57 var f = Math.floor(i * fsDivN); // index -> frequency; 58 59 // 500 Hz単位にy軸の線とラベル出力 60 if ((f % 500) === 0) { 61 var text = (f < 1000) ? (f + ' Hz') : ((f / 1000) + ' kHz'); 62 // Draw grid (X) 63 canvasContext.fillRect(x, 0, 1, canvas.height); 64 // Draw text (X) 65 canvasContext.fillText(text, x, canvas.height); 66 } 67 } 68 69 canvasContext.stroke(); 70 71 // x軸の線とラベル出力 72 var textYs = ['1.00', '0.50', '0.00']; 73 for (var i = 0, len = textYs.length; i < len; i++) { 74 var text = textYs[i]; 75 var gy = (1 - parseFloat(text)) * canvas.height; 76 // Draw grid (Y) 77 canvasContext.fillRect(0, gy, canvas.width, 1); 78 // Draw text (Y) 79 canvasContext.fillText(text, 0, gy); 80 } 81} 82 83 var startButton = document.getElementById('startRecording'); 84// 解析開始 85 startButton.addEventListener("click", function(e){ 86 recordingFlg = true; 87 navigator.getUserMedia({audio: true}, function(stream){ 88 // 録音関連 89 localMediaStream = stream; 90 var scriptProcessor = audioContext.createScriptProcessor(bufferSize, 1, 1); 91 localScriptProcessor = scriptProcessor; 92 var mediastreamsource = audioContext.createMediaStreamSource(stream); 93 mediastreamsource.connect(scriptProcessor); 94 scriptProcessor.onaudioprocess = onAudioProcess; 95 scriptProcessor.connect(audioContext.destination); 96 // 音声解析関連 97 audioAnalyser = audioContext.createAnalyser(); 98 audioAnalyser.fftSize = 2048; 99 frequencyData = new Uint8Array(audioAnalyser.frequencyBinCount); 100 timeDomainData = new Uint8Array(audioAnalyser.frequencyBinCount); 101 mediastreamsource.connect(audioAnalyser); 102 console.log(recordingFlg); 103 }, 104 function(e) { 105 console.log(e); 106 }); 107 108}); 109 110var endButton = document.getElementById('endRecording'); 111 112// 解析終了 113 endButton.addEventListener("click", function(e){ 114 recordingFlg = false; 115 //audioDataをサーバに送信するなど終了処理 116}); 117 118});
試したこと
scriptProcessor.onaudioprocess = onAudioProcess;をscriptProcessor.onaudioprocess = onAudioProcess();にしたところ、以下のエラーメッセージ が発生しました。
Uncaught TypeError: Cannot read properties of undefined (reading 'inputBuffer')
最終的にはcanvasで描画するのではなく、録音した音声の周波数の最高値と最低値を取得する予定です。
参考にしたサイト
https://saitodev.co/search?q=%E5%91%A8%E6%B3%A2%E6%95%B0
こちらの
「JavaScriptのWeb Audio APIで録音してみる」
「JavaScriptのAnalyzerNodeで拾った音の周波数を可視化してみる」1~3
https://qiita.com/mhagita/items/6c7d73932d9a207eb94d
getUserMediaで音声を拾いリアルタイムで波形を出力する
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Float32Array
https://developer.mozilla.org/ja/docs/Web/API/AudioBuffer/getChannelData
補足情報(FW/ツールのバージョンなど)
回答1件
あなたの回答
tips
プレビュー