问题
With browser Web API, I'd like to set MediaDevices.getUserMedia
constraints attributes, suitable to record audio speech (voice messages), e.g. setting these parameters:
- mono
- 16bit
- 16KHz
Here my code:
const mediaStreamConstraints = {
audio: {
channelCount: 1,
sampleRate: 16000,
sampleSize: 16,
volume: 1
},
video: false
}
navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
.catch( err => serverlog(`ERROR mediaDevices.getUserMedia: ${err}`) )
.then( stream => {
// audio recorded as Blob
// and the binary data are sent via socketio to a nodejs server
// that store blob as a file (e.g. audio/inp/audiofile.webm)
} )
The recorded clip is grabbed and stored (using MediaRecorder
API), eventually sent to a nodejs server where the blob is saved as a file and processed (the application is a voicebot).
Something goes wrong and the WebM saved file hasn't the required parameters:
$ mediainfo audio/inp/audiofile.webm
General
Complete name : audio/inp/audiofile.webm
Format : WebM
Format version : Version 4 / Version 2
File size : 2.04 KiB
Writing application : Chrome
Writing library : Chrome
IsTruncated : Yes
Audio
ID : 1
Format : Opus
Codec ID : A_OPUS
Channel(s) : 1 channel
Channel positions : Front: C
Sampling rate : 48.0 kHz
Bit depth : 32 bits
Compression mode : Lossy
Language : English
Default : Yes
Forced : No
E.g.
Sampling rate : 48.0 kHz
Bit depth : 32 bits
But constraints would imply different values:
Sampling rate : 16 kHz
Bit depth : 16 bits
Also the blob, played with anew Audio(audioUrl(blob)).play()
, doesn't play. Weird. But all works if constraints are just:
const mediaStreamConstraints = { audio: true }
I checked the browser console and I didn't see any error of navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
API call.
BTW, I followed guidelines here:
- https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
- https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints
Note that my user agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36
(I'm using a last Brave browser version).
Seems to me that any audio constraints settings not allowed by the browser:
- brokes the audio blob,
- without raising an error exception (I catched both
navigator.mediaDevices.getUserMedia()
andnew MediaRecorder(...)
. Isn't this last at least a bug?
My question is:
There is any way to have sampling rate/bit depth as requested?
Or the audio format is "hardcoded"/decided by browser implementation?
BTW, The reason of audio parameters formats is because I want to minimize audio blob size to minimize bandwidth in websocket communications between the browser client and the server, optimizing audio blob exchanges for speech (voice messages)
回答1:
Try setting your audio constraints on the audio media track within your stream before you instantiate MediaRecorder.
Something like this, not debugged:
const constraints = {
audio: {
channelCount: 1,
sampleRate: 16000,
sampleSize: 16,
volume: 1
},
navigator.mediaDevices.getUserMedia({audio:true})
.catch( err => serverlog(`ERROR mediaDevices.getUserMedia: ${err}`) )
.then( stream => {
const audioTracks = stream.getAudioTracks()
if (audioTracks.length !== 1) throw new Error ('too many tracks???')
const audioTrack = audioTracks[0]
audioTrack.applyConstraints (constraints)
.then (()=> {
const mediaRecorder = new MediaRecorder(stream)
/* etc etc etc */
} )
.catch(console.error) /* you might get constraint failure here. */
} )
All that being said, the Opus audio codec does a good job compressing voice to a reasonable size. Just because it sez 48kHz x 32bits doesn't mean it uses that much bandwidth; the audio signal is compressed.
And, try it on the most recent releases of Google Chrome and/or Firefox. This media stuff is in active development.
来源:https://stackoverflow.com/questions/62392352/mediadevices-getusermedia-how-can-i-set-audio-constraints-sampling-rate-bit-d