是否可以录制应用程序产生的内部声音?
我的应用程序允许您创建和播放音乐序列。
soundPool.play(soundIds[i], 1f, 1f, 1, 0, Constants.TIME_RATE);
我希望能够记录序列并导出为 mp3。
我查看了音频捕获,但 setAudioSource (int audio_source) 似乎只接受 MIC 录音。
谢谢
是否可以录制应用程序产生的内部声音?
我的应用程序允许您创建和播放音乐序列。
soundPool.play(soundIds[i], 1f, 1f, 1, 0, Constants.TIME_RATE);
我希望能够记录序列并导出为 mp3。
我查看了音频捕获,但 setAudioSource (int audio_source) 似乎只接受 MIC 录音。
谢谢
不,没有用于获取音频输出的 API,即使对于您自己的应用程序也是如此(实际上这并不完全正确,因为您可以通过Visualizer
API 获得它,但它的质量太低了,我怀疑它对你)。
如果你想要那种功能,你必须自己实现它。那是; 当您开始播放声音时,将它们混合并将结果也写入文件。如果声音被压缩,您还必须自己解码。
请注意,Android 中不包含 MP3 编码器,因此如果您要导出的格式是这种格式,则无论如何您都必须提供自己的 MP3 编码器。
正如迈克尔所说,您需要为此实现自己的编码器和解码器。Visualizer 提供的数据质量非常低,因为我们可以使用它来显示与均衡器同步的自定义视图和效果。
这是您可以找到 MP3 文件的简单解码器和编码器的链接。他们在哪里从 MP3 文件中读取数据并将其放入新的 MP3 文件中。他们也创建了对其他扩展的支持。
根据http://xzpeter.org/?p=254,如果您修改 Android 源,则可以捕获内部声音播放。特别是类的写功能AudioFlinger::MixerThread
。(注意这篇文章有点老了——对最新的Android版本AudioFlinger
进行了重新整理,现在可以在threadLoop_write()
函数中找到写代码)。
引用原始解决方案作者:
AudioFlinger 在 dir 下实现
frameworks/base/services/audioflinger/
。我们要做的是找到混音器的输出。在文件AudioFlinger.cpp中,我们可以看到AudioFlinger::MixerThread::threadLoop()
,它是混音器的工作线程,这个MixerThread继承自AudioFlinger::BaseThread
. 然后,只需用你最好的编辑器(vim、emacs、gedit 等)搜索关键字mOutput->write
,我们会在函数下找到类似这样的内容threadLoop()
:mLastWriteTime = systemTime(); mInWrite = true; mBytesWritten += mixBufferSize; int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize); if (bytesWritten < 0) mBytesWritten -= mixBufferSize; mNumWrites++; mInWrite = false;
这就是混音器输出缓冲区转移到我认为的硬件相关代码的关键点,并且音频剪辑位于
mMixbuffer
,大小为mixBufferSize
。在这个缓冲区中,有 44100Hz 采样率、2 个通道和 16 位 little endian 作为其参数的 PCM 原始音频数据。如果将此缓冲区写入文件,例如/data/wav.raw
,则可以使用 adb pull 将数据文件检索到主机并使用 aplay 播放:
aplay -t raw -c 2 -f S16_LE -r 44100 wav.raw
无论如何,为了将其转换为 mp3,您必须使用 Michael 所述的外部编码器。