5

是否可以录制应用程序产生的内部声音?

我的应用程序允许您创建和播放音乐序列。

soundPool.play(soundIds[i], 1f, 1f, 1, 0,  Constants.TIME_RATE);

我希望能够记录序列并导出为 mp3。

我查看了音频捕获,但 setAudioSource (int audio_source) 似乎只接受 MIC 录音。

谢谢

4

3 回答 3

3

不,没有用于获取音频输出的 API,即使对于您自己的应用程序也是如此(实际上这并不完全正确,因为您可以通过VisualizerAPI 获得它,但它的质量太低了,我怀疑它对你)。

如果你想要那种功能,你必须自己实现它。那是; 当您开始播放声音时,将它们混合并将结果也写入文件。如果声音被压缩,您还必须自己解码。

请注意,Android 中不包含 MP3 编码器,因此如果您要导出的格式是这种格式,则无论如何您都必须提供自己的 MP3 编码器。

于 2013-08-08T09:10:27.900 回答
1

正如迈克尔所说,您需要为此实现自己的编码器和解码器。Visualizer 提供的数据质量非常低,因为我们可以使用它来显示与均衡器同步的自定义视图和效果。

这是您可以找到 MP3 文件的简单解码器和编码器的链接。他们在哪里从 MP3 文件中读取数据并将其放入新的 MP3 文件中。他们也创建了对其他扩展的支持。

http://code.google.com/p/ringdroid/source/browse/#svn%2Fbranches%2Fgingerbread%2Fsrc%2Fcom%2Fringdroid

于 2013-08-09T10:10:10.333 回答
1

根据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 所述的外部编码器。

于 2014-05-29T00:50:09.470 回答