我正在尝试使用WiFi通过接入点将MP3从Android手机流式传输到另一部Android手机。问题是OpenSL ES似乎只支持PCM音频缓冲区作为源(除非使用URI)。而不是在发送之前解码“主”侧的潜在巨大文件我宁愿让“客户端”将MP3解码为PCM。请记住,这必须作为文件流发生,而不是简单地发送整个文件然后解码。有没有办法使用OpenSL ES来实现这一目标? AudioTrack?这似乎是一个相当普遍的要求。
答案 0 :(得分:5)
你是正确的,opensl似乎没有带有mp3源的简单缓冲队列。话虽这么说,您应该能够使用SLDataLocator_URI。现在,我知道您启动时没有完整的文件(因为您正在流式传输),但有一种解决方法。如果您创建一个空文件,并将其用作opensl URI播放器的源,则一切都应该有效。当您获取数据(mp3文件的位)时,只需将此数据添加到您创建的空文件中。在完成向其附加数据之前,您可以让OpenSL从此文件开始播放。
使用以下命令创建一个空文件:
RandomAccessFile raf = new RandomAccessFile(new File(mFileUri), "rw");
raf.setLength(audioFileSize);
将您的音频源创建为:
SLDataLocator_URI loc_uri = {SL_DATALOCATOR_URI, (SLchar *) fileLoc};
SLDataFormat_MIME format_mime = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
SLDataSource audioSrc = {&loc_uri, &format_mime};
使用以下内容加载缓冲区:
for (int i = 0; i < BUFFER_COUNT; i++) {
// get byte[] data from stream
raf.seek(i*Constants.BUFFER_SIZE);
raf.write(data);
}
随时使用OpenSL开始播放音频,然后继续加载缓冲区。只要你在流媒体流程中保持领先,你应该没事。
答案 1 :(得分:1)
你必须使用opensl吗? MediaCodec(在Android 4.2中可用)可以将mp3解码为PCM块,可以传递给AudioTrack。
答案 2 :(得分:0)
您是否尝试过使用OpenSL ES的Victor Lazzarini音频编程示例 http://audioprograming.wordpress.com/2012/10/29/lock-free-audio-io-with-opensl-es-on-android/
它提供了基于http://mobilepearls.com/labs/native-android-api/ndk/docs/opensles/
的良好流式传输实现