Android5.1 录音机 MediaRecorder、微信 AudioRecord

 

Android提供了两个对象用于录音的实现:MediaRecorder 和AudioRecord

1.MediaRecorder:录制的音频文件是经过压缩后的,需要设置编码器 并且录制的音频文件可以用系统自带的Music播放器播放 MediaRecorder已经集成了录音、编码、压缩等,并支持少量的录音音频格式,但是这也是他的缺点,支持的格式过少并且无法实时处理音频数据
2.AudioRecord:主要实现对音频实时处理以及边录边播功能,相对MediaRecorder比较专业,输出是PCM语音数据 如果保存成音频文件,是不能够被播放器播放的,所以必须先写代码实现数据编码以及压缩

 

一.录音机

1.1.packages\apps\SoundRecorder\src\com\android\soundrecorder\Recorder.java

mRecorder.prepare(); //准备

mRecorder.start();//开始

     public void startRecording(int outputfileformat, int recordingType,String extension, Context context) {
        stop();
        if (mSampleFile == null) {
            String myExtension = extension + TEMP_SUFFIX;
            File sampleDir = Environment.getExternalStorageDirectory();
            if (!sampleDir.canWrite()) // Workaround for broken sdcard support on the device.
                sampleDir = new File("/sdcard/sdcard");
            String sampleDirPath = null;
            if (sampleDir != null) {
                sampleDirPath = sampleDir.getAbsolutePath() + File.separator
                        + RECORD_FOLDER;
            }
            if (sampleDirPath != null) {
                sampleDir = new File(sampleDirPath);
            }
            if (sampleDir != null && !sampleDir.exists()) {
                if (!sampleDir.mkdirs()) {
                    Log.i(TAG, "<startRecording> make dirs fail");
                }
            }
            try {
                if (null != sampleDir) {
                    Log.i(TAG, "SR sampleDir  is:" + sampleDir.toString());
                }
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
                        "yyyyMMddHHmmss");
                String time = simpleDateFormat.format(new Date(System
                        .currentTimeMillis()));
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.append(SAMPLE_PREFIX).append("_"+time)
                        .append(myExtension);
                String name = stringBuilder.toString();
                mSampleFile = new File(sampleDir, name);
                boolean result = mSampleFile.createNewFile();
                if (result) {
                    Log.i(TAG, "creat file success");
                }
            } catch (IOException e) {
                setError(SDCARD_ACCESS_ERROR);
                return;
            }
        }
        
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(outputfileformat);
        mRecorder.setOutputFile(mSampleFile.getAbsolutePath());

		mRecorder.setAudioSamplingRate(mSamplingRate);

1.2.frameworks\base\media\java\android\media\MediaRecorder.java

     public native void start() throws IllegalStateException;
     public native void stop() throws IllegalStateException;

1.3.frameworks\base\media\jni\android_media_MediaCodec.cpp

static void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) {
    ALOGV("android_media_MediaCodec_start");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    status_t err = codec->start();

    throwExceptionAsNecessary(env, err, ACTION_CODE_FATAL, "start failed");
}

static void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) {
    ALOGV("android_media_MediaCodec_stop");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return;
    }

    status_t err = codec->stop();

    throwExceptionAsNecessary(env, err);
}

 二.微信

2.1.AudioRecord

    /**
     * 开始录音
     *
     * @param listener 音频流的监听
     */
    public void startRecord(final RecordStreamListener listener) {

        if (status == Status.STATUS_NO_READY || TextUtils.isEmpty(fileName)) {
            throw new IllegalStateException("录音尚未初始化,请检查是否禁止了录音权限~");
        }
        if (status == Status.STATUS_START) {
            throw new IllegalStateException("正在录音");
        }
        Log.d("AudioRecorder", "===startRecord===" + audioRecord.getState());
        audioRecord.startRecording();

        new Thread(new Runnable() {
            @Override
            public void run() {
                writeDataTOFile(listener);
            }
        }).start();
    }

2.2.frameworks\base\media\java\android\media\AudioRecord.java

    /**
     * Starts recording from the AudioRecord instance.
     * @throws IllegalStateException
     */
    public void startRecording()
    throws IllegalStateException {
        if (mState != STATE_INITIALIZED) {
            throw new IllegalStateException("startRecording() called on an "
                    + "uninitialized AudioRecord.");
        }

        // start recording
        synchronized(mRecordingStateLock) {
            if (native_start(MediaSyncEvent.SYNC_EVENT_NONE, 0) == SUCCESS) {
                handleFullVolumeRec(true);
                mRecordingState = RECORDSTATE_RECORDING;
            }
            mFileObserver.startWatching();
        }
    }

    /**
     * Starts recording from the AudioRecord instance when the specified synchronization event
     * occurs on the specified audio session.
     * @throws IllegalStateException
     * @param syncEvent event that triggers the capture.
     * @see MediaSyncEvent
     */
    public void startRecording(MediaSyncEvent syncEvent)
    throws IllegalStateException {
        if (mState != STATE_INITIALIZED) {
            throw new IllegalStateException("startRecording() called on an "
                    + "uninitialized AudioRecord.");
        }

        // start recording
        synchronized(mRecordingStateLock) {
            if (native_start(syncEvent.getType(), syncEvent.getAudioSessionId()) == SUCCESS) {
                handleFullVolumeRec(true);
                mRecordingState = RECORDSTATE_RECORDING;
            }
        }
        mFileObserver.startWatching();
    }

  

 

posted @ 2021-11-18 15:04  CrushGirl  阅读(251)  评论(0编辑  收藏  举报