使用HTML5录制用户的麦克风声音

9
我即将完成一个小项目,但是遇到了一个小问题,我自己无法解决。我最终想要做的是从用户的麦克风录制用户的声音,并在录制完成后将录音上传到我的服务器上。我正在使用此项目中的代码:https://github.com/cwilso/AudioRecorder
这个项目很好用,但是我需要添加一个默认不包含的功能。我需要能够在录音完成后将文件上传到我的服务器上。使用默认代码,文件可以被下载到我的计算机本地,但不能上传。所以我进行了一些研究,并找到了另一个类似的项目,具有上传功能。然而,我认为该项目的其余部分存在更多错误。因此,我尝试添加以下项目的“上传代码”:https://github.com/nusofthq/Recordmp3js Javascript 代码:
function uploadAudio(mp3Data){
    var reader = new FileReader();
    reader.onload = function(event){
        var fd = new FormData();
        var mp3Name = encodeURIComponent('audio_recording_' + new Date().getTime() + '.mp3');
        console.log("mp3name = " + mp3Name);
        fd.append('fname', mp3Name);
        fd.append('data', event.target.result);
        $.ajax({
            type: 'POST',
            url: 'upload.php',
            data: fd,
            processData: false,
            contentType: false
        }).done(function(data) {
            //console.log(data);
            log.innerHTML += "\n" + data;
        });
    };      
    reader.readAsDataURL(mp3Data);
}

PHP 代码:

<?php
if(!is_dir("recordings")){
    $res = mkdir("recordings",0777); 
}

// pull the raw binary data from the POST array
$data = substr($_POST['data'], strpos($_POST['data'], ",") + 1);
$filename = urldecode($_POST['fname']);

// write the data out to the file
$fp = fopen('recordings/'.$filename, 'wb');
fwrite($fp, $decodedData);
fclose($fp);
?>

我尝试将这段代码与https://github.com/cwilso/AudioRecorder项目结合使用,但没有成功。请问我需要在JavaScript代码中做哪些更改,以及在哪里添加它?非常感谢任何帮助!

PS:我知道这只适用于Chrome、Firefox和Opera。

2个回答

10
我最近使用类似的资源实现了你正在尝试实现的任务。由于你没有说明需要将音频上传为mp3格式,因此我将向你展示如何使用Recorderjs上传wav文件,使用的源代码在这里:https://github.com/cwilso/AudioRecorder 需要注意的是,Recorderjs会将未压缩的wav文件存储在名为“blob”的变量中。这发生在recorder js的101行,更具体地说在以下函数中:
worker.onmessage = function(e){
  var blob = e.data;
  currCallback(blob);
}

问题在于blob是在该函数中进行本地声明的。我们需要再次使用它,因此为了这个例子,请让我们使其易于访问并将其全局化。因此,在recorder.js之外声明一个变量blob,如下所示:
var blob = null;

然后在recorderjs中修改上述函数,将数据存储在全局声明的“blob”变量中,函数应如下所示:

worker.onmessage = function(e){
  blob = e.data;
  currCallback(blob);
}

现在我们可以使用“blob”。现在在任何地方声明以下函数,
function uploadAudio(){
        var fd = new FormData();
        var wavName = encodeURIComponent('audio_recording_' + new Date().getTime() + '.wav');
        console.log("wavName = " + wavName);
        fd.append('fname', wavName);
        fd.append('data', blob);
        $.ajax({
            type: 'POST',
            url: 'upload.php',
            data: fd,
            processData: false,
            contentType: false
        }).done(function(data) {
            //console.log(data);
            log.innerHTML += "\n" + data;
        });
}

你的服务器端代码应该使用以下内容:

<?php
if(!is_dir("recordings")){
    $res = mkdir("recordings",0777); 
}
move_uploaded_file($_FILES["file"]["tmp_name"],
  $res . $_FILES["file"]["fname"]);
?>

注意:$_FILES ["file"] ["tmp_name"] 就是它听起来的样子,即文件的临时位置。这由ajax调用和表单数据为您完成。
祝你好运,如果遇到问题,请告诉我。

1
据我所见,AudioRecorder以Blob的形式导出。Blob是您可以轻松通过XMLHttpRequest上传的内容(而XMLHttpRequest上传可以通过Google轻松找到)。简而言之,您不需要FileReader(甚至可以跳过FormData,因为您只上传单个Blob)。
请记住,人们倾向于不回答没有OP先前分析的问题; 在这种情况下,您应该至少解释a)您必须上传什么类型的数据,以及b)您现有实现中的确切问题。在这里,您实际上要求人们交叉使用两个库(我们大多数人都从未使用过其中任何一个,更不用说两个了)。事实上,我可能对Blobs错了,但您比我更了解它,只是未能通知。 (不要误会,我希望我是正确的,您很快就会使您的代码正常工作。)

谢谢您的回答和建议。那么我真正需要知道的是,在AudioRecorder项目中,我应该在哪个文件中添加XMLHttpRequest以上传blob? - three3
我的猜测是根本没有文件(Blob不是文件)。由于我从未使用过AudioRecorder,所以我只能告诉你我在源代码中看到了exportWAV方法(似乎正在导出Blob),但在相信我的话之前,你应该自己尝试一下。如果确实可以,那么这个Blob正是你想要传递到XHR上传的内容。 - K Lee
你提到的 exportWAV 方法,在几个 AudioRecorder 文件中都有提到。当你谈到 exportWAV 方法时,你指的是哪个文件?一旦我知道了这个,我就会尝试使用 XMLHttpRequest。再次感谢! - three3
你应该明白我并不知道地球上所有的API,对吧?你所问的已经不仅仅是关于JavaScript了,而是关于你正在使用的特定库。我假设你已经知道如何从AudioRecorder中导出,否则你怎么能确定你的原始代码一开始就无法工作呢? - K Lee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接