Es gibt ein Problem auf dem Exoplayer repository geöffnet. Grundsätzlich werden die Metadaten über Header übertragen, nicht im Stream selbst.
Ich hatte einen Erfolg mit der audiostream-metadata-retriever, obwohl ich einige Track-Synchronisationsprobleme hatte wegen der Stream-Caching und Metadaten ankommen, bevor der eigentliche Song zu spielen beginnt.
Edit:
RxJava Umsetzung:
private long icyMetaInt = 1000;
public void showStreamData() {
Log.d(TAG, "Show stream metadata");
streamService.getStreamData()
.subscribeOn(Schedulers.io())
.repeatWhen(delays -> delays.concatMap(metaIntDelay -> {
Log.d(TAG, "icyMetaDelay = " + icyMetaInt + "ms ");
return Observable.timer(icyMetaInt, TimeUnit.MILLISECONDS);
}))
.subscribe(new Observer<Response<ResponseBody>>() {
@Override
public void onSubscribe(Disposable disposable) {
Log.d(TAG, "OnSubscribe");
}
@Override
public void onNext(Response<ResponseBody> response) {
Log.d(TAG, "onNext - " + response);
if (response.isSuccessful()) {
InputStream stream = response.body().byteStream();
if (stream != null) {
icyMetaInt = Integer.parseInt(response.headers().get("icy-metaint"));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
long skipped = stream.skip(icyMetaInt);
while (skipped != icyMetaInt) {
skipped += stream.skip(icyMetaInt - skipped);
}
int symbolLength = stream.read();
int metaDataLength = symbolLength * 16;
if (metaDataLength > 0) {
for (int i = 0; i < metaDataLength; ++i) {
int metaDataSymbol = stream.read();
if (metaDataSymbol > 0) {
baos.write(metaDataSymbol);
}
}
String result = baos.toString()
.replace("StreamTitle=", "")
.replaceAll("'", "")
.replaceAll(";", "");
baos.reset();
Log.d(TAG, result);
runOnUiThread(() -> textView.setText(result));
Log.d(TAG, response.headers().get("ice-audio-info"));
Log.d(TAG, response.headers().get("icy-description"));
Log.d(TAG, response.headers().get("icy-genre"));
Log.d(TAG, response.headers().get("icy-name"));
Log.d(TAG, response.headers().get("icy-url"));
}
} catch (IOException e) {
onError(e);
Log.e(TAG, "Failed to obtain metadata");
} finally {
try {
baos.close();
stream.close();
} catch (IOException e) {
onError(e);
}
}
}
}
}
@Override
public void onError(Throwable throwable) {
Log.d(TAG, "onError");
throwable.printStackTrace();
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
}
});
}
Retrofit-Schnittstelle:
import io.reactivex.Observable;
import okhttp3.ResponseBody;
import retrofit2.Response;
import retrofit2.http.GET;
import retrofit2.http.Headers;
import retrofit2.http.Streaming;
public interface StreamService {
@GET("stream")
@Headers("Icy-MetaData:1")
@Streaming
Observable<Response<ResponseBody>> getStreamData();
}
Dank für diese Antwort, Goran. Ihr Link für den Issue Tracker ist gebrochen, denke ich. Aber Sie haben mich auf den richtigen Weg gebracht. Ich habe diese Bibliothek als eine Inspiration verwendet, um die Metadaten mit Retrofit und Rx etwas sauberer imho holen. – tim
Sie haben Recht, ich habe den Link korrigiert. Ich stimme zu, dass die Bibliothek ein bisschen übertrieben ist und das einfache Antworten reichen würde. Werde es selbst ausprobieren wenn ich Zeit habe. Bitte akzeptiere die Antwort. – GoranNSW