代码之家  ›  专栏  ›  技术社区  ›  szark

angularjs捕获音频并上载文件

  •  0
  • szark  · 技术社区  · 6 年前

    我正在开发一个网络应用程序,你可以从浏览器中录制音频,然后上传到服务器上,这样其他用户就可以收听,给你一个评价,更正——语言学习。

    我有部分代码,但我不知道如何将它们组合在一起:

    JS(录制音频的脚本-工作正常,跳过录制部分和停止按钮):

    navigator.mediaDevices.getUserMedia({audio:true})
    .then(stream => {handlerFunction(stream)})
    
    function handlerFunction(stream) {
        rec = new MediaRecorder(stream);
        rec.ondataavailable = e => {
            audioChunks.push(e.data);
            if(rec.state == "inactive") {
    
                let blob = new Blob(audioChunks, {type:'audio/mpeg-3'});
                recordedAudio.src = URL.createObjectURL(blob);
                recordedAudio.controls = true;
    
                var url = recordedAudio.src;
                var link = document.getElementById("download");
                link.href = url;
                link.download = 'audio.wav';
            }
        }
    }
    

    创建控件的HTML部分:录制、停止,然后下载录制的音频:

    <button id="record">Record</button>
    <button id="stopRecord">Stop</button>
    <p> <audio id="recordedAudio"></audio></p>
    <div id="recordings"><a id="download"> Download</a></div>
    

    上传可以很好地选择文件,但我不知道如何将这两段代码组合在一起。

    <form>
        <input type="file" file-model="uploadedFile">
        <button type="submit" ng-click="doUploadFile()">Upload</button>
    </form> 
    

    文件上载指令:

    .directive('fileModel', ['$parse', function($parse) {
        return {
            restrict: 'A',
            link: function(scope, element, attrs) {
                var model = $parse(attrs.fileModel);
                var modelSetter = model.assign;
    
                element.bind('change', function() {
                    scope.$apply(function() {
                        modelSetter(scope, element[0].files[0]);
                    });
                });
            }
        };
    }]);
    

    我想在这里实现的目标:

    1. 此链接与录制的音频文件关联

    2. 单击此按钮将调用doUploadFile()方法

    如何修改代码,把这两个部分放在一起,这样我们就可以在录制完成后直接上传?

    我还是个新手,很高兴能得到你的帮助!

    1 回复  |  直到 6 年前
        1
  •  0
  •   szark    6 年前

    编辑

    设法让它工作起来: 删除了上传文件的表单。该指令也不再需要了。我把录音和上传的代码放在一起。我在控制器内部添加了一个FormData对象并附加了blob。现在工作得很好。

    var data = new FormData();
    
    
    $scope.doUploadFile = function() {
        var url = "/uploadfile";
    
        var config = {
                transformRequest: angular.identity,
                transformResponse: angular.identity,
                headers : { 'Content-Type': undefined }
        }
    
        $http.post(url, data, config)
        .then(function(response) {
            $scope.uploadResult = response.data;
            data = new FormData();
        });
    };
    
    navigator.mediaDevices.getUserMedia({audio:true})
    .then(stream => {handlerFunction(stream)})
    
    function handlerFunction(stream) {
        rec = new MediaRecorder(stream);
        rec.ondataavailable = e => {
            audioChunks.push(e.data);
            if(rec.state == "inactive") {
    
                let blob = new Blob(audioChunks, {type:'audio/mpeg-3'});
                recordedAudio.src = URL.createObjectURL(blob);
                recordedAudio.controls = true;
                recordedAudio.autoplay = false;
    
                var url = recordedAudio.src;
    
                data.append('uploadfile', blob, "recording.wav");
            }
        }
    }