是否可以录制应用程序生成的内部声音?
我的应用程序允许您创建和播放音乐序列。
soundPool.play(soundIds[i], 1f, 1f, 1, 0, Constants.TIME_RATE);
我希望能够录制序列并导出到mp3。
我查看了 Audio Capture 但是setAudioSource(int audio_source)似乎只接受了MIC录音。
由于
答案 0 :(得分:3)
不,没有用于获取音频输出的API,即使对于您自己的应用程序也是如此(实际上这并非完全正确,因为您可以通过Visualizer
API获取它,但它的质量会低于我怀疑它对你有用。)
如果你想要这种功能,你必须自己实现它。那是;当您开始播放声音时,将它们混合并将结果写入文件。如果声音被压缩,你还必须自己解码它们。
请注意,Android中不包含MP3编码器,因此如果您要导出格式,则无论如何都必须提供自己的MP3编码器。
答案 1 :(得分:1)
正如迈克尔所说,你需要为此实现自己的编码器和解码器。 Visualizer提供的数据质量非常低,因为我们可以使用它来显示与均衡器同步的自定义视图和效果。
这是 link ,您可以在其中找到MP3文件的简单解码器和编码器。他们从MP3文件中读取数据并将其放入新的MP3文件中。他们也为其他一些扩展创建了支持。
答案 2 :(得分:0)
根据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
。然后,只需搜索关键字mOutput->write
用你最好的编辑器(vim,emacs,gedit等),我们会发现 在threadLoop()
函数mLastWriteTime = systemTime(); mInWrite = true; mBytesWritten += mixBufferSize; int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize); if (bytesWritten < 0) mBytesWritten -= mixBufferSize; mNumWrites++; mInWrite = false;
这就是混音器输出缓冲区转移到我认为的硬件相关代码的重点,音频片段在
mMixbuffer
,大小为mixBufferSize
。在这个缓冲区中,有PCM原始音频数据,采样率为44100Hz,2个通道和16位小端作为其参数。 如果将此缓冲区写入文件,例如/data/wav.raw
,则可以使用adb pull将数据文件检索到主机并使用aplay播放:
aplay -t raw -c 2 -f S16_LE -r 44100 wav.raw
无论如何,为了将其转换为mp3,您必须使用迈克尔所述的外部编码器。