Android AudioRecord가 다른 스트림을 MIC 오디오 소스로 강제 전송
업데이트 3: 저는 다른 개발자와 파트너 관계를 맺고 있으며, 큰 금액으로 이 작업을 수행할 수 있는 사람을 찾은 것 같습니다.그들은 우리에게 테스트 apk를 보냈고 그것은 효과가 있는 것 같습니다.소스를 구입하겠습니다.나는 우리가 사기를 당하지 않기를 바란다.알게 되면 업데이트하겠습니다.
업데이트 2: 아직 진행 중입니다.좀 더 고통스러워진 날들이 지나고 나니, 지금은 별 볼일 없는 것 같지만, AudioFlinger(링크 참조)를 네이티브 측에서 사용하여 AudioFlinger를 호출하고 있습니다:setParameters
Audio Flinger를 호출하기 위해 간단한 JNI를 쓰는 방법을 찾고 있습니다: setParameters with audio_io_handle_t ioHandle, cst String8 & key ValuePairs
keyValuePairs는 알 수 있지만 audio_io_handle_t에 대한 단서는 알 수 없습니다.
업데이트: 다른 앱이 CAF에서 QCOM 오디오를 사용하고 있을 수 있습니다.링크의 audio_extn_utils_send_audio_calibration을 참조하십시오.
및 링크의 voice_get_incall_rec_snd_device는 동일하다.
저는 C/+에 대한 지식이 없습니다.이 메서드를 네이티브 측에서 호출할 수 있는지 어떻게 알 수 있습니까?다른 앱도 가능하니까 방법이 있을 거예요.
적어도 하루에 5~6시간씩 40일 넘게 이 문제로 고생하고 있어요.SO가 허락하는지는 모르겠지만 정답을 위해 기부를 하게 되어 기쁩니다.
VOICE_CALL 오디오 소스를 사용하는 통화 녹음 앱이 있습니다.ASOP에서는 실장/의무가 없지만, 대부분의 제조원은 VOICE_CALL을 실장하고 있어 VOICE_CALL 오디오소스를 사용하는 어플리케이션은 많은 디바이스에서 정상적으로 동작합니다.안드로이드6까지입니다.
구글은 안드로이드6에서 이 동작을 바꿨다.VOICE_CALL 오디오 소스를 열려면 안드로이드가 필요합니다.허가.CAPTURE_AUDIO_OUTPUT. 시스템응용 프로그램에만 부여됩니다.
이것에 의해, 기본적으로 콜 녹음이 정지됩니다.그렇지 않으면 정지합니다.이 제한에서 벗어날 수 있는 방법을 찾은 3명을 제외한 저와 200명 이상의 다른 통화 녹음 앱에도 해당됩니다.
Android 6를 탑재한 여러 폰에서 이 앱을 사용해 본 결과, 녹음이 가능한 특징을 알 수 있었습니다.
모두 Android Audio Record 클래스와 오픈 MIC 오디오 소스를 사용합니다.저도 그렇지만, 제 앱에서는, 상대방이 아닌 MIC로부터만 오디오를 들을 수 있습니다.내가 알아낸 것은 그들이 녹음을 시작한 직후 또는 시작하기 전에 일종의 시스템 호출을 발행하고 있다는 것이다.
VOICE_CALL이 MIC를 사용하여 녹음하는 경우에도 VOICE_CALL을 정상적으로 녹음하는 어플리케이션 중 하나에서 다음 로그를 확인하십시오.MIC에 VOICE_CALL 오디오 소스를 믹스/루팅/스트림/머지하는 방법이 앱인 것 같습니다.
- D/audio_hw_primary: in_set_parameters: enter: kvpairs=input_source=1;routing=-2147483644
- D/PermissionCache: checking android.permission.MODIFY_AUDIO_SETTINGS for uid=10286 => granted (432 us)
- D/audio_hw_primary: in_set_parameters: enter: kvpairs=input_source=4;routing=-2147483584;format=1
- D/audio_hw_primary: select_devices: out_snd_device(0: ) in_snd_device(283: voice-dmic-ef)
- D/hardware_info: hw_info_append_hw_type : device_name = voice-dmic-ef
- D/voice: voice_get_incall_rec_snd_device: in_snd_device(283: voice-dmic-ef) incall_record_device(283: voice-dmic-ef)
첫 번째 줄에서 볼 수 있듯이 MIC 오디오소스 input_source=1;mic=-2147483644로 시작합니다.
그리고 두 번째 줄에서 뭔가를 하고 안드로이드를 부여받습니다.허가.MODIFY_AUDIO_SETTINGS는 일반 권한으로 앱도 가지고 있습니다.이것이 가장 중요한 부분인 것 같고, 3개 모두 JNI를 사용하여 VOICE_CALL 오디오소스의 MIC로의 스트리밍/머지를 트리거하고 스탠드아트의 AudioRecorder API를 사용하여 녹음을 실행하는 것 같습니다.
다음 줄에는 오디오하드웨어가 MIC(1) 오디오소스를 오픈했는데도 VOICE_CALL(input_source=4)을 믹스하기 시작하고 있는 것을 알 수 있습니다.
난 그들이 사용했다고 추측했다.
AudioManager.setParameters("key=value")
여러 가지 변형을 시도했습니다.
AudioManager.setParameters("input_source=4;routing=-2147483584;format=1")
아무 행운도 없이
그리고 Android, NDK, 오디오 라우팅이 헤드셋을 통해 오디오를 강제하고 있는 것을 발견했습니다.그것은 현재의 AudioRecord 세션에 어떻게 mix/route/stream/merge VOICE_CALL이 포함되어 있는지 생각했기 때문에 (C 지식이 없기 때문에) 아래 코드로 같은 것을 실현하기 위해 리플레이션을 사용하려고 했지만 실패했을지도 모릅니다.
private static void setForceUseOn() {
/*
setForceUse(int usage, int config);
----usage for setForceUse, must match AudioSystem::force_use
public static final int FOR_COMMUNICATION = 0;
public static final int FOR_MEDIA = 1;
public static final int FOR_RECORD = 2;
public static final int FOR_DOCK = 3;
public static final int FOR_SYSTEM = 4;
public static final int FOR_HDMI_SYSTEM_AUDIO = 5;
----device categories config for setForceUse, must match AudioSystem::forced_config
public static final int FORCE_NONE = 0;
public static final int FORCE_SPEAKER = 1;
public static final int FORCE_HEADPHONES = 2;
public static final int FORCE_BT_SCO = 3;
public static final int FORCE_BT_A2DP = 4;
public static final int FORCE_WIRED_ACCESSORY = 5;
public static final int FORCE_BT_CAR_DOCK = 6;
public static final int FORCE_BT_DESK_DOCK = 7;
public static final int FORCE_ANALOG_DOCK = 8;
public static final int FORCE_DIGITAL_DOCK = 9;
public static final int FORCE_NO_BT_A2DP = 10;
public static final int FORCE_SYSTEM_ENFORCED = 11;
public static final int FORCE_HDMI_SYSTEM_AUDIO_ENFORCED = 12;
public static final int FORCE_DEFAULT = FORCE_NONE;
*/
try {
Class audioSystemClass = Class.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
setForceUse.invoke(null, 0, 0); // setForceUse(FOR_RECORD, FORCE_NONE)
} catch (Exception e) {
e.printStackTrace();
}
}
분명히 녹음을 가능하게 하는 뭔가 놓치고 있는 것이 있습니다.
심지어 이 정보를 얻기 위해 돈을 주겠다고 제안했지만, 모두 거절했어요.좋아, 내가 말한 대로야.한 번 출판할 거야/찾으면!
그들이 뭘 하고 있을지 짐작 가는 거라도 있나요?
나와 내 파트너는 우리가 찾고 있던 것을 살 수 있었다.올바른 경로로 진행 중이었고, 네이티브 측에서 keyValuePairs를 설정했습니다.
유감스럽게도 소스를 작성한 회사의 라이센스 제한으로 인해 소스를 공개할 수 없습니다.
이치노나는 몇 가지 작은 프로젝트와 관련된 일을 했다.AudioRecord
API. 다음 정보가 도움이 되었으면 합니다.
예를 들어 다음과 같이 셋업합니다.AudioRecord
16kHz의 16비트 모노로 녹음할 수 있습니다.이를 수행하려면 다음과 같은 몇 가지 도우미 메서드를 사용하여 클래스를 만듭니다.
public class AudioRecordTool {
private final int minBufferSize;
private boolean doRecord = false;
private final AudioRecord audioRecord;
public AudioRecordTool() {
minBufferSize = AudioTrack.getMinBufferSize(16000,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
audioRecord = new AudioRecord(
MediaRecorder.AudioSource.VOICE_COMMUNICATION,
16000,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
minBufferSize * 2);
}
public void writeAudioToStream(OutputStream audioStream) {
doRecord = true; //Will dictate if we are recording.
audioRecord.startRecording();
byte[] buffer = new byte[minBufferSize * 2];
while (doRecord) {
int bytesWritten = audioRecord.read(buffer, 0, buffer.length);
try {
audioStream.write(buffer, 0, bytesWritten);
} catch (IOException e) {
//You can log if you like, or simply ignore it
stopRecording();
}
}
//cleanup
audioRecord.stop();
audioRecord.release();
}
public void stopRecording() {
doRecord = false;
}
}
Mashimallow 사용자는 거의 모든 멋진 사용자가 아니더라도 특정 권한에 접근할 수 있는 유일한 사용자이기 때문에 동일한 권한을 유지할 필요가 있다고 생각합니다.
수업을 실시해 보고, 어떻게 되었는지 알려 주세요.또한 더 많은 연구가 필요할 경우를 대비해서 참고 자료를 남깁니다.
행운을 빌어요.
언급URL : https://stackoverflow.com/questions/37080374/android-audiorecord-forcing-another-stream-to-mic-audio-source
'source' 카테고리의 다른 글
스프링 부트:최대 연결 수 등의 JDBC 풀 속성을 설정하려면 어떻게 해야 합니까? (0) | 2022.09.11 |
---|---|
Java에서 익명 내부 클래스를 정적으로 만들 수 있습니까? (0) | 2022.09.11 |
Javascript에서 괄호 사이에 문자열을 가져오는 정규 표현식 (0) | 2022.09.11 |
DIV의 치수가 변경된 것을 감지하는 방법 (0) | 2022.09.11 |
Vue.js를 사용한 Facebook 로그인 컴포넌트 및 증폭 (0) | 2022.09.11 |