Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Phonegap Media API - Record and Play Audio - Android

I'm hoping to record some audio and then have the ability to play it back. Its important for me to be able to customize the record interface.

In the below example after recording I get a duration of -1 and no audio is played.

Step 1. Added Media Plugin

cordova plugin add org.apache.cordova.media

Step 2. My Code

Note src is "amr" as requested from docs.

Android devices record audio in Adaptive Multi-Rate format. The specified file should end with a .amr extension.

However, "myrecording.amr" does not exist in my file structure as I'm hoping it will be created.

Javascript

var data = {
  rec: ""
};
$scope.record = function(){
    console.log('record');
    var src = "myrecording.amr";
    data.rec = new Media(src,
    function() {
      console.log("recordAudio():Audio Success");
    },

    function(err) {
      console.log("recordAudio():Audio Error: "+ err.code);
    });

    data.rec.startRecord();
}

$scope.stopRecording = function(){
    console.log('stop');
    data.rec.stopRecord();
}

$scope.playRecording = function(){
    console.log('play');
    data.rec.play();
}

$scope.logDuration = function(){
    console.log(data.rec.getDuration());
}

HTML

<button ng-click="record()">Record</button>
<button ng-click="stopRecording()">Stop Record</button>
<button ng-click="playRecording()">Play Record</button>
<button ng-click="logDuration()">Log Duration</button>

Output From Above

No audio is played when I click play.

0     999846   log      record
1     001845   log      stop
2     002000   log      recordAudio():Audio Success
3     004657   log      play
4     008989   log      -1

Any help would be greatly appreciated. Let me know if I can answer any questions.

like image 762
Daniel Rasmuson Avatar asked Oct 23 '14 02:10

Daniel Rasmuson


2 Answers

Here are my steps for getting this to work.

1. Run these commands

ionic start RecordTest blank
ionic platform add ios
cordova plugin add org.apache.cordova.media

2. Create RecordTest/www/myrecording.wav

3. Paste the below code in RecordTest/www/index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <title></title>

    <link href="lib/ionic/css/ionic.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">

    <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
    <link href="css/ionic.app.css" rel="stylesheet">
    -->

    <!-- ionic/angularjs js -->
    <script src="lib/ionic/js/ionic.bundle.js"></script>

    <!-- cordova script (this will be a 404 during development) -->
    <script src="cordova.js"></script>

    <!-- your app's js -->
    <!-- <script src="js/app.js"></script> -->
    <script type="text/javascript" charset="utf-8">

    // Wait for PhoneGap to load
    //
    document.addEventListener("deviceready", onDeviceReady, false);

    // Record audio
    // 
    function recordAudio() {
        var src = "myrecording.wav";
        var mediaRec = new Media(src, onSuccess, onError);

        // Record audio
        mediaRec.startRecord();

        // Stop recording after 10 sec
        var recTime = 0;
        var recInterval = setInterval(function() {
            recTime = recTime + 1;
            setAudioPosition(recTime + " sec");
            if (recTime >= 3) {
                clearInterval(recInterval);
                mediaRec.stopRecord();
                mediaRec.play();
            }
        }, 1000);
    }

    // PhoneGap is ready
    //
    function onDeviceReady() {
        recordAudio();
    }

    // onSuccess Callback
    //
    function onSuccess() {
        console.log("recordAudio():Audio Success");
    }

    // onError Callback 
    //
    function onError(error) {
        alert('code: '    + error.code    + '\n' + 
              'message: ' + error.message + '\n');
    }

    // Set audio position
    // 
    function setAudioPosition(position) {
        document.getElementById('audio_position').innerHTML = position;
    }
    </script>
  </head>
  <body ng-app="starter">
    <ion-pane>
      <ion-header-bar class="bar-stable">
        <h1 class="title">Ionic Blank Starter</h1>
      </ion-header-bar>
      <ion-content>
          <title>Device Properties Example</title>
          <!-- <script type="text/javascript" charset="utf-8" src="phonegap-1.4.1.js"></script> -->
          <p id="media">Recording audio...</p>
          <p id="audio_position"></p>
      </ion-content>
    </ion-pane>
  </body>
</html>

4. Run ionic emulate ios

The above should work.

Note: the extension changes depending on the platform you're developing for

like image 130
Daniel Rasmuson Avatar answered Nov 03 '22 04:11

Daniel Rasmuson


I'm working with something similar with ionicframworkf and phonegap plugins.. I build a Record Factory for:

startRecord, stopRecord, playRecord and Save record to the server... This is my factory file:

 /**
 * Record service
 * @module record
 * @author Claudio A. Marrero
 * @class famvoice
 */
 services.factory('$record', [

  '$rootScope',
  '$socket',
  '$account',

  function($rootScope, $socket, $account) {

    var enumerator = 0;
    var recordName = 'record-'+enumerator+'.mp3';
    var mediaRec = null;
    var OnCallback = null;
    var OnAppendData = {};

    /**
    * Start a record
    *
    * @method startRecord
    */
    function startRecord(){
      enumerator++;
      recordName = 'record-'+enumerator+'.mp3';
      mediaRec = new Media(recordName,
          function() {
          },
          function(err) {
          });
      mediaRec.startRecord();
    }

    /**
    * Stop record
    *
    * @method stopRecord
    */
    function stopRecord(){
      mediaRec.stopRecord();
    }

    /**
    * Stop record
    *
    * @method stopRecord
    */
    function playRecord(){
      mediaRec.play();
    }

    /**
    * Get the name of the record
    *
    * @method getRecord
    */
    function getRecord(){
      return recordName;
    }

    /**
    * Save the recorded file to the server
    *
    * @method save
    */
    function save(callback,appendData){
      OnCallback = callback;
      OnAppendData = appendData;
      window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, OnFileSystem, fail);
    }

    /**
    * Callback for setting the file system to persistent.
    *
    * @method OnFileSystem
    */
    function OnFileSystem(fileSystem){
      fileSystem.root.getFile(recordName, null, OnGetFile, fail);
    }

    /**
    * Callback for geting the file for disk
    *
    * @method OnGetFile
    */
    function OnGetFile(fileEntry){
      fileEntry.file(OnFileEntry, fail);
    }

    /**
    * Callback for file entry, this get the file.
    *
    * @method OnFileEntry
    */
    function OnFileEntry(file){
      var reader = new FileReader();
      reader.onloadend = function(evt) {

          var image = evt.target.result;
          var base64Data  =   image.replace(/^data:audio\/mpeg;base64,/, "");
          base64Data  +=  base64Data.replace('+', ' ');

          $socket.emit('playlists:file',{file:base64Data,name:recordName, token: $account.token(), info:OnAppendData},OnCallback);
      };
      reader.readAsDataURL(file);
    }

    /**
    * When any process of saving file fail, this console the error.
    *
    * @method OnFileEntry
    */
    function fail(err){
      console.log('Error');
      console.log(err);
    }

    /**
    * Play record
    *
    * @method playRecord
    */
    function playRecord(){
      var mediaFile = new Media(recordName,
          function() {
            console.log("playAudio():Audio Success");
          },
          function(err) {
            console.log("playAudio():Audio Error: "+err);
          }
      );
      // Play audio
      mediaFile.play();
    }

  return {
    start: startRecord,
    stop: stopRecord,
    play:playRecord,
    name:getRecord,
    save:save
  };
}]);

My project is on GitHub if you want to check how I implement this factory:

https://github.com/cmarrero01/famvoice

You will need to checkout the development branch.

I hope that is ussesful for you. :)

PH: I notice this question on codementor request, but I'm not a good english speaker. :)

like image 39
cmarrero01 Avatar answered Nov 03 '22 05:11

cmarrero01