使用带有HTML5的用户麦克风录制音频

时间:2014-08-03 02:20:17

标签: javascript jquery html5 html5-audio audio-recording

我非常接近完成我的一个小项目,但是,我遇到了一个我似乎无法自己解决的轻微问题。我最终想要做的是从用户麦克风录制用户的语音,然后在完成后将录音上传到我的服务器。我正在使用此项目中的代码: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 个答案:

答案 0 :(得分:9)

我最近实施了一项类似的任务,您尝试使用类似的资源来实现。您还没有表明您需要将上传的音频作为mp3播放,因此我将向您展示如何使用recorderjs上传wav,使用此处的源代码:https://github.com/cwilso/AudioRecorder

首先要注意的是,recorderjs将未压缩的wav存储在名为blob的var中。这发生在记录器js的第101行,更具体地说是在这个函数中:

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

问题是blob是在该函数中本地声明的。我们需要再次使用它,所以为了这个例子,让它很容易实现并使其全局化。因此,在记录器js之外声明一个变量blob,如下所示:

var blob = null;

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

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

现在我们可以使用&#39; blob&#39;。现在在某处声明以下函数,

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 [&#34; file&#34;] [&#34; tmp_name&#34;]听起来像。文件的临时位置。这是通过ajax调用和表单数据完成的。

祝你好运,如果你遇到问题,请告诉我。

答案 1 :(得分:1)

据我所知,AudioRecorder导出为Blob。使用XMLHttpRequest可以轻松上传Blob(而且您可以通过Google轻松找到XMLHttpRequest上传内容)。简而言之,您不需要FileReader(甚至可能会跳过FormData,因为您只上传了一个Blob。)

请记住,人们倾向于不回答表明OP没有事先分析的问题;在这种情况下,您应该至少解释了a)您必须上传什么类型的数据,以及b)在您现有的实现中究竟什么不起作用。在这里,你有效地要求人们跨越两个图书馆(我们大多数人从未使用过任何一个图书馆,更不用说两者了)。事实是我对Blob可能是错的,但你实际上知道这比我更好而且没有告知。 (不要误解我的意思;我希望我是对的,你很快就会得到你的代码。)