5
votes

I am using the Android MediaExtractor like this:

MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource("path/to/my/wav/file.wav");
extractor.selectTrack(0);

ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferIndex);
int sampleSize =  extractor.readSampleData(inputBuffer, 0);

The inputBuffer is provided by MediaCodec which is configured as AAC Encoder. The goal is to convert the wave file to aac. The above code is abbreviated, of course, but I tracked the error down to the last line.

It also only occurs when using the MediaExtractor with a wav file. For example, I used a .m4a instead and everything worked fine.

The documentation of MediaExtractor says:

MediaExtractor facilitates extraction of demuxed, typically encoded, media data from a data source.

"typically encdoded" does not exclude un-encodec PCM audio....right? Anyone tried this before or knows another stable(!) way to:

  • extract the audio samples from a wav (excluding 44byte or 46byte header)?
  • convert an wav file to aac on Android?

UPDATE

Here is the logcat:

W/System.err: java.lang.IllegalArgumentException
W/System.err:     at android.media.MediaExtractor.readSampleData(Native Method)
W/System.err:     at com.myproject.android.audiosandbox.convert.MediaEncoder2.encodeLollipopStyle(MediaEncoder2.java:247)
W/System.err:     at com.myproject.android.audiosandbox.convert.MediaEncoder2.encodeSong(MediaEncoder2.java:119)
W/System.err:     at com.myproject.android.audiosandbox.convert.MediaEncoder2.encode(MediaEncoder2.java:70)
W/System.err:     at com.myproject.android.audiosandbox.fragments.AudioConvertFragment$1.onClick(AudioConvertFragment.java:40)
W/System.err:     at android.view.View.performClick(View.java:4763)
W/System.err:     at android.view.View$PerformClick.run(View.java:19821)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:739)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err:     at android.os.Looper.loop(Looper.java:135)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5272)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at java.lang.reflect.Method.invoke(Method.java:372)
W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)

I am using API 16, so MediaMuxer is not an option (was added in API 18).

2
Can you please share the exact logcat logs? IllegalArgumentException could come due to multiple scenarios. If you have logcat, it would be easier to isolate and suggest a solution. On a related note, have you confirmed that the file exists here path/to/my/wav/file.wav?. Also, could you please specify which version of Android you are working on?Ganesh
From your logs com.android.audiosandbox.convert.MediaEncoder2.encode, it looks like a custom encoder is being used. To isolate this problem, can you please remove this encoder from media_codecs.xml and try to use the default software encoder i.e. MediaCodec as in this example: androidxref.com/4.1.2/xref/frameworks/av/cmds/stagefright/…Ganesh
Well, the "custom encoder" is the class I am working on. I got it work now, but not with MediaExtractor. I will post a gist as an answer. If you have more insight on using the MediaExtractor with wav files, I'd gladly hear it. Thanks!muetzenflo
The only reason why there could be an error as reported by you is due to insufficient size of the buffer required to read the content. The native implementation of MediaExtractor is implemented by NuMediaExtractor. In the method quoted in the log, the only erroneous exit could be due to -ENOMEM as shown here: androidxref.com/4.1.1/xref/frameworks/av/media/libstagefright/…. Can you please retry with MediaExtractor with a big buffer and check if the same works fine? If this works, I will post it as answerGanesh
I already read in another post that the buffer size might be the reason for this Exception. But I have no influence on the buffer size, since I need to use the input- and outputBuffers provided by MediaCodec.muetzenflo

2 Answers

6
votes

I could not figure out "if" or "why not" the MediaExtractor seems to be unable to read data from a simple wav file, so I chose a different approach. Since WAV file don't really need to be decoded, I now use a simple FileInputStream and skip the 44-byte header.

I got a working sample published in this gist: https://gist.github.com/muetzenflo/3e83975aba6abe63413abd98bb33c401

After almost one week of research, try and error, this piece of code seems to be rare. I documented almost every line and hope that I can help others who struggle with the MediaCodec class on Android.

0
votes

Before calling decoder.configure(format, ...), I suggest to call format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 65536);, it will make decoder use bigger buffers. This should fix the issue. If not, try to increase buffer size.