¿Cómo puedo separar los metadatos y la pista de un flujo de shoutcast sin realizar solicitudes separadas de metadatos y el streaming

He hecho una aplicación de radio que funciona perfectamente bien. Soy capaz de reproducir el flujo de radio y buscar los metadatos también. El servicio de streaming es de shoutcast.

El único problema es que, estoy agregando la url como la fuente de datos para el reproductor de medios y luego buscar el título y el artista cada 5 segundos.

¿Hay alguna manera, sólo puedo hacer una solicitud http y luego dividir el audio y los metadatos y luego enviarlo al reproductor multimedia?

Código para obtener metadatos.

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; } 

Y pasando la url a la fuente de datos del reproductor multimedia

 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(); } 

La tarea que intenta lograr no es algo que sea fácil de hacer. (Tho no es imposible.) Los metadatos de la corriente se descargan solamente "al principio de la corriente, así que cambiarla después no tendría ningún efecto que lee las metainformations" en caché "de la corriente. Para leer las nuevas propiedades tienes que reiniciar la secuencia, esto buscará los nuevos encabezados etc. (Pero podría causar una interrupción en la secuencia por lo que no es realmente recomendable.)

En tecnología de sonido es común utilizar marcas de agua . Es un proceso en el que enriquece su sonido con algún tipo de datos de la manera no destructiva (de calidad). ( Usage en youtube. ) Altogh es difícil de hacer, hay algunas maneras de ocultar su información en la corriente. Recomiendo leer esto para alcanzar la meta que desea alcanzar.

Debido a que su hardware es un teléfono móvil y no todos los dispositivos Android son lo suficientemente fuertes que debe considerar algunas nuevas solicitudes http. El procesamiento de audio no es una cosa barata hablar en términos de CPU, memoria, etc Hay algunas otras opciones a considerar si lo hace. La encuesta de cinco segundos no es la mejor manera de obtener la información, ya que podría mostrar información falsa al usuario y la información falsa es peor que nada. Recomiendo un empuje del lado del servidor basado en mqtt. Aquí hay un ejemplo bastante agradable del uso. Una solución basada en este método insted de la encuesta está usando menos tráfico y es más exacta.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.