之前在做直播的時候需要使用到內錄功能,比如經常看到遊戲主播在直播玩遊戲,遊戲的聲音不是通過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.flagsinclude $(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屏幕錄制漏洞
?