【问题标题】:Media Player play from radio stream and get data from stream媒体播放器从广播流中播放并从流中获取数据
【发布时间】:2021-01-18 23:23:20
【问题描述】:

我正在通过在线流媒体播放媒体播放器:

mMediaPlayer = new MediaPlayer();
try {
    mMediaPlayer.setDataSource("http://online-radioroks.tavrmedia.ua/RadioROKS");
    mMediaPlayer.prepareAsync();

    mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

        public void onPrepared(MediaPlayer mp) {
            start();
        }
    });

    notifyCallbackListeners(PlayerCallbackEvent.PLAYER_SONG_CHANGE);
}
catch (IllegalArgumentException e) {
    e.printStackTrace();
}
catch (IOException e) {
    e.printStackTrace();
} catch (IllegalStateException ex){
    ex.printStackTrace();
}

它工作正常,但我可以从流中获取数据,比如现在正在播放的歌曲和电台名称吗?

【问题讨论】:

    标签: android media-player


    【解决方案1】:

    从流中获取数据,例如现在正在播放的歌曲和电台名称?

    对于该流 url 应该提供该数据,而不是相应地您可以读取数据。

    对于您在问题中提到的 URL,它在标头中提供数据,请求 Icy-MetaData 和标头 icy-metaint。有关这些类型的 url 和标头数据的更多详细信息,请查看this 链接。

    现在如何解析该标头数据?

    你可以试试下面贴出的代码

    public class ParsingHeaderData {
        public class TrackData {
            public String artist = "";
            public String title = "";
        }
    
        protected URL streamUrl;
        private Map<String, String> metadata;
        private TrackData trackData;
    
        public ParsingHeaderData() {
    
        }
    
        public TrackData getTrackDetails(URL streamUrl) {
            trackData = new TrackData();
            setStreamUrl(streamUrl);
            String strTitle = "";
            String strArtist = "";
            try {
                metadata = executeToFetchData();
                if (metadata != null) {
                    String streamHeading = "";
                    Map<String, String> data = metadata;
                    if (data != null && data.containsKey("StreamTitle")) {
                        strArtist = data.get("StreamTitle");
                        streamHeading = strArtist;
                    }
                    if (!TextUtils.isEmpty(strArtist) && strArtist.contains("-")) {
                        strArtist = strArtist.substring(0, strArtist.indexOf("-"));
                        trackData.artist = strArtist.trim();
                    }
                    if (!TextUtils.isEmpty(streamHeading)) {
                        if (streamHeading.contains("-")) {
                            strTitle = streamHeading.substring(streamHeading
                                    .indexOf("-") + 1);
                            trackData.title = strTitle.trim();
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return trackData;
        }
    
        private URLConnection con;
        private InputStream stream;
        private List<String> headerList;
    
        private Map<String, String> executeToFetchData() throws IOException {
            try {
                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();
                stream = con.getInputStream();
    
                if (headers.containsKey("icy-metaint")) {
                    headerList = headers.get("icy-metaint");
                    if (headerList != null) {
                        if (headerList.size() > 0) {
                            metaDataOffset = Integer.parseInt(headers.get(
                                    "icy-metaint").get(0));
                        } else
                            return null;
                    } else
                        return null;
    
                } else {
                    return null;
    
                }
    
                // In case no data was sent
                if (metaDataOffset == 0) {
                    return null;
                }
    
                // Read metadata
                int b;
                int count = 0;
                int metaDataLength = 4080; // 4080 is the max length
                boolean inData = false;
                StringBuilder metaData = new StringBuilder();
                while ((b = stream.read()) != -1) {
                    count++;
                    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;
                    }
    
                }
                metadata = ParsingHeaderData.parsingMetadata(metaData.toString());
                stream.close();
            } catch (Exception e) {
                if (e != null && e.equals(null))
                    Log.e("Error", e.getMessage());
            } finally {
                if (stream != null)
                    stream.close();
            }
            return metadata;
    
        }
    
        public URL getStreamUrl() {
            return streamUrl;
        }
    
        public void setStreamUrl(URL streamUrl) {
            this.metadata = null;
            this.streamUrl = streamUrl;
        }
    
        public static Map<String, String> parsingMetadata(String metaString) {
            @SuppressWarnings({ "rawtypes", "unchecked" })
            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 class Test extends AsyncTask<Void, Void, Void> {
    
            /*
             * (non-Javadoc)
             * 
             * @see android.os.AsyncTask#doInBackground(Params[])
             */
            @Override
            protected Void doInBackground(Void... params) {
                try {
                    URL url = new URL(
                            "http://online-radioroks.tavrmedia.ua/RadioROKS");
                    ParsingHeaderData streaming = new ParsingHeaderData();
                    TrackData trackData = streaming.getTrackDetails(url);
                    Log.e("Song Artist Name ", trackData.artist);
                Log.e("Song Artist Title", trackData.title);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }
    
        }
    

    调用执行任务

    new Test().execute();
    

    【讨论】:

    • 谢谢伙计,这太好了。很遗憾我不能为你的回复投票
    • @user1140237 它不能在 android 4.4.2 中工作,但在棉花糖中工作,有什么解决方案吗?
    【解决方案2】:

    这个问题太老了,这个答案可能对某人有所帮助,在我的情况下,我试图从 radio.co 的 API 获取曲目信息。

    所以首先我必须添加这个类以允许我执行 HTTP 请求,将其命名为 HttpHandler:

    public class HttpHandler {
    
    private static final String TAG = HttpHandler.class.getSimpleName();
    
    public HttpHandler() {
    }
    
    public String makeServiceCall(String reqUrl) {
        String response = null;
        try {
            URL url = new URL(reqUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            // read the response
            InputStream in = new BufferedInputStream(conn.getInputStream());
            response = convertStreamToString(in);
        } catch (MalformedURLException e) {
            Log.e(TAG, "MalformedURLException: " + e.getMessage());
        } catch (ProtocolException e) {
            Log.e(TAG, "ProtocolException: " + e.getMessage());
        } catch (IOException e) {
            Log.e(TAG, "IOException: " + e.getMessage());
        } catch (Exception e) {
            Log.e(TAG, "Exception: " + e.getMessage());
        }
        return response;
    }
    
    private String convertStreamToString(InputStream is) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
    
        String line;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line).append('\n');
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        return sb.toString();
    }
    }
    

    要获取曲目信息,我已将此方法添加到我的主要活动中:

    private class getTrackInfo extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //Toast.makeText(MainActivity.this,"Getting Song Info",Toast.LENGTH_LONG).show();
    
        }
    
        @Override
        protected Void doInBackground(Void... arg0) {
            HttpHandler sh = new HttpHandler();
            // Making a request to url and getting response
            String url = "Your URL HERE";
            String jsonStr = sh.makeServiceCall(url);
    
            //Log.e(TAG, "Response from url: " + jsonStr);
            if (jsonStr != null) {
                try {
                    JSONObject jsonObj = new JSONObject(jsonStr);
    
                    // Getting JSON Array node
                    JSONObject current_track = jsonObj.getJSONObject("current_track");
                    strArtist = current_track.getString("title");
                    artwork_url = current_track.getString("artwork_url");
    
                    String streamHeading = strArtist;
    
                    if (!TextUtils.isEmpty(strArtist) && strArtist.contains("-")) {
                        strArtist = strArtist.substring(0, strArtist.indexOf("-"));
                        trackData.artist = strArtist.trim();
                    }
                    if (!TextUtils.isEmpty(streamHeading)) {
                        if (streamHeading.contains("-")) {
                            strTitle = streamHeading.substring(streamHeading
                                    .indexOf("-") + 1);
                            trackData.title = strTitle.trim().replace("-","");
                        }
                    }
                    if (!TextUtils.isEmpty(artwork_url)) {
                        trackData.artwork_url = artwork_url;
                    }
                } catch (final JSONException e) {
                    Log.e(TAG, "Json parsing error: " + e.getMessage());
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(),
                                    "Json parsing error: " + e.getMessage(),
                                    Toast.LENGTH_LONG).show();
                        }
                    });
    
                }
    
            } else {
                Log.e(TAG, "Couldn't get json from server.");
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(),
                                "Couldn't get json from server. Check LogCat for possible errors!",
                                Toast.LENGTH_LONG).show();
                    }
                });
            }
    
            return null;
        }
    
        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            //Log.e(TAG, "Artist: " + trackData.artist + "\ntitle : " + trackData.title + "\nartwork_url :" + trackData.artwork_url);
    
            //to update my user interface with the new info
            songTitle.setText(trackData.title);
            albumTitle.setText(trackData.artist);
            new getAlbumImageTask(albumImage).execute(trackData.artwork_url);
        }
    }
    

    调用这个方法:

    new getTrackInfo().execute();
    

    要加载艺术品图像,请添加此方法:

    private class getAlbumImageTask extends AsyncTask<String, Void, Bitmap> {
        ImageView bmImage;
    
        public getAlbumImageTask(ImageView bmImage) {
            this.bmImage = bmImage;
        }
    
        protected Bitmap doInBackground(String... urls) {
            String urldisplay = urls[0];
            Bitmap mIcon11 = null;
            try {
                InputStream in = new java.net.URL(urldisplay).openStream();
                mIcon11 = BitmapFactory.decodeStream(in);
            } catch (Exception e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return mIcon11;
        }
    
        protected void onPostExecute(Bitmap result) {
            bmImage.setImageBitmap(result);
        }
    }
    

    调用方法加载艺术品图像:

    new getAlbumImageTask(albumImage).execute(trackData.artwork_url);
    

    此代码中存在与我的情况相关的变量,然后忽略并根据您的情况调整代码 我希望这对某人有所帮助

    【讨论】:

      【解决方案3】:

      提供的解决方案(ParsingHeaderData)很有吸引力,但是我遇到了西里尔编码的问题。

      这是我如何修补 executeToFetchData 方法以使其正常工作:

          private Map<String, String> executeToFetchData() throws IOException {
              try {
                  con = streamUrl.openConnection();
                  con.setRequestProperty("Accept-Charset", "UTF-8");
                  con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
                  con.setRequestProperty("Icy-MetaData", "1");
                  con.connect();
      
                  int metaDataOffset = 0;
                  Map<String, List<String>> headers = con.getHeaderFields();
                  stream = con.getInputStream();
      
                  if (headers.containsKey("icy-metaint")) {
                      headerList = headers.get("icy-metaint");
                      if (headerList != null) {
                          if (headerList.size() > 0) {
                              metaDataOffset = Integer.parseInt(headers.get(
                                      "icy-metaint").get(0));
                          } else
                              return null;
                      } else
                          return null;
      
                  } else {
                      return null;
      
                  }
      
                  // In case no data was sent
                  if (metaDataOffset == 0) {
                      return null;
                  }
      
                  // Read metadata
                  int b;
                  int count = 0;
                  int metaDataLength = 4080; // 4080 is the max length
      
                  ByteArrayOutputStream buffer = new ByteArrayOutputStream();
      
                  while ((b = stream.read()) != -1) {
                      count++;
                      if (count == metaDataOffset + 1) {
                          metaDataLength = b * 16;
                      }
                      if (count > metaDataOffset + 1
                              && count < (metaDataOffset + metaDataLength)) {
                          if (b != 0) {
                              buffer.write(b);
                          }
                      }
                      if (count > (metaDataOffset + metaDataLength)) {
                          break;
                      }
                  }
                  metadata = ParsingHeaderData.parsingMetadata(
                          new String(buffer.toByteArray(), 0, buffer.size(), "UTF-8"));
                  buffer.close();
                  stream.close();
              } catch (Exception e) {
                  if (e != null && e.equals(null))
                      Log.e("Error", e.getMessage());
              } finally {
                  if (stream != null)
                      stream.close();
              }
              return metadata;
          }

      【讨论】:

        猜你喜欢
        • 2012-03-19
        • 1970-01-01
        • 1970-01-01
        • 2017-10-18
        • 2012-11-10
        • 2011-07-02
        • 2017-10-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多