MediaDevices.getUserMedia() How can I set audio constraints (sampling rate/bit depth)?

我们两清 提交于 2020-06-28 06:01:40

问题


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() and new 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!