我有一个从 IceCast 流启动 ExoPlayer 的 AsyncTask:
OkHttpClient okHttpClient = new OkHttpClient();
UriDataSource uriDataSource = new OkHttpDataSource(okHttpClient, userAgent, null, null, CacheControl.FORCE_NETWORK);
((OkHttpDataSource) uriDataSource).setRequestProperty("Icy-MetaData", "1");
((OkHttpDataSource) uriDataSource).setPlayerCallback(mPlayerCallback);
DataSource dataSource = new DefaultUriDataSource(context, null, uriDataSource);
ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, dataSource, allocator,
BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE);
MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
MediaCodecSelector.DEFAULT, null, true, null, null,
AudioCapabilities.getCapabilities(context), AudioManager.STREAM_MUSIC);
mPlayerCallback.playerStarted();
exoPlayer.prepare(audioRenderer);
OkHttpDataSource 是使用 OkHttpClient 实现 HttpDataSource 的类。它创建 InputStream 作为请求的响应。我从 AACDecoder 库https://github.com/vbartacek/aacdecoder-android/blob/master/decoder/src/com/spoledge/aacdecoder/IcyInputStream.java中包含了这个类,并根据响应将 InputStream 替换为 IcyInputStream:
(在 OkHttpDataSource 的 open() 中)
try {
response = okHttpClient.newCall(request).execute();
responseByteStream = response.body().byteStream();
String icyMetaIntString = response.header("icy-metaint");
int icyMetaInt = -1;
if (icyMetaIntString != null) {
try {
icyMetaInt = Integer.parseInt(icyMetaIntString);
if (icyMetaInt > 0)
responseByteStream = new IcyInputStream(responseByteStream, icyMetaInt, playerCallback);
} catch (Exception e) {
Log.e(TAG, "The icy-metaint '" + icyMetaInt + "' cannot be parsed: '" + e);
}
}
} catch (IOException e) {
throw new HttpDataSourceException("Unable to connect to " + dataSpec.uri.toString(), e,
dataSpec);
}
现在 IcyInputStream 可以捕获 medatada 并调用回调对象(此处为 playerCallback)。PlayerCallback 也来自 AACDecoder 库:https ://github.com/vbartacek/aacdecoder-android/blob/b58c519a341340a251f3291895c76ff63aef5b94/decoder/src/com/spoledge/aacdecoder/PlayerCallback.java
这样您就不会制作任何重复的流并且它是单数的。如果您不想在项目中包含 AACDecoder 库,那么您可以复制所需的文件并将它们直接包含在您的项目中。