86 lines
2.1 KiB
JavaScript
86 lines
2.1 KiB
JavaScript
export const AUDIO_INPUT_ENABLED_KEY = 'audioInputEnabled'
|
|
export const AUDIO_INPUT_DEVICE_ID_KEY = 'audioInputDeviceId'
|
|
|
|
const AUDIO_RECORDER_MIME_CANDIDATES = [
|
|
'audio/webm;codecs=opus',
|
|
'audio/webm',
|
|
'audio/mp4',
|
|
'audio/ogg;codecs=opus',
|
|
'',
|
|
]
|
|
|
|
export function supportsAudioInputCapture() {
|
|
return (
|
|
typeof navigator !== 'undefined' &&
|
|
typeof window !== 'undefined' &&
|
|
typeof window.MediaRecorder !== 'undefined' &&
|
|
Boolean(navigator.mediaDevices?.getUserMedia) &&
|
|
Boolean(navigator.mediaDevices?.enumerateDevices)
|
|
)
|
|
}
|
|
|
|
export function getAudioInputConstraints(deviceId = '') {
|
|
const audio = {
|
|
echoCancellation: true,
|
|
noiseSuppression: true,
|
|
autoGainControl: true,
|
|
}
|
|
|
|
if (deviceId) {
|
|
audio.deviceId = { exact: deviceId }
|
|
}
|
|
|
|
return { audio }
|
|
}
|
|
|
|
export function stopMediaStream(stream) {
|
|
stream?.getTracks?.().forEach(track => track.stop())
|
|
}
|
|
|
|
export async function ensureAudioInputPermission() {
|
|
if (!supportsAudioInputCapture()) {
|
|
throw new Error('Microphone capture is not available in this environment.')
|
|
}
|
|
|
|
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
|
|
stopMediaStream(stream)
|
|
}
|
|
|
|
export async function listAudioInputDevices() {
|
|
if (!supportsAudioInputCapture()) {
|
|
return []
|
|
}
|
|
|
|
const devices = await navigator.mediaDevices.enumerateDevices()
|
|
return devices
|
|
.filter(device => device.kind === 'audioinput')
|
|
.map((device, index) => {
|
|
const label = String(device.label || '').trim()
|
|
return {
|
|
deviceId: device.deviceId || `audio-input-${index + 1}`,
|
|
label: label || `Microphone ${index + 1}`,
|
|
hasLabel: Boolean(label),
|
|
}
|
|
})
|
|
}
|
|
|
|
export function getPreferredAudioRecorderMimeType() {
|
|
if (typeof window === 'undefined' || typeof window.MediaRecorder === 'undefined') {
|
|
return ''
|
|
}
|
|
|
|
for (const mimeType of AUDIO_RECORDER_MIME_CANDIDATES) {
|
|
if (!mimeType) {
|
|
return ''
|
|
}
|
|
if (
|
|
typeof window.MediaRecorder.isTypeSupported !== 'function' ||
|
|
window.MediaRecorder.isTypeSupported(mimeType)
|
|
) {
|
|
return mimeType
|
|
}
|
|
}
|
|
|
|
return ''
|
|
}
|