emulienfou Posté(e) 11 avril 2011 Share Posté(e) 11 avril 2011 Bonjour, actuellement en cour de développement d'application pour une webradio, je partage avec toute la communauté FrAndroid mes sources qui pourront surement servir à d'autres personnes, je l'espère, permettant de lire un flux audio depuis un serveur de type IceCast et Shoutcast(utilisé par Winamp). Fichier source PulsDroidScanner.java : Permet de gérer les TexView ainsi que l'url qui sera passée en paramètre package com.test; /** * Copyright (C) 2011 <David SANCHEZ> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Sources : http://uniqueculture.net/2010/11/stream-metadata-plain-java/ * : http://www.smackfu.com/stuff/programming/shoutcast.html * * Test : 2.1U1 WORKING ! * : 2.2 WORKING ! * : 2.3 WORKING ! * */ import java.net.MalformedURLException; import java.net.URL; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.widget.TextView; import android.widget.Toast; public class PulsDroid_Scanner extends Activity { static TextView tv1; static TextView tv2; static TextView tv3; static TextView tv4; static TextView tv5; static TextView tv6; static TextView tv7; static TextView tv8; static TextView tv9; static TextView tv10; static Toast toast; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); URL url = null; try { url = new URL ("http://stream8.pulsradio.com:6000/"); // inflate views tv1 = (TextView) this.findViewById(R.id.TextView01); tv2 = (TextView) this.findViewById(R.id.TextView02); tv3 = (TextView) this.findViewById(R.id.TextView03); tv4 = (TextView) this.findViewById(R.id.TextView04); tv5 = (TextView) this.findViewById(R.id.TextView05); tv6 = (TextView) this.findViewById(R.id.TextView06); tv7 = (TextView) this.findViewById(R.id.TextView07); tv8 = (TextView) this.findViewById(R.id.TextView08); tv9 = (TextView) this.findViewById(R.id.TextView09); tv10 = (TextView) this.findViewById(R.id.TextView10); // call asynchronous task classes new IcyAsyncMeta().execute(url); new IcyAsyncTitle().execute(url); } catch(MalformedURLException mue) { Log.e("ERR", "Bad URL: " + mue.getMessage()); } catch(Exception e) { Log.e("ERR", "Read error: " + e.getMessage()); } } } Fichier source IcyAsyncMeta.java : Permet de récupérer toutes les informations sur le flux audio(sauf le titre de la musique en cour) package com.test; import java.io.IOException; import java.net.URL; import java.net.URLConnection; import android.os.AsyncTask; import android.util.Log; public class IcyAsyncMeta extends AsyncTask<URL, Integer, Long> { private URLConnection conn; protected void onPreExecute() { Log.i("LOGGER", "onPreExecute"); } /** * Connection to stream * Using URL */ @Override protected Long doInBackground(URL... urls) { // TODO Auto-generated method stub Log.i("IcyAsyncMeta", "doInBackground"); try { conn = urls[0].openConnection(); conn.setRequestProperty ("Icy-Metadata", "1"); conn.setRequestProperty("Connection", "close"); conn.setRequestProperty("Accept", null); conn.connect(); Log.i("IcyAsyncMeta", conn.getHeaderField("icy-name")); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } publishProgress(); return null; } protected void onProgressUpdate(Integer... progress) { Log.i("IcyAsyncMeta", "onProgressUpdate"); PulsDroid_Scanner.tv1.setText(conn.getHeaderField("icy-notice1")); PulsDroid_Scanner.tv2.setText(conn.getHeaderField("icy-notice2")); PulsDroid_Scanner.tv3.setText(conn.getHeaderField("icy-name")); PulsDroid_Scanner.tv4.setText(conn.getHeaderField("icy-genre")); PulsDroid_Scanner.tv5.setText(conn.getHeaderField("icy-url")); PulsDroid_Scanner.tv6.setText(conn.getHeaderField("content-type")); PulsDroid_Scanner.tv7.setText(conn.getHeaderField("icy-pub")); PulsDroid_Scanner.tv8.setText(conn.getHeaderField("icy-metaint")); PulsDroid_Scanner.tv9.setText(conn.getHeaderField("icy-br") + "kbps"); } @Override protected void onPostExecute(Long result) { Log.i("IcyAsyncMeta", "onPostExecute"); } } Fichier source IcyAsyncTitle.java : Permet de récupérer le titre de la musique en cour uniquement package com.test; 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; import android.os.AsyncTask; import android.util.Log; public class IcyAsyncTitle extends AsyncTask<URL, Integer, Long> { private URLConnection conn; private Map<String, String> metadata; @Override protected Long doInBackground(URL... urls) { // TODO Auto-generated method stub Log.i("IcyAsyncTitle", "doInBackground"); try { conn = urls[0].openConnection(); conn.setRequestProperty ("Icy-Metadata", "1"); conn.setRequestProperty("Connection", "close"); conn.setRequestProperty("Accept", null); conn.connect(); // Step 1 publishProgress(retreiveMetadata()); // Step 2 if (metadata == null) { publishProgress(retreiveMetadata()); } // Step 3 publishProgress(Integer.getInteger(metadata.get("StreamTitle"))); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } protected void onProgressUpdate(Integer... params) { Log.i("IcyAsyncTitle", "onProgressUpdate"); if (metadata.containsKey("StreamTitle")) { PulsDroid_Scanner.tv10.setText(metadata.get("StreamTitle")); } } @Override protected void onPostExecute(Long result) { Log.i("IcyAsyncTitle", "onPostExecute"); } private Integer retreiveMetadata() throws IOException { try { int metaDataOffset = 0; Map<String, List<String>> headers = conn.getHeaderFields(); InputStream stream; stream = conn.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)); } } // 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 = this.parseMetadata(metaData.toString()); // Close stream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } protected Map<String, String> parseMetadata(String metaString) { Map<String, String> metadata = new HashMap<String, String>(); 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; } } Fichier source main.xml : <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/TextView01" android:text="@string/hello" android:layout_height="wrap_content" android:layout_width="fill_parent"></TextView> <TextView android:id="@+id/TextView02" android:text="@string/hello" android:layout_height="wrap_content" android:layout_width="fill_parent"></TextView> <TextView android:id="@+id/TextView03" android:text="@string/hello" android:layout_height="wrap_content" android:layout_width="fill_parent"></TextView> <TextView android:id="@+id/TextView04" android:text="@string/hello" android:layout_height="wrap_content" android:layout_width="fill_parent"></TextView> <TextView android:id="@+id/TextView05" android:text="@string/hello" android:layout_height="wrap_content" android:layout_width="fill_parent"></TextView> <TextView android:id="@+id/TextView06" android:text="@string/hello" android:layout_height="wrap_content" android:layout_width="fill_parent"></TextView> <TextView android:id="@+id/TextView07" android:text="@string/hello" android:layout_height="wrap_content" android:layout_width="fill_parent"></TextView> <TextView android:id="@+id/TextView08" android:text="@string/hello" android:layout_height="wrap_content" android:layout_width="fill_parent"></TextView> <TextView android:id="@+id/TextView09" android:text="@string/hello" android:layout_height="wrap_content" android:layout_width="fill_parent"></TextView> <TextView android:id="@+id/TextView10" android:text="@string/hello" android:layout_height="wrap_content" android:layout_width="fill_parent"></TextView> </LinearLayout> Je me permet aussi de vous demander de l'aide pour mettre ajour le titre de la musique dès que celle-ci se met à changer, je suppose qu'il faut utiliser un thread mais je ne voie pas trop comment faire ? cordialement Lien vers le commentaire Partager sur d’autres sites More sharing options...
Recommended Posts
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.