【问题标题】:Play mp3 file after uploading it with html5 drag and drop upload使用html5拖放上传上传后播放mp3文件
【发布时间】:2011-10-08 22:50:55
【问题描述】:

是否可以先用html5拖放上传系统上传一个mp3文件,然后用webkit的音频API播放(http://chromium.googlecode.com/svn/trunk/samples/audio/index.html) html)而不提交表单(在谷歌浏览器中)?是否可以在 FF 中使用 Mozilla 的音频 API?如果是这样,怎么做?另外,有没有关于 webkit 的 API 的教程?我没找到。

【问题讨论】:

    标签: javascript api audio google-chrome mozilla


    【解决方案1】:

    你需要遵循的基本流程是

    1. 使用Drag and Drop Files捕获文件
    2. 将文件发布到Form Data Object
    3. 回复您要播放的音频项目的 URL
    4. 使用音频 API 播放音频

    jsFiddle 允许您将音频文件拖到某个区域,然后它将播放该文件。

    您应该可以使用JavaScriptAudioNode 的 onaudioprocess 事件来获取当前幅度。

    编辑:

    根据JaapH 所说的,我再次对此进行了调查。处理器用于获取适当的事件来渲染画布。所以它并不是真正需要的。这个jsFiddle 和下面的一样。但是,它使用requestAnimationFrame 而不是处理器。

    这是旧代码,使用请求动画帧的版本请参见上面的小提琴:

    var context = new (window.AudioContext || window.webkitAudioContext)();
    var source;
    var processor;
    var analyser;
    var xhr;
    
    function initAudio(data) {
        source = context.createBufferSource();
    
        if(context.decodeAudioData) {
            context.decodeAudioData(data, function(buffer) {
                source.buffer = buffer;
                createAudio();
            }, function(e) {
                console.log(e);
            });
        } else {
            source.buffer = context.createBuffer(data, false /*mixToMono*/);
            createAudio();
        }
    }
    
    function createAudio() {
        processor = context.createJavaScriptNode(2048 /*bufferSize*/, 1 /*num inputs*/, 1 /*numoutputs*/);
        processor.onaudioprocess = processAudio;
        analyser = context.createAnalyser();
    
        source.connect(context.destination);
        source.connect(analyser);
    
        analyser.connect(processor);
        processor.connect(context.destination);
    
        source.noteOn(0);
        setTimeout(disconnect, source.buffer.duration * 1000);
    }
    
    function disconnect() {
        source.noteOff(0);
        source.disconnect(0);
        processor.disconnect(0);
        analyser.disconnect(0);
    }
    
    function processAudio(e) {
        var freqByteData = new Uint8Array(analyser.frequencyBinCount);
        analyser.getByteFrequencyData(freqByteData);
        console.log(freqByteData);
    }
    
    function handleResult() {
        if (xhr.readyState == 4 /* complete */) {
            switch(xhr.status) {
                case 200: /* Success */
                    initAudio(request.response);
                    break;
                default:
                    break;
            }
            xhr = null;
        }      
    }
    
    function dropEvent(evt) {
        evt.stopPropagation();
        evt.preventDefault();
    
        var droppedFiles = evt.dataTransfer.files;
    
        //Ajax the file to the server and respond with the data
    
        var formData = new FormData();
        for(var i = 0; i < droppedFiles.length; ++i) {
                var file = droppedFiles[i];
    
                files.append(file.name, file);
        }
    
        xhr = new XMLHttpRequest();
        xhr.open("POST", 'URL');  
        xhr.onreadystatechange = handleResult;
        xhr.send(formData);
    }
    
    function dragOver(evt) {
        evt.stopPropagation();
        evt.preventDefault();
        return false;
    }
    
    var dropArea = document.getElementById('dropArea');
    dropArea.addEventListener('drop', dropEvent, false);
    dropArea.addEventListener('dragover', dragOver, false);
    

    希望对你有帮助

    【讨论】:

    • 这可以正常工作,但我需要使用 webkit 的音频 API 和/或 Mozilla 的来播放它。或者,如果有一种方法可以获取音频标签中播放内容的当前幅度,那也可以。另外,不要假设人们正在使用 jquery。
    • 好的。我已经取出 jquery 代码并更新了使用音频 API 的答案。这个jsFiddle 包含所有音频 API 代码,但它使用文件阅读器而不是 AJAX。现在代码中有更多内容。如果我需要更好地解释,请告诉我。
    • 当我运行 jsfiddle 示例时,声音失真,这是因为处理器和源都连接到 context.destination。
    • 我无法重现声音失真的任何问题。但是,如果您只想为频率数据设置动画,我添加了一个编辑,显示使用 requestAnimationFrame 而不是处理器。
    • 我已经更新了小提琴,由于音频 api 更新,它似乎无法正常工作。这应该使它起作用:jsfiddle.net/gaJyT/182
    【解决方案2】:

    当我运行 jsfiddle 示例时,声音失真,这是因为处理器和源都连接到 context.destination。为了让它工作,我删除了source.connect(context.destination); 行,并在processAudio 函数中添加了将输入样本复制到输出的代码

    var inL = e.inputBuffer.getChannelData(0);
    var inR = e.inputBuffer.getChannelData(1);
    var outL= e.outputBuffer.getChannelData(0);
    var outR =e.outputBuffer.getChannelData(1);
    
    var n = inL.length;
    for (var i = 0; i < n; i++) {
        outL[i] = inL[i];
        outR[i] = inR[i];
    }
    

    【讨论】:

      猜你喜欢
      • 2011-09-24
      • 2011-12-23
      • 2011-05-14
      • 2011-09-08
      • 2011-10-30
      • 1970-01-01
      • 1970-01-01
      • 2013-08-24
      相关资源
      最近更新 更多