折腾:
【已解决】web端html+js中如何调用麦克风获取用户语音输入说话
期间,通过:
【已解决】js中MediaRecorder录音支持哪些音频格式
和
【已解决】js的MediaRecorder的浏览器支持情况和相关polyfill
发现:
官网的html的MediaRecorder,只有Chrome和Firefox支持,Safari浏览器不支持。
且Chrome还不支持wav等常见格式。
现在发现:
MediaStreamRecorder不仅能解决支持多个浏览器的问题,且好像:
https://github.com/streamproc/MediaStreamRecorder#record-audiowav
还支持wav?
好像还支持:
<code> $allowed = array( 'webm', 'wav', 'mp4', 'mp3', 'ogg' ); </code>
mp3和ogg?
看到是支持:
<code>// audio: audioRecorder.mimeType = 'audio/webm'; // MediaRecorderWrapper audioRecorder.mimeType = 'audio/ogg'; // MediaRecorderWrapper audioRecorder.mimeType = 'audio/wav'; // StereoAudioRecorder audioRecorder.mimeType = 'audio/pcm'; // StereoAudioRecorder </code>
所以,此处还是去换用:MediaStreamRecorder
demo:
WebRTC Audio Recording using MediaStreamRecorder
source:
https://github.com/streamproc/MediaStreamRecorder/blob/master/demos/audio-recorder.html
通过:
<code><!-- or link specific release --> <script src="https://github.com/streamproc/MediaStreamRecorder/releases/download/1.3.4/MediaStreamRecorder.js"></script> </code>
打开:
Releases · streamproc/MediaStreamRecorder
果然找到了。最新的是:
MediaStreamRecorder v1.3.4
下载得到:
然后放到代码里,试试效果:
<code><script src="js/MediaStreamRecorder/MediaStreamRecorder.min.js"></script> </code>
<code> function downloadRecordedAudio(blobUrl, suffix){ console.log("downloadRecordedAudio: blobUrl=%s, suffix=%s", blobUrl, suffix); $("#downloadSpeakAudio").attr("href", blobUrl); var curDate = new Date(); console.log("curDate=%o", curDate); var curDatetimeStr = curDate.Format("yyyyMMdd_HHmmss"); console.log("curDatetimeStr=%o", curDatetimeStr); var recordedAudioFilename = curDatetimeStr + suffix; console.log("recordedAudioFilename=%o", recordedAudioFilename); $("#downloadSpeakAudio").attr("download", recordedAudioFilename); } function playRecordedAudio(blobUrl){ console.log("playRecordedAudio: blobUrl=%s", blobUrl); var inputAudio = document.getElementById('inputAudio'); // var inputAudio = $("#inputAudio"); console.log("inputAudio=o", inputAudio); inputAudio.src = blobUrl; console.log("inputAudio.src=%s", inputAudio.src); inputAudio.play(); } function testMediaStreamRecorder(mediaStream){ console.log("testMediaStreamRecorder: mediaStream=%o", mediaStream); var mediaStreamRecorder = new MediaStreamRecorder(mediaStream); console.log("mediaStreamRecorder=%o", mediaStreamRecorder); const AUDIO_TYPE = { webm: { mimeType: 'audio/webm', suffix: ".webm" }, wav: { mimeType: 'audio/wav', suffix: ".wav" }, pcm: { mimeType: 'audio/pcm', suffix: ".pcm" }, ogg: { mimeType: 'audio/ogg', suffix: ".ogg" } } var curAudioType = AUDIO_TYPE.webm; console.log("curAudioType=%o", curAudioType); mediaStreamRecorder.mimeType = curAudioType.mimeType; mediaStreamRecorder.ondataavailable = function (recordedBlob) { console.log("mediaStreamRecorder.ondataavailable: recordedBlob=%o", recordedBlob); const blobUrl = URL.createObjectURL(recordedBlob); console.log("blobUrl=%o", blobUrl); playRecordedAudio(blobUrl); downloadRecordedAudio(blobUrl, curAudioType.suffix); }; $( "#stopSpeak" ).on( "click", function() { console.log("#stopSpeak clicked"); mediaStreamRecorder.stop(); }); mediaStreamRecorder.start(); console.log("mediaStreamRecorder started"); } function onSuccessGetUserMedia(mediaStream) { console.log("handleSuccess: mediaStream=%o", mediaStream); testMediaStreamRecorder(mediaStream); } function testAudioInput(){ console.log("testAudioInput"); var mediaConstraints = { audio: true, video: false }; console.log("mediaConstraints=%o", mediaConstraints); navigator.mediaDevices .getUserMedia(mediaConstraints) .then(onSuccessGetUserMedia) .catch(function (error) { console.error("Try getUserMedia error: %o", error); //Chorome click not allow -> DOMException: Permission denied //Safari -> Trying to call getUserMedia from an insecure document. }); } </code>
效果是OK的,和之前一样的:
再去换成其他格式,比如wav试试
结果提示:
<code>curAudioType={mimeType: "audio/wav", suffix: ".wav"} MediaStreamRecorder.min.js:3 The AudioContext was not allowed to start. It must be resume (or created) after a user gesture on the page. https://goo.gl/7K7WLu </code>
不能录音。
看到:
<code>recorderType You can force StereoAudioRecorder or WhammyRecorder or similar recorders on Firefox or Edge; even on Chrome and Opera. All browsers will be using your specified recorder: // force WebAudio API on all browsers // it allows you record remote audio-streams in Firefox // it also works in Microsoft Edge mediaRecorder.recorderType = StereoAudioRecorder; // force webp based webm encoder on all browsers mediaRecorder.recorderType = WhammyRecorder; // force MediaRecorder API on all browsers // Chrome Canary/Dev already implemented MediaRecorder API however it is still behind a flag. // so this property allows you force MediaRecorder in Chrome. mediaRecorder.recorderType = MediaRecorderWrapper; // force GifRecorder in all browsers. Both WhammyRecorder and MediaRecorder API will be ignored. mediaRecorder.recorderType = GifRecorder; </code>
// audio:
audioRecorder.mimeType = ‘audio/webm’; // MediaRecorderWrapper
audioRecorder.mimeType = ‘audio/ogg’; // MediaRecorderWrapper
audioRecorder.mimeType = ‘audio/wav’; // StereoAudioRecorder
audioRecorder.mimeType = ‘audio/pcm’; // StereoAudioRecorder
难道要强制recorderType?
<code> mediaStreamRecorder.mimeType = curAudioType.mimeType; if (curAudioType == AUDIO_TYPE.wav) { mediaStreamRecorder.recorderType = StereoAudioRecorder; console.log("set recorderType to StereoAudioRecorder when wav"); } </code>
结果:
问题依旧。
换成pcm:
<code>var curAudioType = AUDIO_TYPE.pcm; </code>
结果同样现象,不支持。
换成ogg:
<code>var curAudioType = AUDIO_TYPE.ogg; </code>
结果:
<code>Passing following params over MediaRecorder API. {mimeType: "audio/webm"} </code>
即:
自动换成webm了。。。
想起了了,对于上面的wav提示:
<code>The AudioContext was not allowed to start. It must be resume (or created) after a user gesture on the page. https://goo.gl/7K7WLu </code>
看了不能代码主动start,要放到别的,比如按钮点击,才能触发
【未解决】MediaStreamRecorder中stop后还会执行ondataavailable
期间看到了:
MediaStreamRecorder/audio-recorder.html at master · streamproc/MediaStreamRecorder
<code>var recorderType = document.getElementById('audio-recorderType').value; if (recorderType === 'MediaRecorder API') { mediaRecorder.recorderType = MediaRecorderWrapper; } if (recorderType === 'WebAudio API (WAV)') { mediaRecorder.recorderType = StereoAudioRecorder; mediaRecorder.mimeType = 'audio/wav'; } if (recorderType === 'WebAudio API (PCM)') { mediaRecorder.recorderType = StereoAudioRecorder; mediaRecorder.mimeType = 'audio/pcm'; } // don't force any mimeType; use above "recorderType" instead. // mediaRecorder.mimeType = 'audio/webm'; // audio/ogg or audio/wav or audio/webm </code>
意思是:
我此处的,主动设置mimeType,是不好的做法,应该设置recorderType
-》内部会自动设置mimeType?
抽空去优化看看