Add audio input support utilities
This commit is contained in:
85
src/audioInput.js
Normal file
85
src/audioInput.js
Normal file
@@ -0,0 +1,85 @@
|
||||
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 ''
|
||||
}
|
||||
Reference in New Issue
Block a user