更新3:我和另一个开发者合作,我们似乎找到了一个可以花一大笔钱做这件事的人。他们给我们发了一个测试apk,看起来很有效。我们将继续购买源代码。我希望我们不会被骗。一旦我发现了,我会更新的。
更新2:仍在努力。经过更痛苦的日子,我现在认为没有什么花哨的事情发生,但他们只是在原生端使用音频Flinger(见链接)来调用音频Flinger::set参数
我现在正在寻找如何编写一个简单的JNI来使用audio_io_handle_tioHandle、constString8调用AudioFlinger::setParameters
我知道关键价值对是什么,但不是关于audio_io_handle_t
更新:我现在相信其他应用程序可能会在CAF中使用QCOM音频。请参阅链接中的audio_extn_utils_send_audio_calibration
并且voice_get_incall_rec_snd_device位于相同的链接
我没有C/知识。我如何才能知道是否可以从本机端调用这些方法?既然其他应用程序可以,那一定有办法。
我已经为此奋斗了40多天,每天至少5-6个小时。我不确定SO是否允许这样做,但我也很乐意为正确答案捐款。
我有一个使用VOICE_CALL音频源的通话录音应用。尽管ASOP没有实施/强制要求它,但大多数制造商已经实施了VOICE_CALL,并且使用VOICE_CALL音频源的应用程序在许多设备上都能正常工作。直到Android6。
谷歌在Android6中改变了这种行为。现在,打开VOICE_CALL音频源需要android.permission.CAPTURE_AUDIO_OUTPUT,这仅授予系统应用程序。
这基本上停止了通话录音,或者它应该有。好吧,除了3个已经找到绕过此限制的方法之外,我和其他200个通话录音应用程序也是如此。
我一直在许多不同的Android 6手机上尝试这些应用程序,并发现了它们管理记录方式的某些特征。
他们都使用Android AudioRecord类并打开MIC音频源。我也是;但在我的应用程序中,我只从MIC获得音频,而不是另一方。我发现的是,他们在开始录制之后或之前发出了某种系统html" target="_blank">调用。
看看下面的日志,它是一个成功录制VOICE_CALL的应用程序,即使它使用MIC来录制。看起来应用程序是如何管理混合/路由/流/合并VOICE_CALL音频源到MIC中的。
- 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;路由=-2147483644开始。
然后,在第二行,它做了一些事情,并获得了Android . permission . modify _ AUDIO _ SETTINGS,这是正常的权限,我的应用程序也有它。这似乎是最重要的部分,看起来所有3个都在使用JNI做他们曾经做过的事情来触发语音呼叫音频源到麦克风的流/合并,并用standart AudioRecorder API记录
在下一行中,您可以看到音频硬件开始混合VOICE_CALL(input_source=4),即使它们已经打开了MIC(1)音频源。
我猜他们用了
AudioManager.setParameters("key=value")
并尝试了许多变化,例如
AudioManager.setParameters("input_source=4;routing=-2147483584;format=1")
没有任何运气。
然后,我发现了Android,NDK,音频路由,迫使音频通过耳机,并认为他们可能是一些如何混合/路由/流/合并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();
}
}
很明显,我缺少了一些东西,使得录音成为可能。
我甚至提出付钱去获取这些信息,但都被拒绝了。我说得很公平。我会发布它一次/如果我找到它!
你知道他们可能在做什么吗?
你的发现很有趣。我做过一些涉及< code>AudioRecord API的小项目。希望以下内容会有所帮助:
假设您想要设置一个< code>AudioRecord实例,以便您可以在16位单声道中以16kHz录制。您可以通过创建一个包含一些helper方法的类来实现这一点,如下所示:
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;
}
}
我猜您需要保留相同的权限,因为Marshmallow用户是唯一授予我们访问某些权限(如果不是几乎所有很酷的权限)的用户。
尝试实现该类,并让我们知道它是如何进行的,我也留下了一些额外的参考,以防您需要更多的研究。
祝你好运。
AudioRecord API
AudioCaputre API
媒体记录器API
我和我的搭档能够买到我们想要的东西。我们走在正确的道路上,您在本机端设置了keyValuePairs。
不幸的是,由于公司的许可限制,我不能公布源代码
问题内容: 更新3: 我已经与另一位开发人员建立了合作伙伴关系,我们似乎发现有人可以为此花很多钱。他们给我们发送了一个测试apk,它似乎有效。我们将继续购买源。我希望我们不会被骗。我一发现就会更新 更新2: 仍在努力。经过更痛苦的日子之后,我现在认为没有任何幻想,但他们只是在本机端使用AudioFlinger(请参阅链接)来调用 AudioFlinger :: setParameters 我现在正
我正在使用OpenSL ES播放音频剪辑。在我的代码中,我有 在插入耳机时强制音频通过扬声器。它工作正常,但我无法控制音量。在播放剪辑时按下音量按钮会使音量搜索栏出现并移动,但音量不会改变。播放前调用或似乎没有帮助。更改我的应用程序之外的任何音量(例如在Android设置中)不会影响播放音量。当没有应用路由时,音量控制在耳机和扬声器上都可以正常工作。 我还尝试使用在另一个答案中找到的代码将音频发送
我正在尝试使用FFMPEG合并2个mp4文件。其中一个文件同时具有视频和音频(),而另一个只有音频()。这些文件的名称以以下方式列在名为的文本文件中: 然后执行下面的ffmpeg命令来合并它们。 但是,生成的连接文件只包含。也就是说,如果
问题内容: 我正在尝试建立一个程序来录制一部分互联网音频流,并将其保存到文件(最好是mp3或wav)。我到处都看过,找不到任何合适的方法来做到这一点。我找到了两个似乎可以工作的不同库(NativeBass和Xuggle),但我都不支持64位Windows。 有谁知道使用Java保存一部分互联网音频流的任何简单方法?(如果重要,则为“音频/ mpeg”流)。 编辑:好的,我发现了一种可行的方法。但是
问题内容: 我已经看到了一些与此相关的主题,但是没有答案,所以我想在受污染的youtube相关页面的坟墓中添加另一个主题。 我有一个100MB的mp4视频,需要由浏览器完全下载, 但是,完全下载完之后不会触发任何事件,Chrome似乎会停止缓冲更多的视频,直到当前视频时间快要达到缓冲的末尾为止,然后它会请求更多。 如何让浏览器完全下载视频并将其缓冲100%? 谢谢 问题答案: 遗憾的是,Chrom
我需要录制音频(我相信使用函数)并将其从nodejs服务器传输到连接的客户端浏览器。我环顾了一些例子,没有什么太明确的内容,并且采用了不同的方法。 我不能使用webrtc。它必须使用服务器向客户端发送流。但是,我可以使用(我相信这是webrtc的一部分)来录制音频并将其发送到nodejs服务器)。 是否有任何资源或示例显示这样的工作方式?