8

我正在尝试通过接入点使用 WiFi 将 MP3 从 Android 手机流式传输到另一部 Android 手机。问题是 OpenSL ES 似乎只支持 PCM 音频缓冲区作为源(除非使用 URI)。与其在发送之前在“主”端解码一个潜在的巨大文件,我更愿意让“客户端”将 MP3 解码为 PCM。请记住,这必须在文件流传输时发生,而不是简单地发送整个文件然后解码。有没有办法使用 OpenSL ES 来完成这个?音轨?这似乎是一个相当普遍的要求。

4

3 回答 3

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 开始播放音频,然后继续加载缓冲区。只要您在流式传输过程中保持领先,就应该没问题。

于 2013-02-07T23:09:21.803 回答
1

你必须使用opensl。MediaCodec(在 Android 4.2 中可用)可以将 mp3 解码为可传递给 AudioTrack 的 PCM 块。

于 2014-02-14T10:00:23.533 回答
0

您是否尝试过这个 Victor Lazzarini 的 OpenSL ES 音频编程示例 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/的良好流实现

于 2013-02-06T13:36:11.350 回答