2016-05-31 18 views
8

Tôi đã tạo một ứng dụng radio hoạt động hoàn toàn tốt. Tôi có thể phát luồng radio và tìm nạp siêu dữ liệu. Dịch vụ phát trực tuyến là từ shoutcast.Làm cách nào để tách siêu dữ liệu và bản nhạc khỏi luồng truyền phát mà không yêu cầu siêu dữ liệu riêng và phát trực tuyến

Vấn đề duy nhất là, tôi thêm url làm nguồn dữ liệu vào trình phát đa phương tiện và sau đó tìm nạp tiêu đề và nghệ sĩ cứ 5 giây một lần.

Có cách nào, tôi chỉ có thể thực hiện một yêu cầu http và sau đó chia âm thanh và siêu dữ liệu rồi gửi cho trình phát đa phương tiện không?

Mã để tìm nạp Siêu dữ liệu.

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

Và đi qua các url với nguồn dữ liệu của 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(); 
} 
+0

Có, bạn chỉ cần bỏ qua siêu dữ liệu từ luồng. Xem câu trả lời này để biết thêm chi tiết: http://stackoverflow.com/questions/4911062/pulling-track-info-from-an-audio-stream-using-php/4914538#4914538 Nếu bạn muốn có câu trả lời cụ thể cho Java trên Android , bạn nên hiển thị mã của mình về cách bạn đang nhận dữ liệu luồng hiện tại. – Brad

+0

@Brad Xem câu trả lời cập nhật của tôi. Cảm ơn. – Searock

Trả lời

1

Nhiệm vụ bạn cố gắng để đạt được không phải là cái gì đó rất dễ dàng để làm. (Tho nó không phải là không thể.) Siêu dữ liệu của dòng chỉ được "tải xuống" ở đầu luồng, do đó, thay đổi nó sau đó sẽ không có hiệu lực đọc các metainformations "lưu trữ" từ dòng. Để đọc các thuộc tính mới, bạn phải khởi động lại dòng, điều này sẽ lấy các tiêu đề mới vv (Nhưng nó có thể gây ra một vết rách ở suối nên nó là không thực sự khuyến khích.)

Trong công nghệ âm thanh người ta thường sử dụng watermarking. Nó là một quá trình mà bạn làm giàu âm thanh của bạn với một số loại dữ liệu theo cách không phá hủy (chất lượng). (Usage on youtube.) Rất khó để thực hiện, có một số cách để ẩn thông tin của bạn trong luồng. Tôi khuyên bạn nên đọc this để đạt được mục tiêu bạn muốn tiếp cận.

Vì phần cứng của bạn là điện thoại di động và không phải tất cả các thiết bị Android đều đủ mạnh, bạn nên cân nhắc một số yêu cầu http mới. Việc xử lý âm thanh không phải là một điều rẻ nói về CPU, bộ nhớ vv Có một số tùy chọn khác để xem xét nếu bạn làm như vậy. Năm thứ hai bỏ phiếu không phải là cách tốt nhất để có được thông tin, bởi vì bạn có thể hiển thị thông tin sai lệch cho người dùng và thông tin sai lệch là tồi tệ hơn không có gì. Tôi khuyên bạn nên đẩy phía máy chủ dựa trên mqtt. Here là một ví dụ khá hay về cách sử dụng. Một giải pháp dựa trên phương pháp này được kích hoạt bởi việc bỏ phiếu đang sử dụng ít lưu lượng truy cập hơn và chính xác hơn.

Các vấn đề liên quan