I have made a radio app which works perfectly fine. I'm able to play the radio stream and fetch the metadata too. The streaming service is from shoutcast.
The only problem is that, I'm adding the URL as the data source to the media player and then fetching the title and artist every 5 seconds.
Is there any way, I can just make one HTTP request and then split the audio and the metadata and then send it to the media player?
Code for fetching Metadata.
private void retreiveMetadata() throws IOException {
int metaDataOffset = 0;
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.addHeader("Icy-MetaData", "1")
.addHeader("Connection", "close")
.addHeader("Accept", "")
.url(streamUrl)
.build();
request.headers("");
Response response = client.newCall(request).execute();
InputStream stream = response.body().byteStream();
//Map<String, List<String>> headers = response..getHeaderFields();
if (!response.headers("icy-metaint").equals("")) {
// Headers are sent via HTTP
String icyMetaInt = response.headers("icy-metaint").toString();
icyMetaInt = icyMetaInt.replace("[", "");
icyMetaInt = icyMetaInt.replace("]", "");
metaDataOffset = Integer.parseInt(icyMetaInt);
} else {
// Headers are sent within a stream
StringBuilder strHeaders = new StringBuilder();
char c;
while ((c = (char)stream.read()) != -1) {
strHeaders.append(c);
if (strHeaders.length() > 5 && (strHeaders.substring((strHeaders.length() - 4), strHeaders.length()).equals("\r\n\r\n"))) {
// end of headers
break;
}
}
// Match headers to get metadata offset within a stream
Pattern p = Pattern.compile("\\r\\n(icy-metaint):\\s*(.*)\\r\\n");
Matcher m = p.matcher(strHeaders.toString());
if (m.find()) {
metaDataOffset = Integer.parseInt(m.group(2));
}
}
// In case no data was sent
if (metaDataOffset == 0) {
isError = true;
return;
}
// Read metadata
int b;
int count = 0;
int metaDataLength = 4080; // 4080 is the max length
boolean inData = false;
StringBuilder metaData = new StringBuilder();
// Stream position should be either at the beginning or right after headers
while ((b = stream.read()) != -1) {
count++;
// Length of the metadata
if (count == metaDataOffset + 1) {
metaDataLength = b * 16;
}
if (count > metaDataOffset + 1 && count < (metaDataOffset + metaDataLength)) {
inData = true;
} else {
inData = false;
}
if (inData) {
if (b != 0) {
metaData.append((char)b);
}
}
if (count > (metaDataOffset + metaDataLength)) {
break;
}
}
// Set the data
metadata = IcyStreamMeta.parseMetadata(metaData.toString());
// Close
stream.close();
}
public static Map<String, String> parseMetadata(String metaString) {
Map<String, String> metadata = new HashMap();
String[] metaParts = metaString.split(";");
Pattern p = Pattern.compile("^([a-zA-Z]+)=\\'([^\\']*)\\'$");
Matcher m;
for (int i = 0; i < metaParts.length; i++) {
m = p.matcher(metaParts[i]);
if (m.find()) {
metadata.put((String)m.group(1), (String)m.group(2));
}
}
return metadata;
}
And passing the url to the datasource of the media player
String url = "http://68.68.109.106:8356/";
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mp.setDataSource(url);
mp.prepare();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(context, e.toString(), Toast.LENGTH_SHORT).show();
} catch (SecurityException e) {
// TODO Auto-generated catch block
Log.e(TAG, "SecurityException");
Toast.makeText(context, e.toString(), Toast.LENGTH_SHORT).show();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
Log.e(TAG, "IllegalStateException");
Toast.makeText(context, e.toString(), Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e(TAG, "IOException");
Toast.makeText(context, e.toString(), Toast.LENGTH_SHORT).show();
}