2014-12-01 22 views
5

Sto provando a registrare l'audio da un utente del sito Web e salvare l'audio sul mio server. Molti dei post che ho studiato fino ad ora hanno fatto riferimento ai registratori di Matt Diamond. Ho tentato di ricreare la demo allo http://webaudiodemos.appspot.com/AudioRecorder/index.html aprendo il codice sorgente tramite il mio browser. Ho copiato l'html, "audiodisplay.js", "recorder.js" e "main.js" e li ho messi sul mio server. Ho anche aggiunto il file "recorderWorker.js" dal suo sito GitHub. Nel file recorder.js, ho cambiato var WORKER_PATH = 'js/recorderjs/recorderWorker.js' in var WORKER_PATH = 'recorderWorker.js';registra l'audio dall'utente e salva sul server

Quando eseguo la demo che ho configurato, ricevo l'avviso "ti piacerebbe condividere il tuo microfono ..." e posso avviare la registrazione premendo l'icona del microfono sul lato destro. Tuttavia, quando smetto di registrare, la forma d'onda audio non viene visualizzata qui sotto come nella demo di Matt e l'icona di salvataggio non si attiva.

Se riesco a far funzionare la demo, il problema successivo è salvare il file wav sul server anziché localmente come nella demo. Ho trovato diversi post che dicono di usare XMLHttpRequest(), tuttavia non riesco a capire come collegare questi esempi ai registratori. Saving WAV File Recorded in Chrome to ServerHTML5 & getUserMedia - Record Audio & Save to Web Server after Certain TimeRecorderJS uploading recorded blob via AJAX

risposta

4

Ho trovato una soluzione, ma accogliamo con piacere altri relativi ai registratori. Ho usato MP3RecorderJS a https://github.com/icatcher-at/MP3RecorderJS. La demo html funziona se cambi la parte superiore del codice html da src = "js/jquery.min.js" e src = "js/mp3recorder.js" ovunque si trovino nel tuo server. Per me, è src = "jquery.min.js" e src = "mp3recorder.js" Ho dovuto anche fare la stessa cosa con il file "mp3recorder.js": var RECORDER_WORKER_PATH = 'js/recorderWorker.js'; var ENCODER_WORKER_PATH = 'js/mp3Worker.js'; cambiato in var RECORDER_WORKER_PATH = 'recorderWorker.js'; var ENCODER_WORKER_PATH = 'mp3Worker.js';

Il programma è impostato per registrare sia mp3 che wav. Volevo wav, quindi ho apportato alcune modifiche al file html. Alla linea 55 si trovano:

recorderObject.exportMP3(function(base64_mp3_data) { 
     var url = 'data:audio/mp3;base64,' + base64_mp3_data; 
     var au = document.createElement('audio'); 

ho cambiato a:

recorderObject.exportWAV(function(base64_wav_data) { 
     var url = 'data:audio/wav;base64,' + base64_wav_data; 
     var au = document.createElement('audio'); 

La demo aggiunge un nuovo giocatore ogni volta che si registra. Per evitare ciò, ho cancellato (commentato) il $ recorder.append (au); parte, fatto un nuovo div per memorizzare il lettore audio, e quindi ho cancellato quel div ogni volta, prima che venga creato il lettore audio. Per caricare sul mio server, ho usato una tecnica che ho imparato dal caricamento di immagini su un server save canvas image to server Fondamentalmente, la variabile "url" nella riga 56 era quello di cui avevo bisogno, ma non riuscivo a capire come inserirlo in una variabile universale da usare da un'altra funzione. Quindi, ho fatto un div nascosto e reso il suo contenuto uguale a "url". Ho quindi fatto riferimento a quel div in una nuova funzione chiamata "upload". Ho quindi utilizzato un file php chiamato "uploadWav.php". Devo ancora capire un modo per attivare e disattivare il pulsante di caricamento per impedire all'utente di caricare un file vuoto prima della registrazione, ma questo è un altro problema. Ecco il codice html e php finale che ha funzionato per me:

<!DOCTYPE html> 
<html> 
    <head> 
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> 
    <title>MP3 Recorder test</title> 
    </head> 
    <body id="index" onload=""> 

    <script type="text/javascript" src="jquery.min.js"></script> 
    <script type="text/javascript" src="mp3recorder.js"></script> 
    <script type="text/javascript"> 
    var audio_context; 

    function __log(e, data) { 
     log.innerHTML += "\n" + e + " " + (data || ''); 
    } 

    $(function() { 

     try { 
    // webkit shim 
    window.AudioContext = window.AudioContext || window.webkitAudioContext; 
    navigator.getUserMedia = (navigator.getUserMedia || 
        navigator.webkitGetUserMedia || 
        navigator.mozGetUserMedia || 
        navigator.msGetUserMedia); 
    window.URL = window.URL || window.webkitURL; 

    var audio_context = new AudioContext; 
    __log('Audio context set up.'); 
    __log('navigator.getUserMedia ' + (navigator.getUserMedia ? 'available.' : 'not present!')); 
    } catch (e) { 
    alert('No web audio support in this browser!'); 
    } 

    $('.recorder .start').on('click', function() { 
    $this = $(this); 
    $recorder = $this.parent(); 

    navigator.getUserMedia({audio: true}, function(stream) { 
     var recorderObject = new MP3Recorder(audio_context, stream, { statusContainer: $recorder.find('.status'), statusMethod: 'replace' }); 
     $recorder.data('recorderObject', recorderObject); 

     recorderObject.start(); 
    }, function(e) { }); 
    }); 

    $('.recorder .stop').on('click', function() { 
    $this = $(this); 
    $recorder = $this.parent(); 

    recorderObject = $recorder.data('recorderObject'); 
    recorderObject.stop(); 

    recorderObject.exportWAV(function(base64_wav_data) { 
     var url = 'data:audio/wav;base64,' + base64_wav_data; 
     var au = document.createElement('audio'); 

     document.getElementById("playerContainer").innerHTML = ""; 
     //console.log(url) 

     var duc = document.getElementById("dataUrlcontainer"); 
     duc.innerHTML = url; 

     au.controls = true; 
     au.src = url; 
     //$recorder.append(au); 
     $('#playerContainer').append(au); 

     recorderObject.logStatus(''); 
    }); 

    }); 

    }); 
    </script> 


<script> 
    function upload(){ 

    var dataURL = document.getElementById("dataUrlcontainer").innerHTML; 

     $.ajax({ 
     type: "POST", 
     url: "uploadWav.php", 
     data: { 
      wavBase64: dataURL 
     } 
    }).done(function(o) { 
     console.log('saved'); 

     }); 

    }  
    </script> 


<div class="recorder"> 
    Recorder 1 
    <input type="button" class="start" value="Record" /> 
    <input type="button" class="stop" value="Stop" /> 
    <pre class="status"></pre> 
</div> 

<div><button onclick="upload()">Upload</button></div> 

<div id="playerContainer"></div> 

<div id="dataUrlcontainer" hidden></div> 

<pre id="log"></pre> 

</body> 
</html> 

e il file "uploadWav.php":

<?php 
// requires php5 
define('UPLOAD_DIR', 'uploads/'); 
$img = $_POST['wavBase64']; 
$img = str_replace('data:audio/wav;base64,', '', $img); 
$img = str_replace(' ', '+', $img); 
$data = base64_decode($img); 
$file = UPLOAD_DIR . uniqid() . '.wav'; 
$success = file_put_contents($file, $data); 
print $success ? $file : 'Unable to save the file.'; 
?> 
+0

Morto collegamento github. – Ael

0
//**Server Side Code** 
package myPack; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 

import javax.servlet.ServletException; 
import javax.servlet.annotation.MultipartConfig; 
import javax.servlet.annotation.WebServlet; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import org.apache.commons.codec.binary.Base64; 

@WebServlet("/MyServlet") 
@MultipartConfig 
public class MyServlet extends HttpServlet { 
    private static final long serialVersionUID = 1L; 

    public MyServlet() { 
     super(); 
    } 

    protected void doGet(HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException { 
    } 

    protected void doPost(HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException { 
     try { 
      String name = request.getParameter("fname"); 
      String url = request.getParameter("myUrl"); 
      url = url.replace("data:audio/wav;base64,", ""); 
      url = url.replace(" ", "+"); 
      byte[] bytes = url.getBytes(); 
      byte[] valueDecoded = Base64.decodeBase64(bytes); 
      FileOutputStream os = new FileOutputStream(new File("D://" + name 
        + ".wav")); 
      os.write(valueDecoded); 
      os.close(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 
} 

**Client Side Code** 


<!DOCTYPE html> 
<html> 
<head> 
<meta http-equiv="Content-type" content="text/html; charset=utf-8"> 
<title>MP3 Recorder test</title> 
</head> 
<body id="index" onload=""> 

    <script type="text/javascript" src="js/jquery.min.js"></script> 
    <script type="text/javascript" src="js/recorder.js"></script> 
    <script type="text/javascript"> 
    var audio_context; 

    function __log(e, data) { 
     log.innerHTML += "\n" + e + " " + (data || ''); 
    } 

    $(function() { 

     try { 
     // webkit shim 
     window.AudioContext = window.AudioContext || window.webkitAudioContext; 
     navigator.getUserMedia = (navigator.getUserMedia || 
         navigator.webkitGetUserMedia || 
         navigator.mozGetUserMedia || 
         navigator.msGetUserMedia); 
     window.URL = window.URL || window.webkitURL; 

     var audio_context = new AudioContext; 
     __log('Audio context set up.'); 
     __log('navigator.getUserMedia ' + (navigator.getUserMedia ? 'available.' : 'not present!')); 
     } catch (e) { 
     alert('No web audio support in this browser!'); 
     } 

     $('.recorder .start').on('click', function() { 
     $this = $(this); 
     $recorder = $this.parent(); 

     navigator.getUserMedia({audio: true}, function(stream) { 
      var recorderObject = new MP3Recorder(audio_context, stream, { statusContainer: $recorder.find('.status'), statusMethod: 'replace' }); 
      $recorder.data('recorderObject', recorderObject); 

      recorderObject.start(); 
     }, function(e) { }); 
     }); 

     $('.recorder .stop').on('click', function() { 
     $this = $(this); 
     $recorder = $this.parent(); 

     recorderObject = $recorder.data('recorderObject'); 
     recorderObject.stop(); 

     recorderObject.exportWAV(function(base64_wav_data) { 
      var url = 'data:audio/wav;base64,' + base64_wav_data; 
      var au = document.createElement('audio'); 
      document.getElementById("playerContainer").innerHTML = ""; 
      //console.log(url) 

      var duc = document.getElementById("dataUrlcontainer"); 
      duc.innerHTML = url; 

      au.controls = true; 
      au.src = url; 
      //$recorder.append(au); 
      $('#playerContainer').append(au); 

      var fd = new FormData(); 
      fd.append('fname', 'test.wav'); 
      fd.append('myUrl', duc.innerHTML); 
     $.ajax({ 
       type: "POST", 
       url: "/audioPart2/MyServlet", 
       data: fd, 
       processData: false, 
       contentType: false 
      }); 
      recorderObject.logStatus(''); 
     }); 

     }); 

    }); 
    </script> 

    <div class="recorder"> 
     Recorder 1 <input type="button" class="start" value="Record" /> <input 
      type="button" class="stop" value="Stop" /> 
     <div id="playerContainer"></div> 
     <div id="dataUrlcontainer" hidden></div> 
     <pre class="status"></pre> 
    </div> 

<!-- <div class="recorder"> --> 
<!--  Recorder 2 <input type="button" class="start" value="Record" /> <input --> 
<!--   type="button" class="stop" value="Stop" /> --> 
<!--  <pre class="status"></pre> --> 
<!-- </div> --> 

    <pre id="log"></pre> 
</body> 
</html> 

**// Required JS 
1)jquery.min.js 
2) recorder.js** 


**recorder.js is below** 
(function(window){ 

    var RECORDER_WORKER_PATH = 'js/recorderWorker.js'; 
    var ENCODER_WORKER_PATH = 'js/mp3Worker.js'; 


    var MP3Recorder = function(context, stream, cfg) { 
    var config  = cfg || { statusContainer: null, statusMethod: 'append' } 

    var bufferLen = 4096; 
    var recording = false; 

    this.source  = context.createMediaStreamSource(stream); 
    this.node  = (context.createScriptProcessor || context.createJavaScriptNode).call(context, bufferLen, 1, 1); 

    var recorderWorker = new Worker(RECORDER_WORKER_PATH); 
    var encoderWorker = new Worker(ENCODER_WORKER_PATH); 
    var exportCallback; 


    // initialize the Recorder Worker 
    recorderWorker.postMessage({ cmd: 'init', sampleRate: context.sampleRate }); 

    // the recording loop 
    this.node.onaudioprocess = function(e) { 
     if(!recording) return; 
     recorderWorker.postMessage({ cmd: 'record', buffer: e.inputBuffer.getChannelData(0) }); 
    } 


    this.start = function() { 
     recording = true; 
     this.logStatus('recording...'); 
    } 
    this.stop = function() { 
     recording = false; 
     this.logStatus('stopping...'); 
    } 
    this.destroy = function() { recorderWorker.postMessage({ cmd: 'destroy' }); } 

    this.logStatus = function(status) { 
     if(config.statusContainer) { 
     if(config.statusMethod == 'append') { 
      config.statusContainer.text(config.statusContainer.text + "\n" + status); 
     } else { 
      config.statusContainer.text(status); 
     } 
     } 
    } 

    this.exportBlob = function(cb) { 
     exportCallback = cb; 
     if (!exportCallback) throw new Error('Callback not set'); 
     recorderWorker.postMessage({ cmd: 'exportBlob' }); 
    } 

    this.exportWAV = function(cb) { 
     // export the blob from the worker 
     this.exportBlob(function(blob) { 
     var fileReader = new FileReader(); 

     // read the blob as array buffer and convert it 
     // to a base64 encoded WAV buffer 
     fileReader.addEventListener("loadend", function() { 
      var resultBuffer = new Uint8Array(this.result); 
      cb(encode64(resultBuffer)); 
     }); 
     fileReader.readAsArrayBuffer(blob); 
     }); 
    } 

    this.exportMP3 = function(cb) { 
     this.logStatus('converting...'); 

     // export the blob from the worker 
     this.exportBlob(function(blob) { 
     var fileReader = new FileReader(); 

     fileReader.addEventListener("loadend", function() { 
      var wavBuffer = new Uint8Array(this.result); 
      var wavData = parseWav(wavBuffer); 

      encoderWorker.addEventListener('message', function(e) { 
      if (e.data.cmd == 'data') { 
       cb(encode64(e.data.buffer)); 
      } 
      }); 

      encoderWorker.postMessage({ cmd: 'init', config: { mode: 3, channels: 1, samplerate: wavData.sampleRate, bitrate: wavData.bitsPerSample } }); 
      encoderWorker.postMessage({ cmd: 'encode', buf: Uint8ArrayToFloat32Array(wavData.samples) }); 
      encoderWorker.postMessage({ cmd: 'finish' }); 
     }); 

     fileReader.readAsArrayBuffer(blob); 
     }); 
    } 




    // event listener for return values of the recorderWorker 
    recorderWorker.addEventListener('message', function(e) { 
     switch(e.data.from) { 
     case 'exportBlob': 
      exportCallback(e.data.blob); 
      break; 
     }; 
    }); 


    // HELPER FUNCTIONS 

    function encode64(buffer) { 
     var binary = ''; 
     var bytes = new Uint8Array(buffer); 
     var len  = bytes.byteLength; 

     for(var i = 0; i < len; i++) { 
      binary += String.fromCharCode(bytes[i]); 
     } 
     return window.btoa(binary); 
    } 

    function parseWav(wav) { 
     function readInt(i, bytes) { 
      var ret = 0, shft = 0; 

      while(bytes) { 
       ret += wav[i] << shft; shft += 8; 
       i++; bytes--; 
      } 
      return ret; 
     } 
     if(readInt(20, 2) != 1) throw 'Invalid compression code, not PCM'; 
     if(readInt(22, 2) != 1) throw 'Invalid number of channels, not 1'; 

     return { sampleRate: readInt(24, 4), bitsPerSample: readInt(34, 2), samples: wav.subarray(44) }; 
    } 

    function Uint8ArrayToFloat32Array(u8a){ 
     var f32Buffer = new Float32Array(u8a.length); 
     for (var i = 0; i < u8a.length; i++) { 
      var value = u8a[i<<1] + (u8a[(i<<1)+1]<<8); 
      if (value >= 0x8000) value |= ~0x7FFF; 
      f32Buffer[i] = value/0x8000; 
     } 
     return f32Buffer; 
    } 


    this.source.connect(this.node); 
    this.node.connect(context.destination); // this should not be necessary 
    } 

    window.MP3Recorder = MP3Recorder; 

})(window); 
+0

Questo codice è in Java e funziona bene ...... Testato – user2164096

Problemi correlati