在此之前,只有 <video>
和 <audio>
可透過 HTMLMediaElement.setSinkId()
設定音訊輸出裝置。在 Web Audio 中,AudioContext 會使用預設裝置,讓使用者手動變更系統音訊輸出裝置。
自 Chrome 110 起,您可以使用 AudioContext.setSinkId()
透過程式設計將 Web Audio 中的音訊輸出導向至任何允許的裝置。
這在各種即時通訊情境中特別實用。舉例來說,網頁應用程式可以使用這項功能,透過程式設計將輸出內容直接傳送至特定音訊輸出裝置,例如藍牙耳機或擴音器。
將音訊輸出路由至特定裝置
首先,您需要要用來做為目的地的音訊輸出裝置 ID。使用 navigator.mediaDevices.enumerateDevices()
取得可用媒體裝置的清單,只篩選音訊輸出裝置,並取得所選音訊輸出裝置的 deviceId
屬性。空字串 ""
值也可以做為 deviceId
的預設裝置。
取得音訊輸出裝置的 ID 後,請建立 AudioContext
並呼叫 audioContext.setSinkId(deviceId)
。成功時,系統會將音訊路由至所選的已連結輸出裝置,並解析傳回的承諾。如果 AudioContext 已關閉,這項作業可能會失敗。
以下範例說明如何視需要要求麥克風存取權,並將 Web Audio 中的音訊輸出內容導向第一個可用的輸出裝置。
const permission = await navigator.permissions.query({ name: "microphone" });
if (permission.state == "prompt") {
// More audio outputs are available when user grants access to the mic.
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
stream.getTracks().forEach((track) => track.stop());
}
// Request a list of media devices and filter audio output devices.
const devices = await navigator.mediaDevices.enumerateDevices();
const audioOutputs = devices.filter(device => device.kind == "audiooutput");
const audioContext = new AudioContext();
// Pick the first available audio output.
const deviceId = audioOutputs[0].deviceId;
await audioContext.setSinkId(deviceId);
請注意,您也可以在建立 AudioContext
時,將 deviceId
做為 sinkId
參數傳遞。
const audioContext = new AudioContext({ sinkId: deviceId });
使用靜音 AudioContext 算繪音訊
您現在可以在 Web Audio 中指定「無聲輸出裝置」,以盡量降低耗電量。這次請將 { type: "none" }
傳遞至 AudioContext.setSinkId()
,而非字串值。
請注意,透過 audioContext.currentTime
存取的音訊時鐘仍會繼續推進,以算繪音訊圖表。這個靜音 AudioContext 的主要目標,是在不產生可聽音訊的情況下算繪音訊圖表。主要用途是分析麥克風輸入內容,而不會發出聲響。
// Silent Web Audio output.
await audioContext.setSinkId({ type: "none" });
特徵偵測
如要檢查是否支援 AudioContext.setSinkId()
,請使用:
if ("setSinkId" in AudioContext.prototype) {
// AudioContext.setSinkId() is supported.
}
範例
您可以在 https://sinkid.glitch.me/ 試用 AudioContext.setSinkId()
的示範版本。
瀏覽器支援
AudioContext.setSinkId()
適用於 Chrome 110 以上版本。
意見回饋
Chrome 團隊和網路標準社群希望瞭解您使用 AudioContext.setSinkId()
的體驗。如要提供意見回饋,請在現有 GitHub 問題中發表評論,或提交新的 GitHub 問題。
實用連結
特別銘謝
感謝 Hongchan Choi 和 Michael Wilson 審查本文。
日曆圖片由 Steve Harvey 提供,並發布於 Unsplash。