5

我正在使用这样的Android MediaExtractor:

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);

inputBuffer 由配置为 AAC 编码器的 MediaCodec 提供。目标是将wave文件转换为aac。当然,上面的代码是缩写的,但我将错误跟踪到最后一行。

它也仅在使用带有 wav 文件的 MediaExtractor 时发生。例如,我改用 .m4a,一切正常。

MediaExtractor 的文档说:

MediaExtractor 有助于从数据源中提取解复用的(通常是编码的)媒体数据。

“通常编码”不排除未编码的 PCM 音频....对吗?任何人之前都尝试过或知道另一种稳定的(!)方法:

  • 从 wav 中提取音频样本(不包括 44 字节或 46 字节标头)?
  • 在Android上将wav文件转换为aac?

更新

这是日志猫:

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)

我使用的是 API 16,所以 MediaMuxer 不是一个选项(在 API 18 中添加)。

4

2 回答 2

6

我无法弄清楚 MediaExtractor 似乎无法从简单的 wav 文件中读取数据的“如果”或“为什么不”,所以我选择了另一种方法。由于 WAV 文件真的不需要解码,我现在使用一个简单的 FileInputStream 并跳过 44 字节的标头。

我在此要点中发布了一个工作示例: https ://gist.github.com/muetzenflo/3e83975aba6abe63413abd98bb33c401

经过近一周的研究、尝试和错误,这段代码似乎很少见。我记录了几乎每一行代码,希望能帮助其他在 Android 上遇到 MediaCodec 类问题的人。

于 2016-06-26T10:08:47.987 回答
0

在调用之前decoder.configure(format, ...),我建议调用format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 65536);,它会使解码器使用更大的缓冲区。这应该可以解决问题。如果没有,请尝试增加缓冲区大小。

于 2019-12-27T02:49:54.313 回答