現在、多くのブラウザでは、 できます。ただし、ブラウザによっては、完全な動的かつインラインの ユーザーのデバイス上の別のアプリに委任することもできます。
最初はシンプルに、段階的に進めていく
最も簡単な方法は、事前に録音したファイルをユーザーに依頼することです。これを行うには、Terraform で
ファイル入力要素を追加し、音声ファイルのみを受け入れることができることを示す accept
フィルタを追加します。
capture
属性。マイクから直接取得します。
<input type="file" accept="audio/*" capture />
この方法はすべてのプラットフォームで機能します。パソコンでは、
ファイル システムからファイルをアップロードします(capture
属性は無視します)。Safari の場合
マイクアプリが開いて、音声を録音したり、
ウェブページに送り返します場合、ユーザーは
ウェブに送り返す前に音声を録音するアプリを選択する
できます。
ユーザーが録音を終了してウェブサイトに戻ったら、
なんらかの方法でファイルデータを取得する必要があります。次の方法ですばやくアクセスできます。
onchange
イベントを入力要素にアタッチして読み取り
イベント オブジェクトの files
プロパティ。
<input type="file" accept="audio/*" capture id="recorder" />
<audio id="player" controls></audio>
<script>
const recorder = document.getElementById('recorder');
const player = document.getElementById('player');
recorder.addEventListener('change', function (e) {
const file = e.target.files[0];
const url = URL.createObjectURL(file);
// Do something with the audio file.
player.src = url;
});
</script>
</audio>
ファイルにアクセスできれば、どのような操作でも行えます。たとえば、下記の設定が可能です。
<audio>
要素に直接アタッチして再生できるようにする- ユーザーのデバイスにダウンロードする
XMLHttpRequest
に接続して、サーバーにアップロードします。- データを Web Audio API で渡し、フィルタを適用します
入力要素を使用して音声データにアクセスする場合、 最も魅力的な選択肢ではありません。本当に必要なのは ページ上でマイクを直接操作できます。
マイクにインタラクティブにアクセスする
最新のブラウザではマイクに直接接続できるため、 ウェブページに完全に統合され、ユーザーが 閉じることもできます。
マイクへのアクセス権を取得する
WebRTC の API を使用してマイクに直接アクセスできます
getUserMedia()
という仕様です。getUserMedia()
はユーザーに次のプロンプトを表示します。
接続したマイクやカメラへのアクセス権を持ちます。
成功すると、API はカメラまたはStream
次に、それを <audio>
要素にアタッチするか、WebRTC にアタッチするか、
ウェブ オーディオ AudioContext
に添付したり、MediaRecorder
API を使用して保存したりできます。
マイクからデータを取得するには、制約に audio: true
を設定します。
getUserMedia()
API に渡されるオブジェクト。
<audio id="player" controls></audio>
<script>
const player = document.getElementById('player');
const handleSuccess = function (stream) {
if (window.URL) {
player.srcObject = stream;
} else {
player.src = stream;
}
};
navigator.mediaDevices
.getUserMedia({audio: true, video: false})
.then(handleSuccess);
</script>
特定のマイクを選択する場合は、まず使用可能なマイクを列挙できます。
navigator.mediaDevices.enumerateDevices().then((devices) => {
devices = devices.filter((d) => d.kind === 'audioinput');
});
次に、getUserMedia
を呼び出すときに使用する deviceId
を渡すことができます。
navigator.mediaDevices.getUserMedia({
audio: {
deviceId: devices[0].deviceId,
},
});
それだけでは、あまり役に立ちません。私たちができることは、音声データを取得して再生することだけです。
マイクから元データにアクセスする
マイクから元データにアクセスするには、
getUserMedia()
し、Web Audio API を使用してデータを処理します。「
ウェブ オーディオ API は、入力ソースを取得してそれらを接続するシンプルな API です。
音声データを処理できるノードにソースを割り当て(ゲインなどを調整)、
最終的にはスピーカーに接続し
ユーザーに聞くことができます
接続可能なノードの 1 つに AudioWorkletNode
があります。このノードは、
低レベルのカスタム音声処理機能が
用意されています実際の音声
処理は AudioWorkletProcessor
の process()
コールバック メソッドで行われます。
この関数を呼び出して、入力とパラメータをフィードし、出力を取得します。
音声ワークレットを入力をご覧ください。 をご覧ください。
<script>
const handleSuccess = async function(stream) {
const context = new AudioContext();
const source = context.createMediaStreamSource(stream);
await context.audioWorklet.addModule("processor.js");
const worklet = new AudioWorkletNode(context, "worklet-processor");
source.connect(worklet);
worklet.connect(context.destination);
};
navigator.mediaDevices.getUserMedia({ audio: true, video: false })
.then(handleSuccess);
</script>
// processor.js
class WorkletProcessor extends AudioWorkletProcessor {
process(inputs, outputs, parameters) {
// Do something with the data, e.g. convert it to WAV
console.log(inputs);
return true;
}
}
registerProcessor("worklet-processor", WorkletProcessor);
バッファに保持されるデータは、マイクからの元データであり、 そのデータに対していくつかのオプションがあります。
- サーバーに直接アップロードする
- ローカルに保存する
- WAV などの専用ファイル形式に変換し、 ローカルにホストするか、
マイクのデータを保存する
マイクのデータを保存するための最も簡単な方法は、
MediaRecorder
API。
MediaRecorder
API は、getUserMedia
によって作成されたストリームを取得し、
ストリーム上のデータを任意のディレクトリに
あります。
<a id="download">Download</a>
<button id="stop">Stop</button>
<script>
const downloadLink = document.getElementById('download');
const stopButton = document.getElementById('stop');
const handleSuccess = function(stream) {
const options = {mimeType: 'audio/webm'};
const recordedChunks = [];
const mediaRecorder = new MediaRecorder(stream, options);
mediaRecorder.addEventListener('dataavailable', function(e) {
if (e.data.size > 0) recordedChunks.push(e.data);
});
mediaRecorder.addEventListener('stop', function() {
downloadLink.href = URL.createObjectURL(new Blob(recordedChunks));
downloadLink.download = 'acetest.wav';
});
stopButton.addEventListener('click', function() {
mediaRecorder.stop();
});
mediaRecorder.start();
};
navigator.mediaDevices.getUserMedia({ audio: true, video: false })
.then(handleSuccess);
</script>
今回の例では、後で変換できる配列にデータを直接保存しています。
Blob
に格納して、ウェブサーバーにデータを保存するか、
ユーザーのデバイスのストレージに保存されます
責任を持ってマイクを使用する許可を求める
ユーザーがサイトにマイクへのアクセスを許可していない場合は、
getUserMedia
を呼び出すと、ブラウザはユーザーに
サイトにマイクへのアクセスを許可します。
ユーザーは、マシン上の高性能デバイスへのアクセスを要求されることを好みません。 リクエストを頻繁にブロックするか、拒否しない場合は無視します。 プロンプトが作成されたコンテキストを理解できます。ベスト プラクティスは、 必要になったときにのみマイクへのアクセスを要求できます。ユーザーが アクセスが拒否されると再度要求されることはありませんが アクセスを拒否した場合は ユーザーに権限を再度要求することはできません。
Permissions API を使用して、すでにアクセス権があるかどうかを確認する
getUserMedia
API では、ユーザーがすでにリソースを所有しているかどうかは
マイクへのアクセス権が必要です。この場合、適切な UI を提供するための問題が発生します。
ユーザーにマイクへのアクセス権を付与してもらうには、
マイクへのアクセス権が必要です。
この問題は、一部のブラウザでは Permission API を使用することで解決できます。「
navigator.permission
API を使用すると、次の機能の状態をクエリできます。
特定の API へのアクセスを制御できます。
ユーザーのマイクにアクセスできるかどうかを照会するには、
{name: 'microphone'}
をクエリメソッドに追加すると、次のいずれかが返されます。
granted
- ユーザーが以前にマイクへのアクセス権を付与しています。prompt
- ユーザーからアクセス権が与えられておらず、次の場合に確認メッセージが表示されます。getUserMedia
を呼び出します。denied
- システムまたはユーザーが アクセスできなくなります。
ユーザーに変更を加える必要があるかどうかをすばやく確認できます。 ユーザーが必要な操作を行えるようにしました。
navigator.permissions.query({name: 'microphone'}).then(function (result) {
if (result.state == 'granted') {
} else if (result.state == 'prompt') {
} else if (result.state == 'denied') {
}
result.onchange = function () {};
});