According to http://xzpeter.org/?p=254 it's possible to capture internal sound playback if you modify Android sources. Particularly the write function of the AudioFlinger::MixerThread
class. (Note that the article is a little bit old - on the latest Android versions AudioFlinger
was reorganized and write code can be now found in the threadLoop_write()
function).
Quoting original solution author:
AudioFlinger is implemented under dir
frameworks/base/services/audioflinger/
. What we are going to
do is to find the mixer output. In the file AudioFlinger.cpp, we can
see AudioFlinger::MixerThread::threadLoop()
, which is the working
thread of the mixer, and this MixerThread is inherited from
AudioFlinger::BaseThread
. Then, just search the keyword mOutput->write
with your best editor (vim, emacs, gedit, whatever), and we will find
something like this under the threadLoop()
function:
mLastWriteTime = systemTime();
mInWrite = true;
mBytesWritten += mixBufferSize;
int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
mNumWrites++;
mInWrite = false;
That is the very point that mixer output buffer is transferred to hardware related codes I think, and the audio clip is in mMixbuffer
, with size mixBufferSize
. In this buffer, there are PCM raw audio data with 44100Hz sampling rate, 2 channels and 16 bits little endian as its param.
If you write this buffer out to a file, like /data/wav.raw
, you can just use adb pull to retrieve the data file to your host machine and play it with aplay:
aplay -t raw -c 2 -f S16_LE -r 44100 wav.raw
Anyway, in order to convert it to mp3 you will have to use external encoder as stated by Michael.