最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

I developed the recording using the JavaScript web audio API, but the sound quality is poor - Stack Overflow

programmeradmin6浏览0评论

I have created an application that sings along in the app with the web audio API of JavaScript. This worked perfectly on iOS safari and Chrome, but the sound quality was poor on Android Chrome. To solve this, I tried changing the audio deviceId, but it still didn't work. Does someone have information that might help?

Doubt: After recording, I pass the file to the server and play it on another page. I am wondering if this is causing the problem.

This is my code

function captureUserMedia(mediaConstraints) {
    navigator.mediaDevices.getUserMedia(mediaConstraints).then(onMediaSuccess)["catch"]();
}

function record() {
    if (getParameterByName("startSec").length !== 0) {
        masterSound.currentTime = getParameterByName("startSec");
    }
    masterSound.play();
    if (document.querySelectorAll(".record")[0].getAttribute("status") == "off") {
        document.querySelectorAll(".record")[0].setAttribute("status", "on");
        document.querySelectorAll(".record")[0].classList.add("stoped");
        var mediaConstraints;
        const devices = navigator.mediaDevices.enumerateDevices()
        devices.then((value) => {
            // mediaConstraints = {
            //     audio: {
            //         deviceId: {
            //             exact: value[0].deviceId
            //         }
            //     },
            //     video: false
            // };
            mediaConstraints = {
                audio: true,
                video: false,
            };
            captureUserMedia(mediaConstraints, onMediaSuccess);
        });

    } else {
        document.querySelectorAll(".record")[0].setAttribute("status", "off");
        document.querySelectorAll(".record")[0].classList.remove("stoped");
        mediaRecorder.stream.stop();
        masterSound.pause();
    }
}

function onMediaSuccess(stream) {
    var audio = document.createElement('audio');
    audio.controls = true;
    audio.files = true;
    audio.muted = true;
    audio.srcObject = stream;
    audio.play();
    var audiosContainer = document.querySelectorAll(".audio_wrapper")[0];
    audiosContainer.appendChild(audio);
    audiosContainer.appendChild(document.createElement('hr'));
    mediaRecorder = new MediaStreamRecorder(stream);
    mediaRecorder.mimeType = 'audio/wav';
    mediaRecorder.stream = stream;
    mediaRecorder.recorderType = MediaRecorderWrapper;
    mediaRecorder.audioChannels = 1;
    mediaRecorder.start();
    mediaRecorder.ondataavailable = function (blob) {
        audioFile = blob;
        var blobURL = URL.createObjectURL(blob);
        document.querySelectorAll(".append_audio")[0].setAttribute("src", blobURL);

        function blobToFile(theBlob, fileName) {
            theBlob.lastModifiedDate = new Date();
            theBlob.name = fileName;
            return theBlob;
        }

        submit();

        function submit() {
            var audioTest = new Audio(URL.createObjectURL(blob));
            audioTest.play();
        }
    };
} 

I have created an application that sings along in the app with the web audio API of JavaScript. This worked perfectly on iOS safari and Chrome, but the sound quality was poor on Android Chrome. To solve this, I tried changing the audio deviceId, but it still didn't work. Does someone have information that might help?

Doubt: After recording, I pass the file to the server and play it on another page. I am wondering if this is causing the problem.

This is my code

function captureUserMedia(mediaConstraints) {
    navigator.mediaDevices.getUserMedia(mediaConstraints).then(onMediaSuccess)["catch"]();
}

function record() {
    if (getParameterByName("startSec").length !== 0) {
        masterSound.currentTime = getParameterByName("startSec");
    }
    masterSound.play();
    if (document.querySelectorAll(".record")[0].getAttribute("status") == "off") {
        document.querySelectorAll(".record")[0].setAttribute("status", "on");
        document.querySelectorAll(".record")[0].classList.add("stoped");
        var mediaConstraints;
        const devices = navigator.mediaDevices.enumerateDevices()
        devices.then((value) => {
            // mediaConstraints = {
            //     audio: {
            //         deviceId: {
            //             exact: value[0].deviceId
            //         }
            //     },
            //     video: false
            // };
            mediaConstraints = {
                audio: true,
                video: false,
            };
            captureUserMedia(mediaConstraints, onMediaSuccess);
        });

    } else {
        document.querySelectorAll(".record")[0].setAttribute("status", "off");
        document.querySelectorAll(".record")[0].classList.remove("stoped");
        mediaRecorder.stream.stop();
        masterSound.pause();
    }
}

function onMediaSuccess(stream) {
    var audio = document.createElement('audio');
    audio.controls = true;
    audio.files = true;
    audio.muted = true;
    audio.srcObject = stream;
    audio.play();
    var audiosContainer = document.querySelectorAll(".audio_wrapper")[0];
    audiosContainer.appendChild(audio);
    audiosContainer.appendChild(document.createElement('hr'));
    mediaRecorder = new MediaStreamRecorder(stream);
    mediaRecorder.mimeType = 'audio/wav';
    mediaRecorder.stream = stream;
    mediaRecorder.recorderType = MediaRecorderWrapper;
    mediaRecorder.audioChannels = 1;
    mediaRecorder.start();
    mediaRecorder.ondataavailable = function (blob) {
        audioFile = blob;
        var blobURL = URL.createObjectURL(blob);
        document.querySelectorAll(".append_audio")[0].setAttribute("src", blobURL);

        function blobToFile(theBlob, fileName) {
            theBlob.lastModifiedDate = new Date();
            theBlob.name = fileName;
            return theBlob;
        }

        submit();

        function submit() {
            var audioTest = new Audio(URL.createObjectURL(blob));
            audioTest.play();
        }
    };
} 
Share Improve this question edited May 25, 2021 at 5:52 김두호 asked May 25, 2021 at 5:37 김두호김두호 661 silver badge7 bronze badges 7
  • 1 please post your code? specifically around getUserMedia – Sumit Wadhwa Commented May 25, 2021 at 5:43
  • I just added it. thank you before. – 김두호 Commented May 25, 2021 at 5:54
  • 1 Maybe you are recording from the phone call mic and not the video mic? – CherryDT Commented May 25, 2021 at 5:55
  • @CherryDT Yes it is correct! Is there any way to solve this? – 김두호 Commented May 25, 2021 at 5:58
  • Check the available devices returned by enumerateDevices – CherryDT Commented May 25, 2021 at 6:30
 |  Show 2 more ments

2 Answers 2

Reset to default 7

When trying to build high-quality audio with getDisplayMedia, in the past I've passed in MediaStreamConstraints that remove some of the default processing on the input track:

stream = await navigator.mediaDevices.getDisplayMedia(
            { 
                video: true, 
                audio: 
                    { 
                        channels: 2, 
                        autoGainControl: false, 
                        echoCancellation: false, 
                        noiseSuppression: false 
                    }
                }
            );

I'm still learning WebRTC myself, so I'm not sure if these same properties can be passed when using getUserMedia and MediaConstraints, but I thought I'd share in case helpful. It sounds like this might also be about available devices. Good luck!

Had a similar issue where we were getting plaints about very low sound/gain - barely hearable - with our HTML/JS recording client when running on Chrome on some Android devices.

Ended up buying an older Samsung phone (Galaxy A8) to easily replicate the issue.

The culprit was echoCancellation being set to false. With it disabled, we had a very low volume on the recorded audio. The solution was to set echoCancellation as true.

We ended up removing the constraint altogether and relied on each browser's defaults (echoCancellation is enabled by default on Chrome, Safari, Firefox).

Worth mentioning that autoGainControl and noiseSuppression inherit the value of echoCancellation, more exactly, if you only set audio: {echoCancellation: true} the other 2 constraints will also be set as true.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论