如何使Android錄音實現內錄功能
阿新 • • 發佈:2019-01-24
背景
之前在做直播的時候需要使用到內錄功能,比如經常看到遊戲主播在直播玩遊戲,遊戲的聲音不是通過MIC錄製的,而是內錄完成的。故在此記錄一下。
相信大家都很熟悉Android如果錄音的了:
int frequency = 44100;
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
int minBufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding);
int audioSource = MediaRecorder.AudioSource.MIC;
AudioRecord audioRecord = new AudioRecord(audioSource, frequency,
channelConfiguration, audioEncoding, minBufferSize);
audioRecord.startRecording();
...
AudioSource輸入源介紹
專案 | 介紹 | 許可權 |
---|---|---|
DEFAULT | 預設。在原始碼 system/media/audio/include/system/audio.h配置預設項 | 無 |
MIC | 麥克風 | 無 |
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 | 攝像頭的麥克風 | 無 |
VOICE_RECOGNITION | 語音識別 | 無 |
VOICE_COMMUNICATION | 網路電話 | 無 |
REMOTE_SUBMIX | 傳輸到遠端的音訊混合流。預設情況下如何用該項錄音,本地揚聲器或者耳機的聲音將會被截走 | android.permission.CAPTURE_AUDIO_OUTPUT,系統許可權不允許第三方app使用 |
好了,現在我們知道了REMOTE_SUBMIX可以實現內錄功能了。有兩點比較麻煩:
-
需要系統許可權
-
會截走揚聲器和耳機的聲音,也就是說再錄音時本地無法播放聲音
系統許可權問題
這個對我來說比較好辦,因為我是直接在android裝置板子上開發,可以直接使用系統簽名編譯。首先在AndroidManifest.xml新增android:sharedUserId="android.uid.system"
其次,
第一種方法:
adb shell 執行:
signapk.jar platform.x509.pem platform.pk8 app-unsigned.apk signed.apk
adb push signed.apk /system/app
第二種方法:
編寫Android.mk : 設定簽名為platform
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := YourApp
LOCAL_CERTIFICATE := platform
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
include $(BUILD_PACKAGE)
include $(call all-makefiles-under,$(LOCAL_PATH))
截走揚聲器和耳機的聲音問題
修改framework下av/services/audiopolicy/AudioPolicyManager.cpp
audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
bool fromCache)
getDeviceForStrategy方法下找到
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);
}
意思是聲音輸出的裝置添加了耳機和揚聲器,這裡可根據實際情況設定。
至此,將最開始的錄音程式碼
int audioSource = MediaRecorder.AudioSource.MIC;
改成
int audioSource = MediaRecorder.AudioSource.REMOTE_SUBMIX;
就可以實現內錄功能了。
<br/>
ps:
在不修改原始碼的情況下,第三方app目前暫不知如何實現內錄。
延伸閱讀
5.0以後請求Android錄屏預設會彈出確認框,但在系統app下請求就不會彈出了(具體可以去看原始碼)。這也是為了谷歌為了安全考慮。
不過5.0的時候這個彈框卻是一個大漏洞,被國內360發現了,給你們連結^_^
Android 5.0螢幕錄製漏洞