5

Android中实现系统声音录制-RK3399开发板源码修改

 2 years ago
source link: https://www.51cto.com/article/716095.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
959e90405e86761bf5b077b9079a128b9e3dc4.png

这几天做系统声音录制,通过改源码编译后成功的;那就详细介绍下内置声源的录制方案。

Android中可以通过使用MediaRecorder.AudioSource.REMOTE_SUBMIX来实现系统声音的录制,这个属性只有系统应用能够使用。

而且这个属性会截掉耳机和扬声器的声音,听不到手机中播放音乐或者视频时的声音。

这个时候我们就要来改系统源码。

一、录音的简单实现

AudioRecord  audioRecord = new AudioRecord(MediaRecorder.AudioSource.REMOTE_SUBMIX
                , captureSampleRate
                , captureChannel
                , AudioFormat.ENCODING_PCM_16BIT
                , recordBufferSize);
     new Thread(new Runnable() {
            @Override
            public void run() {
                final byte[] bytes = new byte[recordBufferSize];
                audioRecord.read(bytes, 0, bytes.length);
                audioRecord.setPositionNotificationPeriod(captureSampleRate / 25);
                audioRecord.setRecordPositionUpdateListener(new AudioRecord.OnRecordPositionUpdateListener() {
                    @Override
                    public void onMarkerReached(AudioRecord recorder) {
                    }
                    @Override
                    public void onPeriodicNotification(AudioRecord recorder) {
                        singleThreadPool.execute(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    if(audioRecord!=null){
                                        audioRecord.read(bytes, 0, bytes.length);
                                        PcmBuffer.clear();
                                        PcmBuffer.put(bytes, 0, recordBufferSize);
                                        audioFrameParam.sampleRate = ZEGO_AUDIO_SAMPLE_RATE_44K;
                                      //声音的处理
                                    }
                                }catch (Exception e){
                                    e.printStackTrace();
                                }
                            }
                        });
                    }
                });
                audioRecord.startRecording();
            }
        }).start();

二、AudioSource输入源介绍​

public final class AudioSource {
private AudioSource() {}
/** Default audio source **/
public static final int DEFAULT = 0;
/** Microphone audio source */
public static final int MIC = 1;
/** Voice call uplink (Tx) audio source */
public static final int VOICE_UPLINK = 2;
/** Voice call downlink (Rx) audio source */
public static final int VOICE_DOWNLINK = 3;
/** Voice call uplink + downlink audio source */
public static final int VOICE_CALL = 4;
/** Microphone audio source with same orientation as camera if available, the main
 *  device microphone otherwise */
public static final int CAMCORDER = 5;
public static final int VOICE_RECOGNITION = 6;
public static final int VOICE_COMMUNICATION = 7;
public static final int REMOTE_SUBMIX = 8;
}
  • DEFAULT:默认为MIC,android.permission.RECORD_AUDIO。
  •  MIC:麦克风,android.permission.RECORD_AUDIO。
  • VOICE_UPLINK:电话录音上行线路,android.permission.CAPTURE_AUDIO_OUTPUT,系统权限不允许第三方app使用 。
  • VOICE_DOWNLINK:电话录音下行线路,android.permission.CAPTURE_AUDIO_OUTPUT,系统权限不允许第三方app使用。
  •  VOICE_CALL:电话录音上下线路,android.permission.CAPTURE_AUDIO_OUTPUT,系统权限不允许第三方app使用 。
  • CAMCORDER:摄像头的麦克风,android.permission.RECORD_AUDIO。
  • VOICE_RECOGNITION:语音识别,android.permission.RECORD_AUDIO。
  • VOICE_COMMUNICATION:网络电话,android.permission.RECORD_AUDIO。
  • REMOTE_SUBMIX:传输到远程的音频混合流,默认情况下如果用该项录音,本地扬声器或者耳机的声音将会被截走,android.permission.CAPTURE_AUDIO_OUTPUT,系统权限不允许第三方app使用。

REMOTE_SUBMIX使用的注意事项

(1)需要系统权限 。

(2)会截走扬声器和耳机的声音,也就是说再录音时本地无法播放声音。

对于系统权限,需要在在AndroidManifest.xml添加 android:sharedUserId="android.uid.system",然后使用系统签名来打包应用,这样就第三方应用打包为系统应用,就可以使用系统权限了。

三、源码修改

1、Android 10及以下的录屏

frameworks\av\services\audiopolicy\enginedefault\src\Engine.cpp
if(mAvailableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) {
       device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
}
if (mAvailableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) {
       device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
       device2 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE);
       device2 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER);
}

2、Android 11

目标frameworks\av\services\audiopolicy\enginedefault\src\Engine.cpp
 if ((remoteSubmix = availableOutputDevices.getDevice(
                    AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0"),
                    AUDIO_FORMAT_DEFAULT)) != nullptr) {
                devices2.add(remoteSubmix);
            }

修改为​:

if ((remoteSubmix = availableOutputDevices.getDevice(
                    AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0"),
                    AUDIO_FORMAT_DEFAULT)) != nullptr) {
   devices2 = availableOutputDevices.getDevicesFromTypes({
                    AUDIO_DEVICE_OUT_REMOTE_SUBMIX, AUDIO_DEVICE_OUT_WIRED_HEADPHONE, AUDIO_DEVICE_OUT_SPEAKER});
            }

要实现安卓录制系统声音,正常情况下是获取不到的,这个方案是修改源码的方式来实现。

后面可以介绍下系统是怎么实现的,可以把源码贴出来,大家一起学习。

图片

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK