cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From macdo...@apache.org
Subject [1/3] cordova-plugin-media git commit: CB-10776: Add the ability to pause and resume an audio recording (Android)
Date Tue, 26 Apr 2016 16:15:07 GMT
Repository: cordova-plugin-media
Updated Branches:
  refs/heads/master 16729db82 -> a3e639bf9


CB-10776: Add the ability to pause and resume an audio recording (Android)


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/commit/a3e639bf
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/tree/a3e639bf
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/diff/a3e639bf

Branch: refs/heads/master
Commit: a3e639bf995a74ea3ee84d7deb7009cc777791a6
Parents: b1ef73d
Author: Simon MacDonald <simon.macdonald@gmail.com>
Authored: Thu Apr 7 21:40:50 2016 -0400
Committer: Simon MacDonald <simon.macdonald@gmail.com>
Committed: Tue Apr 26 12:10:31 2016 -0400

----------------------------------------------------------------------
 src/android/AudioHandler.java |  26 +++++++--
 src/android/AudioPlayer.java  | 117 +++++++++++++++++++++++++++++++------
 2 files changed, 121 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/blob/a3e639bf/src/android/AudioHandler.java
----------------------------------------------------------------------
diff --git a/src/android/AudioHandler.java b/src/android/AudioHandler.java
index 39702a1..5f5659c 100644
--- a/src/android/AudioHandler.java
+++ b/src/android/AudioHandler.java
@@ -118,7 +118,13 @@ public class AudioHandler extends CordovaPlugin {
             promptForRecord();
         }
         else if (action.equals("stopRecordingAudio")) {
-            this.stopRecordingAudio(args.getString(0));
+            this.stopRecordingAudio(args.getString(0), true);
+        }
+        else if (action.equals("pauseRecordingAudio")) {
+            this.stopRecordingAudio(args.getString(0), false);
+        }
+        else if (action.equals("resumeRecordingAudio")) {
+            this.resumeRecordingAudio(args.getString(0));
         }
         else if (action.equals("startPlayingAudio")) {
             String target = args.getString(1);
@@ -282,13 +288,25 @@ public class AudioHandler extends CordovaPlugin {
     }
 
     /**
-     * Stop recording and save to the file specified when recording started.
+     * Stop/Pause recording and save to the file specified when recording started.
      * @param id				The id of the audio player
+     * @param stop      If true stop recording, if false pause recording
      */
-    public void stopRecordingAudio(String id) {
+    public void stopRecordingAudio(String id, boolean stop) {
         AudioPlayer audio = this.players.get(id);
         if (audio != null) {
-            audio.stopRecording();
+            audio.stopRecording(stop);
+        }
+    }
+
+    /**
+     * Resume recording
+     * @param id				The id of the audio player
+     */
+    public void resumeRecordingAudio(String id) {
+        AudioPlayer audio = players.get(id);
+        if (audio != null) {
+            audio.resumeRecording();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/blob/a3e639bf/src/android/AudioPlayer.java
----------------------------------------------------------------------
diff --git a/src/android/AudioPlayer.java b/src/android/AudioPlayer.java
index 26248e5..2cac5e0 100644
--- a/src/android/AudioPlayer.java
+++ b/src/android/AudioPlayer.java
@@ -32,7 +32,11 @@ import org.json.JSONObject;
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.IOException;
+import java.util.LinkedList;
 
 /**
  * This class implements the audio playback and recording capabilities used by Cordova.
@@ -81,7 +85,8 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener,
On
     private float duration = -1;            // Duration of audio
 
     private MediaRecorder recorder = null;  // Audio recording object
-    private String tempFile = null;         // Temporary recording file name
+    private LinkedList<String> tempFiles = null; // Temporary recording file name
+    private String tempFile = null;
 
     private MediaPlayer player = null;      // Audio player object
     private boolean prepareOnly = true;     // playback after file prepare flag
@@ -98,13 +103,17 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener,
On
         this.id = id;
         this.audioFile = file;
         this.recorder = new MediaRecorder();
+        this.tempFiles = new LinkedList<String>();
+    }
 
-        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
-            this.tempFile = Environment.getExternalStorageDirectory().getAbsolutePath() +
"/tmprecording.3gp";
-        } else {
-            this.tempFile = "/data/data/" + handler.cordova.getActivity().getPackageName()
+ "/cache/tmprecording.3gp";
-        }
-
+    private String generateTempFile() {
+      String tempFileName = null;
+      if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+          tempFileName = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tmprecording-"
+ System.currentTimeMillis() + ".3gp";
+      } else {
+          tempFileName = "/data/data/" + handler.cordova.getActivity().getPackageName() +
"/cache/tmprecording-" + System.currentTimeMillis() + ".3gp";
+      }
+      return tempFileName;
     }
 
     /**
@@ -121,7 +130,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener,
On
             this.player = null;
         }
         if (this.recorder != null) {
-            this.stopRecording();
+            this.stopRecording(true);
             this.recorder.release();
             this.recorder = null;
         }
@@ -141,8 +150,9 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener,
On
         case NONE:
             this.audioFile = file;
             this.recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
-            this.recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); // THREE_GPP);
-            this.recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); //AMR_NB);
+            this.recorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR); // THREE_GPP);
+            this.recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); //AMR_NB);
+            this.tempFile = generateTempFile();
             this.recorder.setOutputFile(this.tempFile);
             try {
                 this.recorder.prepare();
@@ -170,7 +180,6 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener,
On
      */
     public void moveFile(String file) {
         /* this is a hack to save the file as the specified name */
-        File f = new File(this.tempFile);
 
         if (!file.startsWith("/")) {
             if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
@@ -180,23 +189,88 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener,
On
             }
         }
 
-        String logMsg = "renaming " + this.tempFile + " to " + file;
-        Log.d(LOG_TAG, logMsg);
-        if (!f.renameTo(new File(file))) Log.e(LOG_TAG, "FAILED " + logMsg);
+        int size = this.tempFiles.size();
+        Log.d(LOG_TAG, "size = " + size);
+
+        // only one file so just copy it
+        if (size == 1) {
+            String logMsg = "renaming " + this.tempFile + " to " + file;
+            Log.d(LOG_TAG, logMsg);
+            File f = new File(this.tempFile);
+            if (!f.renameTo(new File(file))) Log.e(LOG_TAG, "FAILED " + logMsg);
+        }
+        // more than one file so the user must have pause recording. We'll need to concat
files.
+        else {
+          FileOutputStream outputStream = null;
+          try {
+              outputStream = new FileOutputStream(new File(file));
+              FileInputStream inputStream = null;
+              File inputFile = null;
+              for (int i = 0; i < size; i++) {
+                  try {
+                      inputFile = new File(this.tempFiles.get(i));
+                      inputStream = new FileInputStream(inputFile);
+                      copy(inputStream, outputStream, (i>0));
+                  } catch(Exception e) {
+                      Log.e(LOG_TAG, e.getLocalizedMessage(), e);
+                  } finally {
+                      if (inputStream != null) try {
+                          inputStream.close();
+                          inputFile.delete();
+                          inputFile = null;
+                      } catch (Exception e) {
+                          Log.e(LOG_TAG, e.getLocalizedMessage(), e);
+                      }
+                  }
+              }
+          } catch(Exception e) {
+              e.printStackTrace();
+          } finally {
+              if (outputStream != null) try {
+                  outputStream.close();
+              } catch (Exception e) {
+                  Log.e(LOG_TAG, e.getLocalizedMessage(), e);
+              }
+          }
+        }
+    }
+
+    private static long copy(InputStream from, OutputStream to, boolean skipHeader)
+                throws IOException {
+        byte[] buf = new byte[8096];
+        long total = 0;
+        if (skipHeader) {
+            from.skip(6);
+        }
+        while (true) {
+            int r = from.read(buf);
+            if (r == -1) {
+                break;
+            }
+            to.write(buf, 0, r);
+            total += r;
+        }
+        return total;
     }
 
     /**
-     * Stop recording and save to the file specified when recording started.
+     * Stop/Pause recording and save to the file specified when recording started.
      */
-    public void stopRecording() {
+    public void stopRecording(boolean stop) {
         if (this.recorder != null) {
             try{
                 if (this.state == STATE.MEDIA_RUNNING) {
                     this.recorder.stop();
-                    this.setState(STATE.MEDIA_STOPPED);
                 }
                 this.recorder.reset();
-                this.moveFile(this.audioFile);
+                this.tempFiles.add(this.tempFile);
+                if (stop) {
+                    Log.d(LOG_TAG, "stopping recording");
+                    this.setState(STATE.MEDIA_STOPPED);
+                    this.moveFile(this.audioFile);
+                } else {
+                    Log.d(LOG_TAG, "pause recording");
+                }
             }
             catch (Exception e) {
                 e.printStackTrace();
@@ -204,6 +278,13 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener,
On
         }
     }
 
+    /**
+     * Resume recording and save to the file specified when recording started.
+     */
+    public void resumeRecording() {
+        startRecording(this.audioFile);
+    }
+
     //==========================================================================
     // Playback
     //==========================================================================


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org


Mime
View raw message