Streaming Audio von einer URL in Android mit MediaPlayer?

Ich habe versucht, mp3 über http mit der integrierten MediaPlayer-class von Android zu streamen. Die Dokumentation würde mir nahelegen, dass dies so einfach sein sollte wie:

MediaPlayer mp = new MediaPlayer(); mp.setDataSource(URL_OF_FILE); mp.prepare(); mp.start(); 

Ich bekomme jedoch immer wieder folgendes. Ich habe auch verschiedene URLs ausprobiert. Bitte sag mir nicht, dass das Streaming bei MP3s nicht funktioniert.

 E/PlayerDriver( 31): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported W/PlayerDriver( 31): PVMFInfoErrorHandlingComplete E/MediaPlayer( 198): error (1, -4) E/MediaPlayer( 198): start called in state 0 E/MediaPlayer( 198): error (-38, 0) E/MediaPlayer( 198): Error (1,-4) E/MediaPlayer( 198): Error (-38,0) 

Jede Hilfe sehr geschätzt, danke S

einfacher Media Player mit Streaming-Beispiel. Für XML-Teile benötigen Sie eine Schaltfläche mit ID-Schaltfläche1 und zwei Bilder in Ihrem Zeichnungsordner mit Namen button_pause und button_play und vergessen Sie nicht, die Internet-Berechtigung in Ihrem Manifest hinzuzufügen.

 public class MainActivity extends Activity { private Button btn; /** * help to toggle between play and pause. */ private boolean playPause; private MediaPlayer mediaPlayer; /** * remain false till media is not completed, inside OnCompletionListener make it true. */ private boolean intialStage = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.button1); mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); btn.setOnClickListener(pausePlay); } @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; } private OnClickListener pausePlay = new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub // TODO Auto-generated method stub if (!playPause) { btn.setBackgroundResource(R.drawable.button_pause); if (intialStage) new Player() .execute("http://www.virginmegastore.me/Library/Music/CD_001214/Tracks/Track1.mp3"); else { if (!mediaPlayer.isPlaying()) mediaPlayer.start(); } playPause = true; } else { btn.setBackgroundResource(R.drawable.button_play); if (mediaPlayer.isPlaying()) mediaPlayer.pause(); playPause = false; } } }; /** * preparing mediaplayer will take sometime to buffer the content so prepare it inside the background thread and starting it on UI thread. * @author piyush * */ class Player extends AsyncTask { private ProgressDialog progress; @Override protected Boolean doInBackground(String... params) { // TODO Auto-generated method stub Boolean prepared; try { mediaPlayer.setDataSource(params[0]); mediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { // TODO Auto-generated method stub intialStage = true; playPause=false; btn.setBackgroundResource(R.drawable.button_play); mediaPlayer.stop(); mediaPlayer.reset(); } }); mediaPlayer.prepare(); prepared = true; } catch (IllegalArgumentException e) { // TODO Auto-generated catch block Log.d("IllegarArgument", e.getMessage()); prepared = false; e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block prepared = false; e.printStackTrace(); } catch (IllegalStateException e) { // TODO Auto-generated catch block prepared = false; e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block prepared = false; e.printStackTrace(); } return prepared; } @Override protected void onPostExecute(Boolean result) { // TODO Auto-generated method stub super.onPostExecute(result); if (progress.isShowing()) { progress.cancel(); } Log.d("Prepared", "//" + result); mediaPlayer.start(); intialStage = false; } public Player() { progress = new ProgressDialog(MainActivity.this); } @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); this.progress.setMessage("Buffering..."); this.progress.show(); } } @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); if (mediaPlayer != null) { mediaPlayer.reset(); mediaPlayer.release(); mediaPlayer = null; } } 

Android MediaPlayer unterstützt das native Streaming von MP3 bis 2.2 nicht. In älteren Versionen des Betriebssystems scheint 3GP nur nativ zu streamen. Sie können den Pocketjourney-Code ausprobieren, obwohl er alt ist (hier gibt es eine neue Version ), und ich hatte Probleme damit, ihn sticky zu machen – er würde stottern, wenn er den Puffer wieder auffüllt.

Die NPR News App für Android ist Open Source und verwendet einen lokalen Proxy-Server, um MP3-Streaming in Versionen des Betriebssystems vor Version 2.2 zu verarbeiten. Den entsprechenden Code finden Sie in den Zeilen 199-216 (r94) hier: http://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/ PlaybackService.java?r=7cf2352b5c3c0fbcdc18a5a8c67d836577e7e8e3

Und das ist die StreamProxy-class: http://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java?r=e4984187f45c39a54ea6c88f71197762dbe10e72

Die NPR App erhält auch manchmal den “Fehler (-38, 0)” während des Streams. Dies kann ein Threading-Problem oder ein Netzwerkänderungsproblem sein. Überprüfen Sie den Issue Tracker auf Updates .

Ich vermute, dass Sie versuchen, eine .pls direkt oder etwas ähnliches zu spielen.

probiere das aus:

1: der Code

 mediaPlayer = MediaPlayer.create(this, Uri.parse("http://vprbbc.streamguys.net:80/vprbbc24.mp3")); mediaPlayer.start(); 

2: Die .pls-Datei

Diese URL stammt von BBC nur als Beispiel. Es war eine .pls-Datei, die ich mit Linux heruntergeladen habe

 wget http://foo.bar/file.pls 

und dann öffnete ich mit vim (verwende deinen Lieblings-Editor;) und ich habe die echten URLs in dieser Datei gesehen. Leider sind nicht alle .pls Klartext wie dieser.

Ich habe gelesen, dass 1.6 Streaming MP3 über http nicht unterstützen würde, aber ich habe gerade den obigen Code mit Android 1.6 und 2.2 getestet und hatte kein Problem.

Viel Glück!

Benutzen

  mediaplayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaplayer.prepareAsync(); mediaplayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mediaplayer.start(); } }); 

Ich hatte den gleichen Fehler wie Sie und es stellte sich heraus, dass mit dem Code nichts falsch war. Das Problem war, dass der Webserver den falschen Content-Type-Header gesendet hat.

Versuchen Sie, wireshark oder etwas ähnliches, um zu sehen, welchen Inhaltstyp der Webserver sendet.

Rufen Sie mp.start nicht mit einem OnPreparedListener auf, um den Nullstatus im Protokoll zu vermeiden.

Meine Projekte ansehen:

  1. https://github.com/master255/ImmortalPlayer http / FTP-Unterstützung, Ein Thread zum Lesen, Senden und Speichern zum Zwischenspeichern von Daten. Am einfachsten und am schnellsten arbeitest du. Komplexe Logik – bester Weg!
  2. https://github.com/master255/VideoViewCache Simple Videoansicht mit Cache. Zwei Threads zum Abspielen und Speichern von Daten. Schlechte Logik, aber wenn Sie brauchen, dann benutzen Sie das.