2013-05-10 81 views
3

我正在爲Android設備開發一個應用程序的Radio應用程序,該應用程序應該從Shoutcast服務器獲取流媒體。從Shoutcast流中獲取元數據Android

聲音工作正常,但我想要檢索元數據,所以我可能能夠顯示當前播放的歌曲的標題,藝術家以及專輯圖片。

我使用了MediaMetaDataRetriever,但它似乎沒有工作!

這是我使用的代碼:

public class MainActivity extends FragmentActivity { 

private ImageView bannerView; 
private int[] pub = {R.drawable.banner, R.drawable.pubnautic, R.drawable.pubquad}; 
private int i = 0; 

private ImageView play; 
private ImageView pause; 
private TextView title; 
private MediaPlayer mediaPlayer; 
private MediaMetadataRetriever retriever; 
private String out; 
private String url = "http://streamplus8.leonex.de:14910"; 
//adele-someonelikeyou 
//Accordossie 
//http://support.k-designed.net/test-z/music/adele-someonelikeyou.mp3 
private ImageView albumpic; 
private byte[] image; 
private boolean paused = false; 

private ImageView exit; 

private ImageView wish; 

private ImageView reservation; 

private ImageView contact; 

private ImageView facebook; 

private ImageView twitter; 

@Override 
protected void onCreate(final Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    bannerView = (ImageView) findViewById(R.id.banner); 

    play = (ImageView) findViewById(R.id.play); 
    pause = (ImageView) findViewById(R.id.pause); 
    exit = (ImageView) findViewById(R.id.exit); 
    albumpic = (ImageView) findViewById(R.id.artist); 
    title = (TextView) findViewById(R.id.title); 
    retriever = new MediaMetadataRetriever(); 
    mediaPlayer = new MediaPlayer(); 

    wish = (ImageView) findViewById(R.id.wish); 

    reservation = (ImageView) findViewById(R.id.shop); 

    contact = (ImageView) findViewById(R.id.contact); 

    facebook = (ImageView) findViewById(R.id.facebook); 

    twitter = (ImageView) findViewById(R.id.twitter); 

    this.setVolumeControlStream(AudioManager.STREAM_MUSIC); 

    try { 
     mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
     mediaPlayer.setDataSource(url); 
     retriever.setDataSource(url); 
     mediaPlayer.prepareAsync(); 
    } catch (Exception e) { 
     Toast.makeText(getApplicationContext(), "Please check your connection!", Toast.LENGTH_LONG).show(); 
     e.printStackTrace(); 
    } 

    play.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      try { 
       if(paused == true) { 
        mediaPlayer.start(); 
       } else { 
        mediaPlayer.setOnPreparedListener(new OnPreparedListener() { 

         @Override 
         public void onPrepared(MediaPlayer mp) { 
          mediaPlayer.start(); 

         } 
        }); 
       } 
       paused = false; 
       image = retriever.getEmbeddedPicture(); 
       if(image != null) { 
        albumpic.setImageBitmap(BitmapFactory.decodeByteArray(image, 0, image.length)); 
       } 
       out = "Title: " + retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE) + " \nArtist: " + retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST); 
       title.setText(out); 
       play.setVisibility(ImageView.GONE); 
       pause.setVisibility(ImageView.VISIBLE); 

      } catch(Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 

    pause.setClickable(true); 

    pause.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      pause.setVisibility(ImageView.GONE); 
      play.setVisibility(ImageView.VISIBLE); 
      mediaPlayer.pause(); 
      paused = true; 
     } 
    }); 

    wish.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      Intent wishIntent = new Intent(MainActivity.this, Wish.class); 
      startActivity(wishIntent); 

     } 
    }); 

    reservation.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      Intent reservIntent = new Intent(MainActivity.this, Reservation.class); 
      startActivity(reservIntent); 
     } 
    }); 

    contact.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      Intent contactIntent = new Intent(MainActivity.this, Contact.class); 
      startActivity(contactIntent); 
     } 
    }); 

    facebook.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 

      Intent facebookIntent = new Intent(MainActivity.this, FacebookActivity.class); 
      facebookIntent.putExtra("name", "Just now listening to: " + retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE) + " by " + retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)); 
      facebookIntent.putExtra("caption", "On AgadirAdventure Radio"); 
      facebookIntent.putExtra("description", "A Radio App for Android Devices by K-Designed"); 
      facebookIntent.putExtra("link", "http://www.agadiradventure.com/"); 
      facebookIntent.putExtra("picture", "http://agadiradventure.com/images/logo/logo1.png"); 
      startActivity(facebookIntent); 

     } 
    }); 

    twitter.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      initShareIntent("twi"); 

     } 
    }); 

    exit.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      mediaPlayer.stop(); 
      onBackPressed(); 
     } 
    }); 

    bannerView.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      Uri uri = Uri.parse("http://www.agadiradventure.com"); 
      Intent launchBrowser = new Intent(Intent.ACTION_VIEW, uri); 
      startActivity(launchBrowser); 
     } 
    }); 

    Runnable r = new Runnable() { 

     @Override 
     public void run() { 
      bannerView.setImageResource(pub[i]); 
      i++; 
      if(i >= pub.length) { 
       i = 0; 
      } 
      bannerView.postDelayed(this, 3000); 
     } 
    }; 
    bannerView.postDelayed(r, 3000); 

} 

private void initShareIntent(String type) { 
    boolean found = false; 
    Intent share = new Intent(android.content.Intent.ACTION_SEND); 
    share.setType("text/plain"); 

    // gets the list of intents that can be loaded. 
    List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(share, 0); 
    if (!resInfo.isEmpty()){ 
     for (ResolveInfo info : resInfo) { 
      if (info.activityInfo.packageName.toLowerCase().contains(type) || 
        info.activityInfo.name.toLowerCase().contains(type)) { 
       String sharedText = "Just now listening to: " + retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE) + " by " + retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST) + "\nOn AgadirAdventure\nwww.agadiradventure.com"; 
       share.putExtra(Intent.EXTRA_TEXT, sharedText); 
       share.setPackage(info.activityInfo.packageName); 
       found = true; 
       break; 
      } 
     } 
     if (!found) 
      return; 

     startActivity(Intent.createChooser(share, "Select")); 
    } 
} 

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_BACK) { 
     moveTaskToBack(true); 
     return true; 
    } 
    return super.onKeyDown(keyCode, event); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.activity_main, menu); 
    return true; 
} 

} 

感謝您的幫助!

回答

4

由於@ William-Seemann答案中的類不再可用。這是一個替代方案(其好處是不需要任何庫):

將以下class添加到您的項目中。您現在可以如圖所示使用它here。您也可以使用這樣的:

String title = ""; 
    IcyStreamMeta meta = new IcyStreamMeta(); 
    try { 
     meta.setStreamUrl(new URL(YOURURL)); 
     title = meta.getStreamTitle(); 
    } catch (MalformedURLException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

充分肯定dazza5000創建項目。

+0

但是,我怎麼能聽到「跟蹤更改」事件來更新標籤,例如? – johnnyshrewd 2018-01-30 14:02:32

+0

@johnnyshrewd這個類沒有監聽器。通過每隔x秒運行一次上述代碼片段,直到在標題中檢測到更改,您可以調用您的偵聽器,可能會創建您自己的「事件偵聽器」。 – Mdlc 2018-02-01 09:59:40

6

我創建了我自己的類來檢索基於修改後的版本streamscraper的元數據。使用​​3210 jar(streamscraper),this jar(jsoup)和this類來檢索元數據。該界面類似於MediaMetadataRetriever:

ShoutCastMetadataRetriever smr = new ShoutCastMetadataRetriever(); 
smr.setDataSource(<some url>); 
String artist = smr.extractMetadata(ShoutCastMetadataRetriever.METADATA_KEY_ARTIST); 
String title = smr.extractMetadata(ShoutCastMetadataRetriever.METADATA_KEY_TITLE); 

我不相信Shoutcast一樣的元數據支持專輯封面,所以你將無法檢索。

+0

SHOUTcast v1甚至不支持藝術家或標題。這只是一個通常被格式化爲「藝術家 - 標題」的字符串。 SHOUTcast v2確實提供專輯封面,如果它可以從編碼器中獲得的話。 – Brad 2013-05-11 14:28:53

+0

http://wiki.winamp.com/wiki/SHOUTcast_XML_Metadata_Specification – Brad 2013-05-11 17:45:03

+1

現在你是自相矛盾的。你的帖子說專輯封面不在那裏。您從我發佈的鏈接中引用的報價表示數據正在流中。 – Brad 2013-05-13 03:40:48