【问题标题】:Capturing audio data (using javascript) and uploading on a server as MP3捕获音频数据(使用 javascript)并作为 MP3 上传到服务器
【发布时间】:2019-02-08 04:41:18
【问题描述】:

根据互联网上的一些资源,我正在尝试构建一个简单的网页,在那里我可以录制一些东西(我的声音),然后从录音中制作一个 mp3 文件,最后将该文件上传到服务器。

此时我可以录制也可以播放,但我还没有到上传,好像我什至无法在本地制作mp3文件。 谁能告诉我我做错了什么,或者顺序不对?

以下是我目前拥有的所有代码。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<div>
    <h2>Audio record and playback</h2>
    <p>
        <button id=startRecord><h3>Start</h3></button>
        <button id=stopRecord disabled><h3>Stop</h3></button>
        <audio id="player" controls></audio>
        <a id=audioDownload></a>
    </p>
</div>

<script>
  var player = document.getElementById('player');

  var handleSuccess = function(stream) {
    rec = new MediaRecorder(stream);

    rec.ondataavailable = e => {
        audioChunks.push(e.data);
        if (rec.state == "inactive") {
            let blob = new Blob(audioChunks,{type:'audio/x-mpeg-3'});
            player.src = URL.createObjectURL(blob);
            player.controls=true;
            player.autoplay=true;
            // audioDownload.href = player.src;
            // audioDownload.download = 'sound.data';
            // audioDownload.innerHTML = 'Download';
            mp3Build();
        }
    }

    player.src = stream;
  };

  navigator.mediaDevices.getUserMedia({audio:true/*, video: false */})
      .then(handleSuccess);

startRecord.onclick = e => {
  startRecord.disabled = true;
  stopRecord.disabled=false;
  audioChunks = [];
  rec.start();
}

stopRecord.onclick = e => {
  startRecord.disabled = false;
  stopRecord.disabled=true;
  rec.stop();
}


var ffmpeg = require('ffmpeg');

function mp3Build() {
try {
    var process = new ffmpeg('sound.data');
    process.then(function (audio) {
        // Callback mode.
        audio.fnExtractSoundToMP3('sound.mp3', function (error, file) {
            if (!error) {
                console.log('Audio file: ' + file);
        audioDownload.href = player.src;
        audioDownload.download = 'sound.mp3';
        audioDownload.innerHTML = 'Download';
      } else {
        console.log('Error-fnExtractSoundToMP3: ' + error);
      }
        });
    }, function (err) {
        console.log('Error: ' + err);
    });
} catch (e) {
    console.log(e.code);
    console.log(e.msg);
}
}

</script>

</body>
</html>

当我尝试使用 Web 控制台中的调试器进行调查并查看发生了什么时;上线:

var process = new ffmpeg('sound.data');

我收到这条消息:

Paused on exception
TypeError ffmpeg is not a contructor.

然后就行了:

var ffmpeg = require('ffmpeg');

我收到这条消息:

Paused on exception
ReferenceError require is not defined.

另外,当我看 ffmpeg 这个表达式时,我可以看到:

ffmpeg: undefined

经过进一步调查,并使用 browserify,我使用以下代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<div>
    <h2>Audio record and playback</h2>
    <p>
        <button id=startRecord><h3>Start</h3></button>
        <button id=stopRecord disabled><h3>Stop</h3></button>
        <audio id="player" controls></audio>
        <a id=audioDownload></a>
    </p>
</div>

<script src="bundle.js"></script>
<script>
  var player = document.getElementById('player');

  var handleSuccess = function(stream) {
    rec = new MediaRecorder(stream);

    rec.ondataavailable = e => {
        if (rec.state == "inactive") {
            let blob = new Blob(audioChunks,{type:'audio/x-mpeg-3'});
            //player.src = URL.createObjectURL(blob);
            //player.srcObject = URL.createObjectURL(blob);
            //player.srcObject = blob;
            player.srcObject = stream;
            player.controls=true;
            player.autoplay=true;
            // audioDownload.href = player.src;
            // audioDownload.download = 'sound.data';
            // audioDownload.innerHTML = 'Download';
            mp3Build();
        }
    }

    //player.src = stream;
    player.srcObject = stream;
  };

  navigator.mediaDevices.getUserMedia({audio:true/*, video: false */})
      .then(handleSuccess);

startRecord.onclick = e => {
  startRecord.disabled = true;
  stopRecord.disabled=false;
  audioChunks = [];
  rec.start();
}

stopRecord.onclick = e => {
  startRecord.disabled = false;
  stopRecord.disabled=true;
  rec.stop();
}


var ffmpeg = require('ffmpeg');

function mp3Build() {
try {
    var process = new ffmpeg('sound.data');
    process.then(function (audio) {
        // Callback mode.
        audio.fnExtractSoundToMP3('sound.mp3', function (error, file) {
            if (!error) {
                console.log('Audio file: ' + file);
        //audioDownload.href = player.src;
        audioDownload.href = player.srcObject;
        audioDownload.download = 'sound.mp3';
        audioDownload.innerHTML = 'Download';
      } else {
        console.log('Error-fnExtractSoundToMP3: ' + error);
      }
        });
    }, function (err) {
        console.log('Error: ' + err);
    });
} catch (e) {
    console.log(e.code);
    console.log(e.msg);
}
}

</script>

</body>
</html>

解决了以下问题:

the expression ffmpeg being: undefined

但是播放不再起作用。我可能对 player.srcObject 做的不对,也许还有其他一些事情。

当我使用这条线时:

player.srcObject = URL.createObjectURL(blob);

我收到这条消息:

Paused on exception
TypeError: Value being assigned to HTMLMediaElement.srcObject is not an object.

当我使用这条线时:

player.srcObject = blob;

我收到这条消息:

Paused on exception
TypeError: Value being assigned to HTMLMediaElement.srcObject does not implement interface MediaStream.

最后,如果我使用这个:

player.srcObject = stream;

我没有收到任何错误消息,但录音仍然无法正常工作。

【问题讨论】:

  • 检查控制台是否有“Uncaught ReferenceError: require is not defined”然后看看这里“github.com/substack/node-browserify”对于新Blob中的类型最好使用浏览器检查支持的类型这个“developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/…”也不需要 if (window.URL) { player.src = window.URL.createObjectURL(stream); } 其他 { player.src = 流; /* 你应该做 player.srcObject = stream; */ }
  • 您提到的第一个链接似乎不起作用,第二个链接只工作了一半。此外,我已尝试利用从您的评论中获得的信息,并编辑了我的帖子,并在最后添加了更多信息。但我觉得在一切正常之前我还有一些工作要做。
  • 我真的不明白发生了什么这是第一个链接github.com/browserify/browserify 这是第二个developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/…
  • 谢谢!链接现在可以使用了。
  • 为什么一定要MP3?如果您允许 Opus,您将获得更好的音频质量和浏览器支持。

标签: javascript audio ffmpeg html5-audio web-mediarecorder


【解决方案1】:

require 在浏览器中不起作用。

你应该使用“browserify”这是它的github页面https://github.com/browserify/browserify

最好(如果没有必要)在新 Blob 中使用浏览器 MediaRecorder 支持的音频类型检查此链接https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/isTypeSupported%22

最后,你的代码中不需要player.src = stream;(我说的是第二个)加上它会给你一个错误检查这个https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/srcObject#Basic_example

这是一个小编辑

    var handleSuccess = function(stream) {
    rec = new MediaRecorder(stream);

    rec.ondataavailable = e => {
        if (rec.state == "inactive") {
            let blob = new Blob(audioChunks,{type:'audio/x-mpeg-3'});
            player.src = URL.createObjectURL(blob);
            player.controls=true;
            player.autoplay=true;
            audioDownload.href = player.src;
            audioDownload.download = 'sound.data';
            audioDownload.innerHTML = 'Download';
            mp3Build();
        }
    }

    //No need to put anything here
  };

【讨论】:

  • 请注意,isTypeSupported 对于确定使用 MediaRecorder 实际记录的格式完全没有用处。事实上,即使您使用isTypeSupported 并使用其中一种类型初始化 MediaRecorder,也不能保证您实际从中得到什么。另见:stackoverflow.com/q/38337626/362536
  • @evgeni fotia 感谢您的启发。多亏了您的提示,我想我现在已经解决了“要求”问题。但是播放不再起作用;换句话说,我不能再录下我的声音了。我已经更新了帖子(在末尾添加)以反映当前情况。
  • 这可能不是正确的做法,但如果我不使用 player.srcObject 而不是使用 player.src,就像我之前所做的那样,我可以让播放功能再次工作。
  • 对不起,我不是这个意思。我稍微编辑了我的答案
  • 好的,谢谢;我明白。我现在的问题是我的 mp3Build() 似乎没有做任何好事。我想用录制的声音制作一个(mp3)文件,以便对其进行处理;但这还行不通。
猜你喜欢
  • 1970-01-01
  • 2018-10-28
  • 2021-07-12
  • 1970-01-01
  • 2015-11-25
  • 2014-02-04
  • 2011-06-04
  • 1970-01-01
  • 2014-02-11
相关资源
最近更新 更多