Как получить метаданные потокового онлайн-радио

Я разрабатываю приложение в Android 2.2. Мне нужно получить метаданные потокового онлайн-радио, например, shoutcast.

Я использую класс IcyStreamMeta:

public class IcyStreamMeta<Message> { protected URL streamUrl; private Map<String, String> metadata; private boolean isError; public IcyStreamMeta(URL streamUrl) { setStreamUrl(streamUrl); isError = false; } /** * Get artist using stream's title * * @return String * @throws IOException */ public String getArtist() throws IOException { Map<String, String> data = getMetadata(); if (!data.containsKey("StreamTitle")) return ""; String streamTitle = data.get("StreamTitle"); String title = streamTitle.substring(0, streamTitle.indexOf("-")); return title.trim(); } /** * Get title using stream's title * * @return String * @throws IOException */ public String getTitle() throws IOException { Map<String, String> data = getMetadata(); if (!data.containsKey("StreamTitle")) return ""; String streamTitle = data.get("StreamTitle"); String artist = streamTitle.substring(streamTitle.indexOf("-")+1); return artist.trim(); } public Map<String, String> getMetadata() throws IOException { if (metadata == null) { refreshMeta(); } return metadata; } public void refreshMeta() throws IOException { retreiveMetadata(); } private void retreiveMetadata() throws IOException { URLConnection con = streamUrl.openConnection(); con.setRequestProperty("Icy-MetaData", "1"); con.setRequestProperty("Connection", "close"); con.setRequestProperty("Accept", null); con.connect(); int metaDataOffset = 0; Map<String, List<String>> headers = con.getHeaderFields(); InputStream stream = con.getInputStream(); if (headers.containsKey("icy-metaint")) { // Headers are sent via HTTP metaDataOffset = Integer.parseInt(headers.get("icy-metaint").get(0)); } 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 boolean isError() { return isError; } public URL getStreamUrl() { return streamUrl; } public void setStreamUrl(URL streamUrl) { this.metadata = null; this.streamUrl = streamUrl; this.isError = false; } 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; } } 

И моя основная деятельность я использую функцию:

 public void getMeta(){ timer = new Timer(); timer.schedule(new TimerTask() { public void run() { URL url; //Message msg = handler.obtainMessage(); try { Log.d("Metadatos","Dentro del try para obtener los metadatos"); url = new URL("http://relay5.slayradio.org:8000"); IcyStreamMeta icy = new IcyStreamMeta(url); //Log.d("Metadatos","El metadata de la url es "+icy.getMetadata().toString()); Log.d("Metadatos","El titulo de la cancion es "+icy.getTitle()); //msg.obj = icy.getTitle(); Log.d("Metadatos","El nombre del artista es "+icy.getArtist()); //handler.sendMessage(msg); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }, 0, 10000); } 

Когда я запускаю приложение, не получайте метаданные. Я видел всю почту, но я не могу найти решение. Мне нужна ваша помощь.

С уважением, Хуан.

 import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class IcyStreamMeta { protected URL streamUrl; private Map<String, String> metadata; private boolean isError; private Map<String, String> data; public IcyStreamMeta() { isError = false; } /** * Get artist using stream's title * * @return String * @throws IOException */ public String getArtist() throws IOException { data = getMetadata(); if (!data.containsKey("StreamTitle")) return ""; String streamTitle = data.get("StreamTitle"); String title = streamTitle.substring(0, streamTitle.indexOf("-")); return title.trim(); } /** * Get streamTitle * * @return String * @throws IOException */ public String getStreamTitle() throws IOException { data = getMetadata(); if (!data.containsKey("StreamTitle")) return ""; return data.get("StreamTitle"); } /** * Get title using stream's title * * @return String * @throws IOException */ public String getTitle() throws IOException { data = getMetadata(); if (!data.containsKey("StreamTitle")) return ""; String streamTitle = data.get("StreamTitle"); String artist = streamTitle.substring(streamTitle.indexOf("-")+1); return artist.trim(); } public Map<String, String> getMetadata() throws IOException { if (metadata == null) { refreshMeta(); } return metadata; } synchronized public void refreshMeta() throws IOException { retreiveMetadata(); } synchronized private void retreiveMetadata() throws IOException { URLConnection con = streamUrl.openConnection(); con.setRequestProperty("Icy-MetaData", "1"); con.setRequestProperty("Connection", "close"); con.setRequestProperty("Accept", null); con.connect(); int metaDataOffset = 0; Map<String, List<String>> headers = con.getHeaderFields(); InputStream stream = con.getInputStream(); if (headers.containsKey("icy-metaint")) { // Headers are sent via HTTP metaDataOffset = Integer.parseInt(headers.get("icy-metaint").get(0)); } 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 boolean isError() { return isError; } public URL getStreamUrl() { return streamUrl; } public void setStreamUrl(URL streamUrl) { this.metadata = null; this.streamUrl = streamUrl; this.isError = false; } 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; }} 

Во втором классе создайте AsyncTask

 protected class MetadataTask2 extends AsyncTask<URL, Void, IcyStreamMeta> { @Override protected IcyStreamMeta doInBackground(URL... urls) { try { streamMeta.refreshMeta(); Log.e("Retrieving MetaData","Refreshed Metadata"); } catch (IOException e) { Log.e(MetadataTask2.class.toString(), e.getMessage()); } return streamMeta; } @Override protected void onPostExecute(IcyStreamMeta result) { try { title_artist=streamMeta.getStreamTitle(); Log.e("Retrieved title_artist", title_artist); if(title_artist.length()>0) { updateMetadata(); } metaFlag=true; } catch (IOException e) { Log.e(MetadataTask2.class.toString(), e.getMessage()); } } } 

И вызовите AsyncTask, как показано ниже.

  streamMeta = new IcyStreamMeta(); streamMeta.setStreamUrl(new URL(ConstantData.currentStationData.getUrl())); metadataTask2=new MetadataTask2(); metadataTask2.execute(new URL(ConstantData.currentStationData.getUrl())); 

В методе «Выполнить» в программе «Таймер» напишите код

  { streamMeta.refreshMeta(); String title_artist=streamMeta.getStreamTitle(); } 

Над кодом работает отлично для меня. Сообщите мне, есть ли «Сомнение» и «Извините за форматирование».