Phonegap 插件录制音频

Posted

技术标签:

【中文标题】Phonegap 插件录制音频【英文标题】:Phonegap plugin record audio 【发布时间】:2015-08-15 22:14:05 【问题描述】:

我正在尝试为 phonegap 创建一个 android 插件,该插件开始记录噪音,当用户开始说话时停止噪音记录并开始新的语音记录。

我已经能够让它在 android 中运行,但是当我尝试将它添加为 phonegap 插件时它不起作用。

代码如下:

RecordVoice.js

var RecordVoice = 
 startRecord: function(successCallback, errorCallback) 
    cordova.exec(
        successCallback, // success callback function
        errorCallback, // error callback function
        'RecordVoice', // mapped to our native Java class called     "RecordVoicePlugin"
        'startrecording'); 
 

module.exports = RecordVoice;

RecordVoice.java

    package org.maria.RecordVoice;  
    import org.apache.cordova.CallbackContext;
    import org.apache.cordova.CordovaPlugin;
    import org.json.JSONObject;
    import org.json.JSONArray;
    import org.json.JSONException;

    import android.app.Activity;
    import android.content.Intent;
    import com.androidexample.noisealert.R;
    import android.app.Activity;
    import android.content.Context;
    import android.media.MediaRecorder;
    import android.os.Bundle;
    import android.os.Environment;
    import android.os.Handler;
    import android.os.PowerManager;
    import android.util.Log;
    import android.widget.TextView;
    import android.widget.Toast;

    import java.io.IOException;

    public class NoiseAlert extends CordovaPlugin  
    public static final String ACTION_ADD_RECORD_ENTRY = "startrecording";
        /* constants */
            private static final int POLL_INTERVAL = 300;

            /** running state **/
            private boolean mRunning = false;

            /** config state **/
            private int mThreshold;

            private PowerManager.WakeLock mWakeLock;

            private Handler mHandler = new Handler();

            /* References to view elements */
            private TextView mStatusView;
            private SoundLevelView mDisplay;

            /* sound data source */

        private  boolean thesholdReached =false;
        @Override
        public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException 
            try 
                if (ACTION_ADD_RECORD_ENTRY.equals(action))  
                    JSONObject arg_object = args.getJSONObject(0);

                 cordova.getActivity().runOnUiThread(new Runnable() 
                     public void run() 
                          double amp = getAmplitude();

                            //Log.i("Noise", "runnable mPollTask");
                            updateDisplay(amp, amp);

                            if ((amp > mThreshold)) 
                                  //start();

                                if(thesholdReached==false) 
                                    stop();
                                    startrecordingvoice();
                                    // Show alert when noise thersold crossed
                                    Toast.makeText(getApplicationContext(), "Noise Thersold Crossed, do here your stuff.",
                                            Toast.LENGTH_LONG).show();
                                    //callForHelp();
                                    //Log.i("Noise", "==== onCreate ===");
                                    thesholdReached=true;
                                
                            

                         callbackContext.success(); 
                    
                

                   return true;
                
                callbackContext.error("Invalid action");
                return false;
             catch(Exception e) 
                System.err.println("Exception: " + e.getMessage());
                callbackContext.error(e.getMessage());
                return false;
             
        


            private void start() 

                    startrecordingnoise();
                    if (!mWakeLock.isHeld()) 
                            mWakeLock.acquire();
                    

                    //Noise monitoring start
                    // Runnable(mPollTask) will execute after POLL_INTERVAL
                    mHandler.postDelayed(mPollTask, POLL_INTERVAL);
            

            private void stop() 
                Log.i("Noise", "==== Stop Noise Monitoring===");
                    if (mWakeLock.isHeld()) 
                            mWakeLock.release();
                    
                    mHandler.removeCallbacks(mSleepTask);
                    mHandler.removeCallbacks(mPollTask);

                if (mRecorder != null) 
                    mRecorder.stop();
                    mRecorder.release();
                    mRecorder = null;
                
                    mDisplay.setLevel(0,0);

                    mRunning = false;

            


            private void initializeApplicationConstants() 
                    // Set Noise Threshold
                    mThreshold = 8;

            

            private void updateDisplay(double ampl, double signalEMA) 
                    mStatusView.setText(Double.toString(ampl));
                    // 
                    mDisplay.setLevel((int)signalEMA, mThreshold);
            


            private void callForHelp() 

                stop();
                startrecordingvoice();
                 // Show alert when noise thersold crossed
                  Toast.makeText(getApplicationContext(), "Noise Thersold Crossed, do here your stuff.",
                          Toast.LENGTH_LONG).show();

            
        // This file is used to record voice
        static final private double EMA_FILTER = 0.6;

        private MediaRecorder mRecorder = null;
        private double mEMA = 0.0;

        public void startrecordingnoise() 

            if (mRecorder == null) 
                String outputFile = null;
                outputFile = Environment.getExternalStorageDirectory() + "/NoiseRecording.amr";

                mRecorder = new MediaRecorder();
                mRecorder.setAudiosource(MediaRecorder.AudioSource.MIC);
                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                //mRecorder.setOutputFile("/dev/null");
                mRecorder.setOutputFile(outputFile);

                try 
                    mRecorder.prepare();
                 catch (IllegalStateException e) 
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                 catch (IOException e) 
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                

                mRecorder.start();
                mEMA = 0.0;
            
        
        public void startrecordingvoice() 

            if (mRecorder == null) 
                String outputFile = null;
                outputFile = Environment.getExternalStorageDirectory() + "/VoiceRecording.amr";

                mRecorder = new MediaRecorder();
                mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                //mRecorder.setOutputFile("/dev/null");
                mRecorder.setOutputFile(outputFile);

                try 
                    mRecorder.prepare();
                 catch (IllegalStateException e) 
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                 catch (IOException e) 
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                

                mRecorder.start();
                mEMA = 0.0;
            
        


        public double getAmplitude() 
            if (mRecorder != null)
                return  (mRecorder.getMaxAmplitude()/2700.0);
            else
                return 0;

        

        public double getAmplitudeEMA() 
            double amp = getAmplitude();
            mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
            return mEMA;
        

    ;

index.js

            var app = 
                // Application Constructor
                initialize: function() 
                    this.bindEvents();
                ,
                // Bind Event Listeners
                //
                // Bind any events that are required on startup. Common events are:
                // 'load', 'deviceready', 'offline', and 'online'.
                bindEvents: function() 
                    document.addEventListener('deviceready', this.onDeviceReady, false);
                ,
                // deviceready Event Handler
                //
                // The scope of 'this' is the event. In order to call the 'receivedEvent'
                // function, we must explicitly call 'app.receivedEvent(...);'
                onDeviceReady: function() 
                    app.receivedEvent('deviceready');
                    app.addToCal();
                ,
                // Update DOM on a Received Event
                receivedEvent: function(id) 
                    var parentElement = document.getElementById(id);
                    var listeningElement = parentElement.querySelector('.listening');
                    var receivedElement = parentElement.querySelector('.received');

                    listeningElement.setAttribute('style', 'display:none;');
                    receivedElement.setAttribute('style', 'display:block;');

                    console.log('Received Event: ' + id);
                ,
            addToCal: function() 

                    var success = function()  alert("Success"); ;
                    var error = function(message)  alert("Oopsie! " + message); ;
                    RecordVoice.startRecord(success, error);
            
            ;

plugin.xml

<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
       id="org.maria.RecordVoice"
  version="0.1.0">
<name>RecordVoice</name>
<description>Sample PhoneGap RecordVoice Plugin</description>
<license>MIT</license>
<keywords>phonegap,RecordVoice</keywords>


<js-module src="www/RecordVoice.js" name="RecordVoice">
    <clobbers target="window.RecordVoice" />
</js-module>

<!-- android -->
<platform name="android">
    <config-file target="res/xml/config.xml" parent="/*">
        <feature name="RecordVoice">
            <param name="android-package" value="org.maria.RecordVoice.RecordVoice"/>
        </feature>
    </config-file>

    <source-file src="src/android/RecordVoice.java" target-dir="src/org/maria/RecordVoice" />      
 </platform>          

知道为什么它不起作用吗? 非常感谢您!

最好的问候!

【问题讨论】:

【参考方案1】:

在您的 RecordVoice.js 文件中尝试将空数组 [] 添加到 exec 函数:

var RecordVoice = 
 startRecord: function(successCallback, errorCallback) 
 cordova.exec(
    successCallback, // success callback function
    errorCallback, // error callback function
    'RecordVoice', // mapped to our native Java class called "RecordVoicePlugin"
    'startrecording',
    []
 ); 


module.exports = RecordVoice;

【讨论】:

以上是关于Phonegap 插件录制音频的主要内容,如果未能解决你的问题,请参考以下文章

使用phonegap在iphone上录制音频

用PhoneGap录制音频

使用 PhoneGap 将音频录制到 iOS 上的文档文件夹

phoneGap/Apache Cordova 媒体捕获插件 - 多视频录制

Javascript / HTML5 - 用于网络桌面/移动应用程序的音频流录制

使用外部 Java 插件在 PhoneGap/Cordova 中捕获音频/视频