【问题标题】:How to record audio/voice in background continuously in android?如何在android中连续录制后台音频/语音?
【发布时间】:2012-04-05 09:13:32
【问题描述】:

因为我想在后台录制音频,所以我使用服务..但我无法在服务中录制音频。

我在 Activity 中尝试了相同的代码,它对我有用。但是如何在输入语音/语音时在后台进行录音,这意味着如果有语音输入,则应该开始录音并且应该在后台...?

【问题讨论】:

  • 这些奇怪的缩进和> 符号是怎么回事?
  • 你搞定了吗??

标签: android


【解决方案1】:

在我的一个项目中,我需要从麦克风连续录制音频。我无法共享项目,但我可以共享特定的 AudioRecorder 类。

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.util.Log;

    public class AudioRecorder {
        public enum State {
            INITIALIZING,
            READY,
            RECORDING,
            ERROR,
            STOPPED
        };
        private byte[] audioBuffer = null;
        private int source = MediaRecorder.AudioSource.MIC;
        private int sampleRate = 0;
        private int encoder = 0;
        private int nChannels = 0;
        private int bufferRead = 0;
        private int bufferSize = 0;
        private RandomAccessFile tempAudioFile = null;
        public AudioRecord audioRecorder = null;
        private State state;
        private short bSamples = 16;
        private int framePeriod;

        // The interval in which the recorded samples are output to the file
        // Used only in uncompressed mode
        private static final int TIMER_INTERVAL = 120;
        volatile Thread t = null;
        public int TimeStamp = 0, count = 0, preTimeStamp = 0;

        public AudioRecorder(Context c) {
            this.sampleRate = 11025;
            this.encoder = AudioFormat.ENCODING_PCM_16BIT;
            this.nChannels = AudioFormat.CHANNEL_CONFIGURATION_MONO;
            this.preTimeStamp = (int) System.currentTimeMillis();
            myApp = (MyApp) c.getApplicationContext();
            mQueue = myApp.getQueue();

            try {
                /*          
                    String fileName = "/sdcard/XYZ/11025.wav";
                    tempAudioFile = new RandomAccessFile(fileName,"rw");
                */

                framePeriod = sampleRate * TIMER_INTERVAL / 1000;
                bufferSize = framePeriod * 2 * bSamples * nChannels / 8;

                if (bufferSize < AudioRecord.getMinBufferSize(sampleRate, nChannels, encoder)) {
                    bufferSize = AudioRecord.getMinBufferSize(sampleRate, nChannels, encoder);

                    // Set frame period and timer interval accordingly
                    framePeriod = bufferSize / (2 * bSamples * nChannels / 8);
                    Log.w(AudioRecorder.class.getName(), "Increasing buffer size to " + Integer.toString(bufferSize));
                }

                audioRecorder = new AudioRecord(source, sampleRate, nChannels, encoder, bufferSize);
                audioBuffer = new byte[2048];
                audioRecorder.setRecordPositionUpdateListener(updateListener);
                audioRecorder.setPositionNotificationPeriod(framePeriod);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        private AudioRecord.OnRecordPositionUpdateListener updateListener = new AudioRecord.OnRecordPositionUpdateListener() {
            @Override
            public void onPeriodicNotification(AudioRecord recorder) {
                //          Log.d(Constant.APP_LOG,"Into Periodic Notification...");
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            */
        }

        @Override
        public void onMarkerReached(AudioRecord recorder) {
            // TODO Auto-generated method stub
        }
    };

    public void start() {
        if (state == State.INITIALIZING) {
            audioRecorder.startRecording();
            state = State.RECORDING;

            t = new Thread() {
                public void run() {
                    //Here You can read your Audio Buffers
                    audioRecorder.read(audioBuffer, 0, 2048);
                }
            };

            t.setPriority(Thread.MAX_PRIORITY);
            t.start();
        } else {
            Log.e(AudioRecorder.class.getName(), "start() called on illegal state");
            state = State.ERROR;
        }
    }

    public void stop() {
        if (state == State.RECORDING) {
            audioRecorder.stop();
            Thread t1 = t;
            t = null;
            t1.interrupt();
            count = 0;
            state = State.STOPPED;
        } else {
            Log.e(AudioRecorder.class.getName(), "stop() called on illegal state");
            state = State.ERROR;
        }
    }

    public void release() {
        if (state == State.RECORDING) {
            stop();
        }

        if (audioRecorder != null) {
            audioRecorder.release();
        }
    }

    public void reset() {
        try {
            if (state != State.ERROR) {
                release();
            }
        } catch (Exception e) {
            Log.e(AudioRecorder.class.getName(), e.getMessage());

            state = State.ERROR;
        }
    }

    public State getState() {
        return state;
    }
}

现在,创建服务并调用 start() 方法并为您的目的操作录制的音频缓冲区。

希望对你有所帮助。

【讨论】:

  • 您好,感谢您的回复刚才我编辑了我的问题,我想在有语音(语音)输入时开始录制。如果是的话,你有什么想法吗?请分享
  • 嗨,Dipali 根据您编辑的问题,我刚刚遇到了这个线程stackoverflow.com/questions/9547197/android-sound-verification ...希望它会对您有所帮助。
  • 嗨@NIHANT 为什么你设置't.setPriority(Thread.MAX_PRIORITY);'?你能解释一下mQueue吗?和项目有关吗?
  • @prosoft:在我的项目中,有许多后台线程同时运行,为了避免优先级反转问题,我已将最大优先级设置为记录器线程。 mQueue 是一个 FIFO 队列变量,保存从 PCM 到 AAC 的转换缓冲区并将它们发送到网络。
  • 什么? myApp = (MyApp) c.getApplicationContext(); mQueue = myApp.getQueue();在您的代码中
【解决方案2】:

要在后台开始录制,您可以

  • 创建一个thread 并在线程内进行录制。

  • 创建一个service,它将在后台运行。

希望对你有帮助。

编辑 1

Thread recordInBackGround= new Thread(new Runnable() {
                    @Override
                    public void run() { 
//Your recording portion of the code goes here.
}
});

recordInBackGround.start();

【讨论】:

  • 我已经在使用线程和服务,但它给出了运行时异常
  • 如果你有任何正在后台录制的项目链接,请分享
  • 发布你的代码,线程给出运行时异常,然后我们可能会帮助你。
  • 你能解释一下“创建一个将在后台运行的服务”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-21
  • 2012-01-13
  • 1970-01-01
  • 2017-02-07
  • 1970-01-01
相关资源
最近更新 更多