麦克风名字为空:WebView2 加 --use-fake-ui-for-media-stream 使权限持久化以恢复设备枚举

This commit is contained in:
crosswk committed 2026-07-29 21:06:09 +08:00
1 parent f017cde9df
commit e63c04f0a4
2 files changed
+17 -12

No files matched your search

+1
View File
@@ -25,6 +25,7 @@ use std::thread;
/// with ERROR_INVALID_STATE when the option sets differ).
const WEBVIEW2_BROWSER_ARGS: &str =
"--ignore-certificate-errors --auto-accept-camera-and-microphone-capture \
--use-fake-ui-for-media-stream \
--disable-backgrounding-occluded-windows --disable-renderer-backgrounding \
--disable-background-timer-throttling";
+16 -12
View File
@@ -134,19 +134,23 @@ registerProcessor('pcm-processor', PCMProcessor);
export async function listMicrophones(): Promise<MediaDeviceInfo[]> {
const audioInputs = (list: MediaDeviceInfo[]) => list.filter((d) => d.kind === 'audioinput')
// 新版 WebView2 / Chromium 收紧了设备枚举:只有在麦克风流“活跃”时,
// enumerateDevices() 才会返回设备的真实名字(label),否则只有一个无名通用项。
// 因此这里始终先开一个临时音频流,趁流活跃时枚举,拿到完整列表后立刻关闭。
let stream: MediaStream | null = null
try {
stream = await navigator.mediaDevices.getUserMedia({ audio: true })
return audioInputs(await navigator.mediaDevices.enumerateDevices())
} catch {
// 拿不到权限或没有可用麦克风:退回普通枚举(可能只有通用项)
return audioInputs(await navigator.mediaDevices.enumerateDevices())
} finally {
if (stream) stream.getTracks().forEach((t) => t.stop())
let devices = audioInputs(await navigator.mediaDevices.enumerateDevices())
// 没有持久麦克风权限时,enumerateDevices() 只返回一个无名字的通用项。
// 此时临时打开一路音频流触发授权,趁流活跃时重新枚举,拿到真实名称。
if (devices.length <= 1 || devices.some((d) => !d.label)) {
let stream: MediaStream | null = null
try {
stream = await navigator.mediaDevices.getUserMedia({ audio: true })
devices = audioInputs(await navigator.mediaDevices.enumerateDevices())
} catch {
// 权限被拒或无可用麦克风:保留已有结果
} finally {
if (stream) stream.getTracks().forEach((t) => t.stop())
}
}
return devices
}
function createAudioContext() {